简体   繁体   English

c# 从固定时区转换 DateTime

[英]c# Convert DateTime from fixed timezone

I'm reading from external API dates like this:我正在阅读这样的外部 API 日期:

2022-05-13 07:05:00 2022-05-13 07:05:00

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

These dates are fixed in CET time.这些日期以 CET 时间固定。 I want to convert them into UTC format like "yyyy-MM-ddTHH:mm:sszzz" so I can see UTC offset +02:00.我想将它们转换为 UTC 格式,例如“yyyy-MM-ddTHH:mm:sszzz”,这样我就可以看到 UTC 偏移量 +02:00。

The problem is that I didn't find a way how to specify that my date is in CET timezone.问题是我没有找到如何指定我的日期在 CET 时区的方法。 Functions like ConvertTime, ConvertTimeToUtc doesn't work. ConvertTime、ConvertTimeToUtc 等函数不起作用。

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?如何解决这个问题?

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 .当夏令时从冬季变为夏季时,时钟从02:00:00跳到03:00:01 ,因此没有像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.如果 dateTime 对应于无效时间,则此方法将引发 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 .当夏令时从夏季时间更改为冬季时间时,时钟会从03:00:00跳转到02:00:01 ,因此例如2022-10-30 02:30:00 CET在逻辑上可以转换为00:30中的任何一个:00 UTC 或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.如果 dateTime 对应的时间不明确,则此方法假定它是源时区的标准时间。

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夏令时于 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);
         }
     }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM