时区开始时间

1 c# timezone datetime

您好,我收到一些随机的 datetimeoffset utc 我的观点是 1 - 将其转换为芝加哥时间 2 - 定义芝加哥 startOfDay 3 - 最后将芝加哥 startOfDay 转换回 utc datetimeOffset。(查询utc api需要这个过程)

我写的这个似乎可以做我想做的事,但真的不确定它总是能用夏令时灯等来完成工作。有人可以告诉或改进代码吗?

var UTCDate = DateTimeOffset.UtcNow; //<----------Some random utc dateTimeOffset
            TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
            DateTimeOffset CSTDate = GetZoneDatetimeOffset(UTCDate, zone);
            Console.WriteLine("Utc : {0} Chicago: {1}  local : {2}", UTCDate, CSTDate, UTCDate.ToLocalTime());            
            Console.WriteLine(" Chicago StartOfDay: {0}  Chicago StartOfDay To UTC : {1}", CSTDate.Date, CSTDate.Date.ToUniversalTime());

    public  DateTimeOffset GetZoneDatetimeOffset(DateTimeOffset someUTCDate , TimeZoneInfo destZone)
            {
                
                DateTimeOffset ZoneDateTimeOffset = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(someUTCDate.DateTime , TimeZoneInfo.Utc.Id, destZone.Id);           
                return ZoneDateTimeOffset;
    
            }
Run Code Online (Sandbox Code Playgroud)

Mat*_*int 5

您的代码中有一些错误:

  • 您调用TimeZoneInfo.ConvertTimeBySystemTimeZoneId并传递一个DateTime值。因此,结果也将是一个DateTime. 该Kind结果的 将为Unspecified. 将其分配给因此 将会执行从to 的DateTimeOffset隐式转换操作,这将使用计算机的本地时区 - 而不是您正在使用的时区。DateTimeDateTimeOffset

  • 和DateTimeOffset.Date都DateTimeOffset.DateTime返回一个DateTimewho Kindis Unspecified。因此,当您调用ToLocalTime或 时ToUniversalTime,您将再次使用计算机的本地时区。

  • 确定特定时区的一天的开始可能很棘手。尽管芝加哥(或美国任何地方)不会发生这种情况,但世界上的某些时区的 DST 转换会在一天开始时立即发生。因此,00:00它可能不是一天中的第一时刻,也可能发生两次。你的代码没有考虑到这一点。

    古巴就是一个很好的例子,夏令时接下来开始于古巴2022 年 3 月 13 日午夜,因此古巴这一天的开始时间是2022-03-13T01:00。

    您可以使用我在这个答案中GetStartOfDay提供的方法来处理这些边缘情况。

把它们放在一起:

// Input values
DateTimeOffset utc = DateTimeOffset.UtcNow;
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");

// Convert with full fidelity using only DateTimeOffset values
DateTimeOffset converted = TimeZoneInfo.ConvertTime(utc, zone);

// Get the start of day using the method from https://stackoverflow.com/a/49988688
DateTimeOffset startOfDay = GetStartOfDay(converted.DateTime, zone);

// Output the results
Console.WriteLine("Original values:");
Console.WriteLine("Chicago: {0:o}   UTC: {1:o}   Local: {2:o}", converted, utc, utc.ToLocalTime());
Console.WriteLine();
Console.WriteLine("At start of day in Chicago:");
Console.WriteLine("Chicago: {0:o}   UTC: {1:o}   Local: {2:o}", startOfDay, startOfDay.ToUniversalTime(), startOfDay.ToLocalTime());
Run Code Online (Sandbox Code Playgroud)

示例输出(本例中本地时区是美国太平洋时间):

Original values:
Chicago: 2022-03-10T10:58:47.8164830-06:00   UTC: 2022-03-10T16:58:47.8164830+00:00   Local: 2022-03-10T08:58:47.8164830-08:00

At start of day in Chicago:
Chicago: 2022-03-10T00:00:00.0000000-06:00   UTC: 2022-03-10T06:00:00.0000000+00:00   Local: 2022-03-09T22:00:00.0000000-08:00
Run Code Online (Sandbox Code Playgroud)

另请参阅此处的工作 .NET Fiddle。