简体   繁体   English

如何计算 C# 中两个日期之间我时区的实际经过时间?

[英]How can I calculate the acutal elapsed time in my timezone between two dates in C#?

How do I calculate the actual elapsed time between two DateTime / DateTimeOffset , both in my timezone, taking daylight saving time, leap years, etc, into account?如何计算两个DateTime / DateTimeOffset之间的实际经过时间,都在我的时区,考虑到夏令时、闰年等?

For example, the following code comparing the difference between 00:00 and 05:00 of March 29th 2020 will output a timespan of 6 hours (05:00 becomes 06:00 after the conversion to local time, since daylight saving time starts 02:00 in my timezone, changing clocks forward from 02:00 to 03:00).例如,以下代码比较 2020 年 3 月 29 日 00:00 和 05:00 之间的差异将 output 时间跨度为 6 小时(转换为本地时间后 05:00 变为 06:00,因为夏令时从 02 开始: 00 在我的时区,将时钟从 02:00 向前更改为 03:00)。

var timezone = TimeZoneInfo.Local;

var start = new DateTimeOffset(2020, 03, 29, 00, 00, 00, timezone.BaseUtcOffset).LocalDateTime;
var end   = new DateTimeOffset(2020, 03, 29, 05, 00, 00, timezone.BaseUtcOffset).LocalDateTime;

var diff1 = end.Subtract(start);
var diff2 = end - start;

Console.WriteLine(diff1); // 06:00:00
Console.WriteLine(diff2); // 06:00:00

I'm trying to get an output of 4 hours in the example above since that is the elapsed time between 00:00 and 05:00.我试图在上面的示例中获得4 小时的 output,因为这是 00:00 到 05:00 之间的经过时间。

00:00 -> 01:00 (+ 1 hr)
01:00 -> 02:00 (+ 1 hr)
02:00 -> 03:00 (0)
03:00 -> 04:00 (+ 1 hr)
04:00 -> 05:00 (+ 1 hr)

= 4 hrs

I'm clearly missing something here.我显然在这里遗漏了一些东西。 I've read Comparisons and arithmetic operations with DateTimeOffset values but can't wrap my head around how to do this calculation.我已经阅读了 DateTimeOffset 值的比较和算术运算,但无法理解如何进行此计算。

I am aware that NodaTime can probably achieve this, but surely there's a way to do this without external libraries?我知道 NodaTime 可能可以实现这一点,但肯定有一种方法可以在没有外部库的情况下做到这一点?

As Panagiotis Kanavos pointed out,正如Panagiotis Kanavos指出的那样,

So the offset is wrong.所以偏移量是错误的。 It's no longer the BaseUtcOffset, it's a different one它不再是 BaseUtcOffset,而是不同的

I found TimeZoneInfo.GetUtcOffset and used that.我找到了TimeZoneInfo.GetUtcOffset并使用了它。 I think it does what I want?我认为它做我想要的? Timezones are confusing, but at least I get my output of 4 hours now.时区令人困惑,但至少我现在得到了 4 小时的 output。

var timezone = TimeZoneInfo.Local;

var startTime = new DateTime(2020, 03, 29, 00, 00, 00);
var endTime   = new DateTime(2020, 03, 29, 05, 00, 00);

var startTimeOffset = timezone.GetUtcOffset(startTime);
var endTimeOffset   = timezone.GetUtcOffset(endTime);

var start = new DateTimeOffset(2020, 03, 29, 00, 00, 00, startTimeOffset);
var end   = new DateTimeOffset(2020, 03, 29, 05, 00, 00, endTimeOffset);

var diff1 = end.Subtract(start);
var diff2 = end - start;

Console.WriteLine(diff1); // 04:00:00
Console.WriteLine(diff2); // 04:00:00

Your answer is fine, and is the correct approach when the offset is not provided with if the time zone, assuming it can be any arbitrary time zone.你的答案很好,如果时区没有提供偏移量,这是正确的方法,假设它可以是任意时区。

However, if you are only working with the local system time zone, you can simplify the code as follows:但是,如果您使用本地系统时区,则可以将代码简化如下:

var start = new DateTimeOffset(new DateTime(2020, 3, 29, 0, 0, 0, DateTimeKind.Local));
var end   = new DateTimeOffset(new DateTime(2020, 3, 29, 5, 0, 0, DateTimeKind.Local));
TimeSpan diff = end - start;

This works because the .Kind property of a DateTime is evaluated when passed into the DateTimeOffset constructor that takes a single DateTime parameter.这是因为DateTime.Kind属性在传递到采用单个DateTime参数的DateTimeOffset构造函数时进行评估。 If it's DateTimeKind.Local or DateTimeKind.Utc , then the offset is set correctly.如果是DateTimeKind.LocalDateTimeKind.Utc ,则偏移量设置正确。 It's only in the case of DateTimeKind.Unspecified that the offset could be incorrect (because it will assume local, even if that's not the case).只有在DateTimeKind.Unspecified的情况下,偏移量可能不正确(因为它会假定为本地,即使不是这种情况)。 See the remarks in the docs here. 请参阅此处文档中的备注。

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

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