C#从固定时区转换DateTime

发布于 2025-02-01 11:07:02 字数 636 浏览 4 评论 0原文

我正在从外部API日期阅读:

2022-05-13 07:05:00

2022-05-13 13:00:00 ...

这些日期是在CET时间固定的。我想将它们转换为UTC格式,例如“ yyyy-mm-ddthh:mm:sszzz”,这样我就可以看到UTC偏移+02:00。

问题在于我没有找到一种方法来指定我的日期位于CET时区。诸如转换时间之类的函数,转换timetoutc不起作用。

我的代码是:

    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");

如何解决这个问题?

I'm reading from external API dates like this:

2022-05-13 07:05:00

2022-05-13 13:00:00
...

These dates are fixed in CET time. I want to convert them into UTC format like "yyyy-MM-ddTHH:mm:sszzz" so I can see UTC offset +02:00.

The problem is that I didn't find a way how to specify that my date is in CET timezone. Functions like ConvertTime, ConvertTimeToUtc doesn't work.

My code is:

    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");

How to resolve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

漫漫岁月 2025-02-08 11:07:02

有一种更清洁的方法:

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());

边缘案例:

  1. 当日光节省时间从冬季到夏季变化时,时钟从<02:00:00 03:00:01 ,因此没有什么比2022-03-27 02:30:00 CET

在这种情况下,根据和例外:

如果DateTime对应于无效的时间,则此方法会引发一个参数exception。

  1. 当夏令时节省时间从夏季到冬季变化时,时钟从 03:00:00 02:00:01 ,因此,例如2022-10 -30 02:30:00 CET在逻辑上可以转化为 00:30:00 UTC或 01:30:00 UTC

在这种情况下,根据标准时间(冬季)时间:

如果DateTime对应于模棱两可的时间,则此方法假定这是源时区的标准时间。

There is a cleaner way of doing it:

public static DateTime ParseCET(string dt)
{
    var cet = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
    var localTime = DateTime.Parse(dt);
    return TimeZoneInfo.ConvertTimeToUtc(localTime, cet);
}

The output is consistent and correct, always respecting daylight saving time period:

// 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());

Edge cases:

  1. When daylight saving time changes from winter to summer time, the clock jumps from 02:00:00 to 03:00:01, therefore there is nothing like 2022-03-27 02:30:00 CET.

In this case according to the documentation and exception is thrown:

If dateTime corresponds to an invalid time, this method throws an ArgumentException.

  1. When daylight saving time changes from summer to winter time, the clock jumps from 03:00:00 to 02:00:01, therefore for instance 2022-10-30 02:30:00 CET could logically translate to either of 00:30:00 UTC or 01:30:00 UTC.

In this case according to the documentation standard (winter) time is assumed:

If dateTime corresponds to an ambiguous time, this method assumes that it is the standard time of the source time zone.

自由如风 2025-02-08 11:07:02

您可以使用以下几个小时手动设置:

// Currently CET is ahead of UTC by 2 hours
time = time.AddHours(-2);

然后可以格式化日期时间对象,而不必担心时区。

编辑:添加日光节省。

首先,您必须检查您是否在节省日光有效的时候。

要进行此操作,请首先获取DateTime,然后检查是否在日光节省期间。
日光节省在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);
         }
     }

}

You can manually set the hours back using:

// Currently CET is ahead of UTC by 2 hours
time = time.AddHours(-2);

And then you can format the date time object without worrying about the time zones.

edit: adding daylight saving.

First you have to check whether you are in the time where daylight saving is in effect or not.

To do this first get the datetime, then check if it is in the daylight saving period.
Daylight saving goes into effect at the last sunday of march and is cancelled at the last sunday of october

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);
         }
     }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文