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