迭代一个月中夏令时发生变化的日子

问题描述 投票:0回答:2

我正在创建一个从该月最后一天开始到下个月第一天结束的日期列表,全部采用 UTC 时间。对于本月(2013 年 10 月),法国时区的用户的月份开始 UTC 日期

CalendarMonthStartUTC
为 9/30 @ 10PM,结束日期
CalendarMonthEndUTC
(UTC)为 10/31 @ 11PM。

我有一个看起来像这样的循环:

DateTime StartTime = CalendarMonthStartUTC;
DateTime EndTime = new DateTime()

while (StartTime < CalendarMonthEndUTC)
{
     EndTime = StartTime.AddHours(24);
     ... do something here
     StartTime = StartTime.AddHours(24);
} 

此循环适用于一年中的所有月份(除了 10 月),因为夏令时更改会产生 OBO 错误,因为循环会在每次迭代时添加 24 小时进行迭代。 我想知道如何修改我的循环,以便无论夏令时如何它都可以工作。

感谢您的建议。

c# timezone
2个回答
3
投票

你不能只使用当地时间,最后转换为UTC吗?

如果您想对本地计算机上当前设置的时区执行计算,则可以执行以下操作:

        DateTime calendarMonth = new DateTime(2013, 10, 1, 0, 0, 0, DateTimeKind.Local);
        DateTime startDay = calendarMonth.AddDays(-1);
        DateTime endDay = calendarMonth.AddMonths(1);

        while (startDay <= endDay)
        {
            Console.WriteLine(startDay + " = " + startDay.ToUniversalTime());
            startDay = startDay.AddDays(1);
        }

如果您想计算给定时区的时间,而不管本地计算机设置如何,那么您可以像这样转换为 UTC:

        var timeZone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
        var utcTime = TimeZoneInfo.ConvertTimeToUtc(startDay, timeZone)); 

0
投票

不幸的是,简单地使用

date.AddDays(n)
不会考虑夏令时 - 它会简单地假设一天正好是 24 小时,即使您穿过夏令时边界,在这种情况下您预计它是 23 或 25小时。

为了补偿,我们可以执行以下操作:

  1. 转换为
    DateTime
    删除偏移量。假定这个新日期是目标时区的本地“挂钟”时间。
  2. 进行日期数学计算,而不必担心偏移,即我们只处理“挂钟”时间。
  3. 然后转换回具有目标时区正确偏移量的
    DateTimeOffset
    。这将根据新日期的夏令时正确添加/删除一小时的偏移量。
DateTimeOffset today = ...;
TimeZoneInfo tz = ...;
DateTime dateTimeInTimeZone = date.DateTime.AddDays(1);
DateTimeOffset tomorrow = new DateTimeOffset(dateTimeInTimeZone, tz.GetUtcOffset(dateTimeInTimeZone));

这只适用于以天、月或年为单位进行日期数学计算的情况。它不会与小时等一起工作

© www.soinside.com 2019 - 2024. All rights reserved.