C# 当地时间明天午夜(调整夏时制)

C# 当地时间明天午夜(调整夏时制),c#,.net,timezone,C#,.net,Timezone,我的理解是,DateTime.Today给出了当地时区中今天午夜的时间 是否DateTime.Today.AddDays(1)总是给出当地时区明天的午夜,或者有时会因为夏令时而关闭 i、 e是.AddDays(1)=.AddHours(24),或者在调整夏时制时有时会有所不同 如果.AddDays(1)=.AddHours(24),是否有办法获得明天当地午夜的时间(从现在起可能是23、24或25小时)?夏令时不会自动调整,您需要根据代码进行调整,然后可以使用 DateTime.Today.Add

我的理解是,
DateTime.Today
给出了当地时区中今天午夜的时间

是否
DateTime.Today.AddDays(1)
总是给出当地时区明天的午夜,或者有时会因为夏令时而关闭

i、 e是
.AddDays(1)=.AddHours(24)
,或者在调整夏时制时有时会有所不同


如果
.AddDays(1)=.AddHours(24)
,是否有办法获得明天当地午夜的时间(从现在起可能是23、24或25小时)?

夏令时不会自动调整,您需要根据代码进行调整,然后可以使用

DateTime.Today.AddDays(1)
即使是在夏令时,也会给你们第二天的午夜时间

正确管理时区和夏令时使用 使用Noda time.net库

1.“纯日期时间 关键是要记住,
DateTime
只是一个容器,其中包含所谓的
ticks
,它们是 “自1/1/0001 12:00am以来经过的100纳秒间隔数”
DateTime
不保留它所指向的时区的信息

调用时,实际上是在添加一个常量
TicksPerDay
ticks:

public DateTime AddDays(double value) {
    return Add(value, MillisPerDay);
}

private DateTime Add(double value, int scale) {
    (...)
    return AddTicks(millis * TicksPerMillisecond);
}
AddHours
也会导致添加刻度

当您呼叫
AddHours(24)
时,您的意思是请将24小时添加到“YYYY-MM-DD HH:MM:SS”(第二天15:00->15:00,与时区或DST无关)。你不是在24小时后询问时间(24小时后可能是14:00或16:00)

为了回答“从现在起24小时是几点?”需要时区信息(参见下面的NodaTime)

类似地,
AddHours(25)
的意思是:请在“YYYY-MM-DD HH:MM:SS”中添加1天1小时。日期时间为2019-10-06 14:07加上25小时,则始终为2019-10-07 15:07

请注意,
DateTime
考虑闰年(只需要静态规则)

2.点头时间 野田佳彦时间允许你“打发”时间,也就是说,增加一段时间。换句话说,它允许你回答“n小时内是几点?”

在英语中,我们可以阅读

时间线算法非常简单,但在使用ZoneDateTime时,由于夏令时转换,您可能无法始终获得预期的结果:

DateTimeZone london = DateTimeZoneProviders.Tzdb["Europe/London"];
// 12:45am on March 25th 2012
LocalDateTime local = new LocalDateTime(2012, 3, 25, 0, 45, 00);
ZonedDateTime before = london.AtStrictly(local);
ZonedDateTime after = before + Duration.FromMinutes(20);
我们从当地时间上午12点45分开始。我们添加的时间实际上是“有经验的”时间——就好像我们只是等了二十分钟。然而,那天凌晨1点,欧洲/伦敦时区的时钟向前拨了一个小时——因此我们最终的当地时间是凌晨2:05,而不是你可能预期的凌晨1:05

相反的效果可能发生在另一个夏时制转换中,当时钟向后而不是向前时:因此,凌晨1:45后20分钟很容易变成凌晨1:05!因此,即使我们在ZonedDateTime中公开了“本地时间”的概念,对其执行的任何运算都是使用基础时间线计算的

我的理解是,
DateTime.Today
给出了当地时区中今天午夜的时间

这基本上是正确的,但有一个边缘情况。它将使用本地时区确定当前日期,并将时间设置为
00:00:00.0000000
。生成的
.Kind
将是
DateTimeKind.Local
。其作用相当于以下任何一项:

DateTime.Now.Date
DateTime.UtcNow.ToLocalTime().Date
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local).Date
// etc.
(有关完整列表,请参阅。)

请注意,在我的所有示例中,
.Date
是最后一个。该属性只是将时间设置为零。它保留
.Kind
,但不以任何方式对其求值

边缘情况起作用的地方是,如果您处理的时区在午夜有一个过渡-时钟从
23:59
转到
01:00
。由于没有
00:00
,因此
DateTime.Today
的结果将是不存在的本地时间。其中一个例子是智利圣地亚哥,时间为2019-09-08。那天那里不存在午夜

是否
DateTime.Today.AddDays(1)
总是给出当地时区明天的午夜,或者有时会因为夏令时而关闭

i、 e是
.AddDays(1)=.AddHours(24)
,或者在调整夏时制时有时会有所不同

AddDays
AddHours
功能都不考虑时区。他们两人只需加上24小时。与
.Date
属性类似,这些函数保留了
.Kind
,但它们不会对其进行计算

如果
.AddDays(1)=.AddHours(24)
,是否有办法获得明天午夜当地时间(可能是23、24或25小时后)

请记住,正如前面提到的,午夜可能不存在,您只需针对这种可能性进行调整。下面是一个仅使用
DateTime
的扩展方法:

static DateTime AdjustToValidTime(this DateTime dt, TimeZoneInfo tz)
{
    if (!tz.IsInvalidTime(dt))
    {
        // The time is already valid
        return dt;
    }

    // Get the adjustment rule that applies
    var rule = tz.GetAdjustmentRules()
        .First(x => x.DateStart <= dt && x.DateEnd > dt);

    // Get the transition gap.  Often will be one hour, but not always
    TimeSpan gap = rule.DaylightDelta;

    // Add the gap to adjust to a valid time
    return dt.Add(gap);
}
如果您想看到没有午夜的一天,可以这样使用:

TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific SA Standard Time");
DateTime today = new DateTime(2019, 9, 8);
DateTime adjusted = today.AdjustToValidTime(tz); // Will be 2019-09-08 01:00

DateTime.Today.AddDays(1)
将在下一天的午夜返回day@RufusL因此,为了确认,有一种情况,
x.AddDays(1)=x.AddHours(25)
?不,我不知道
AddDays
字面上只增加日期的日部分(这可能反过来影响月份和年份,但不影响时间)。您可以为夏令时中不存在的时间创建
DateTime
,如
03/10/19 02:00:01 AM
(夏令时从3/10的凌晨2点开始)。但我并不是这里的专家。我从未见过
AddDays
影响对象的时间部分。你的两个说法似乎相互矛盾。如何
DateTime.Today.AddDays(1)
总是在第二天午夜返回,但是
x.AddDays(1)=x.AddHours(25)TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific SA Standard Time");
DateTime today = new DateTime(2019, 9, 8);
DateTime adjusted = today.AdjustToValidTime(tz); // Will be 2019-09-08 01:00