c# 从固定时区转换 DateTime
c# Convert DateTime from fixed timezone
我正在从这样的外部 API 日期读取数据:
2022-05-1307:05:00
2022-05-13 13:00:00
...
这些日期以 CET 时间固定。我想将它们转换成 UTC 格式,如“yyyy-MM-ddTHH:mm:sszzz”,这样我就可以看到 UTC 偏移量 +02:00。
问题是我没有找到一种方法来指定我的日期是在 CET 时区内。 ConvertTime、ConvertTimeToUtc 等函数不起作用。
我的代码是:
var time = new DateTime(2022,5,26,8,15,00, DateTimeKind.Unspecified); // 2022-05-26 8:15:00 CET
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
DateTime cet = TimeZoneInfo.ConvertTime(time, tz); // non sense, as no timezone info in time...
var str = cet.ToString("yyyy-MM-ddTHH:mm:sszzz");
如何解决?
您可以使用以下方法手动设置小时数:
// Currently CET is ahead of UTC by 2 hours
time = time.AddHours(-2);
然后您可以格式化日期时间对象而无需担心时区。
编辑:添加夏令时。
首先你要检查你是否处于夏令时生效的时间。
首先获取日期时间,然后检查它是否处于夏令时。
3月最后一个星期日开始实行夏令时,10月最后一个星期日取消
currentTime = DateTime.Now();
string currentMonth = currentTime.ToString("MM");
string currentDay = currentTime.ToString("DD");
// Daylight saving is in effect
if ( currentMonth > '3' && currentMonth < '10' ) {
time = time.AddHours(-2);
}
// Daylight saving is not in effect
else if ( currentMonth < '3' || currentMonth > '10' ) {
time = time.AddHours(-1);
}
// If it is march or october
else if(currentMonth == '3' || currentMonth == '10')
{
// Find the last sunday
var lastSunday = new DateTime(currentTime.Year,currentTime.Month,1);
lastSunday = lastSunday.AddMonths(1).AddDays(-1);
while (lastSunday.DayOfWeek != DayOfWeek.Sunday)
{
lastSunday = lastSunday.AddDays(-1);
}
string sunday = lastSunday.ToString("DD");
// If it is march, check to see if the day is after or before last sunday
if(currentMonth == '3'){
if( currentDay > sunday )
{
// Daylight saving is in effect
time = time.AddHours(-2);
}
else
{
// It is not in effect
time = time.AddHours(-1);
}
}
// If it is october, check to see if the day is after last sunday or not
else if(currentMonth == '10'){
if( currentDay > sunday )
{
// Daylight saving is not in effect
time = time.AddHours(-1);
}
else
{
// It is in effect
time = time.AddHours(-2);
}
}
}
有一种更简洁的方法:
public static DateTime ParseCET(string dt)
{
var cet = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
var localTime = DateTime.Parse(dt);
return TimeZoneInfo.ConvertTimeToUtc(localTime, cet);
}
输出一致且正确,始终遵守夏令时:
// winter time - prints "2/1/2022 11:00:00 AM"
Console.WriteLine(ParseCET("2022-02-01 12:00:00").ToString());
// summer time - prints "8/1/2022 10:00:00 AM"
Console.WriteLine(ParseCET("2022-08-01 12:00:00").ToString());
边缘情况:
- 当夏令时从冬令时变为夏令时时,时钟从02:00:00跳到03:00:01,因此没有
2022-03-27 02:30:00 CET
.
本例根据documentation抛出异常:
If dateTime corresponds to an invalid time, this method throws an ArgumentException.
- 当夏令时改为冬令时时,时钟从03:00:00跳到02:00:01,因此例如
2022-10-30 02:30:00 CET
在逻辑上可以转换为 00:30:00 UTC 或 01:30:00 UTC。
在这种情况下,根据 documentation 标准(冬季)时间假设:
If dateTime corresponds to an ambiguous time, this method assumes that it is the standard time of the source time zone.
我正在从这样的外部 API 日期读取数据:
2022-05-1307:05:00
2022-05-13 13:00:00 ...
这些日期以 CET 时间固定。我想将它们转换成 UTC 格式,如“yyyy-MM-ddTHH:mm:sszzz”,这样我就可以看到 UTC 偏移量 +02:00。
问题是我没有找到一种方法来指定我的日期是在 CET 时区内。 ConvertTime、ConvertTimeToUtc 等函数不起作用。
我的代码是:
var time = new DateTime(2022,5,26,8,15,00, DateTimeKind.Unspecified); // 2022-05-26 8:15:00 CET
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
DateTime cet = TimeZoneInfo.ConvertTime(time, tz); // non sense, as no timezone info in time...
var str = cet.ToString("yyyy-MM-ddTHH:mm:sszzz");
如何解决?
您可以使用以下方法手动设置小时数:
// Currently CET is ahead of UTC by 2 hours
time = time.AddHours(-2);
然后您可以格式化日期时间对象而无需担心时区。
编辑:添加夏令时。
首先你要检查你是否处于夏令时生效的时间。
首先获取日期时间,然后检查它是否处于夏令时。 3月最后一个星期日开始实行夏令时,10月最后一个星期日取消
currentTime = DateTime.Now();
string currentMonth = currentTime.ToString("MM");
string currentDay = currentTime.ToString("DD");
// Daylight saving is in effect
if ( currentMonth > '3' && currentMonth < '10' ) {
time = time.AddHours(-2);
}
// Daylight saving is not in effect
else if ( currentMonth < '3' || currentMonth > '10' ) {
time = time.AddHours(-1);
}
// If it is march or october
else if(currentMonth == '3' || currentMonth == '10')
{
// Find the last sunday
var lastSunday = new DateTime(currentTime.Year,currentTime.Month,1);
lastSunday = lastSunday.AddMonths(1).AddDays(-1);
while (lastSunday.DayOfWeek != DayOfWeek.Sunday)
{
lastSunday = lastSunday.AddDays(-1);
}
string sunday = lastSunday.ToString("DD");
// If it is march, check to see if the day is after or before last sunday
if(currentMonth == '3'){
if( currentDay > sunday )
{
// Daylight saving is in effect
time = time.AddHours(-2);
}
else
{
// It is not in effect
time = time.AddHours(-1);
}
}
// If it is october, check to see if the day is after last sunday or not
else if(currentMonth == '10'){
if( currentDay > sunday )
{
// Daylight saving is not in effect
time = time.AddHours(-1);
}
else
{
// It is in effect
time = time.AddHours(-2);
}
}
}
有一种更简洁的方法:
public static DateTime ParseCET(string dt)
{
var cet = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
var localTime = DateTime.Parse(dt);
return TimeZoneInfo.ConvertTimeToUtc(localTime, cet);
}
输出一致且正确,始终遵守夏令时:
// winter time - prints "2/1/2022 11:00:00 AM"
Console.WriteLine(ParseCET("2022-02-01 12:00:00").ToString());
// summer time - prints "8/1/2022 10:00:00 AM"
Console.WriteLine(ParseCET("2022-08-01 12:00:00").ToString());
边缘情况:
- 当夏令时从冬令时变为夏令时时,时钟从02:00:00跳到03:00:01,因此没有
2022-03-27 02:30:00 CET
.
本例根据documentation抛出异常:
If dateTime corresponds to an invalid time, this method throws an ArgumentException.
- 当夏令时改为冬令时时,时钟从03:00:00跳到02:00:01,因此例如
2022-10-30 02:30:00 CET
在逻辑上可以转换为 00:30:00 UTC 或 01:30:00 UTC。
在这种情况下,根据 documentation 标准(冬季)时间假设:
If dateTime corresponds to an ambiguous time, this method assumes that it is the standard time of the source time zone.