gpt4 book ai didi

c# - 从 DateTime 中删除 DST

转载 作者:太空狗 更新时间:2023-10-29 22:53:04 25 4
gpt4 key购买 nike

我看到许多网站(通常是论坛)允许用户通过选择来指定他们的时区偏好:

  • 时区
  • 是否使用夏令时

据我所知,在进行转换时,.NET 总是考虑 DST,所以问题是:

如何在 C# 中实现“不使用 DST”部分?

在这一点之下,我介绍了到目前为止我设法做到的事情,但感觉很老套,我想知道是否有更清洁/更好的方法。

首先,为了确保自动应用 DST,我编写了以下测试:

[Test]
public void DateTimeConversion_ToLocalTime_HandlesDSTByDefault()
{
var utcDateInDstInterval = new DateTime(2012, 07, 15, 0, 0, 0, DateTimeKind.Utc);
var utcDateOutisdeDstInterval = new DateTime(2012, 02, 15, 0, 0, 0, DateTimeKind.Utc);

var roTimezone = TimeZoneInfo.FindSystemTimeZoneById("GTB Standard Time");

Assert.AreEqual(3, TimeZoneInfo.ConvertTimeFromUtc(utcDateInDstInterval, roTimezone).Hour);
Assert.AreEqual(2, TimeZoneInfo.ConvertTimeFromUtc(utcDateOutisdeDstInterval, roTimezone).Hour);
}

此测试通过,表明:

  • 当不适用 DST 时(例如在冬天),罗马尼亚时间为 UTC + 2 小时
  • 当夏令时适用时(例如在夏季),罗马尼亚时间为 UTC + 3 小时
  • 进行 DateTime 转换时,会自动考虑 DST

接下来,我注意到 TimeZoneInfo.GetAdjustmentRules()返回 AdjustmentRule 数组的方法对象并发现如果我撤销这些规则的影响,我可以获得 DST 未受影响的值。

因此,如果 DateTime 对象 is affected by DST,我编写了以下方法来执行此操作:

private DateTime RemoveDSTFromDateTime(DateTime dateTime, TimeZoneInfo timeZoneInfo)
{
if (!dateTime.IsDaylightSavingTime())
return dateTime;

var result = dateTime;

foreach (var adjustmentRule in timeZoneInfo.GetAdjustmentRules())
result = result.Subtract(adjustmentRule.DaylightDelta);

return result;
}

回到原来的夏令时/无夏令时场景,但这次强制结果不受夏令时影响:

[Test]
public void DateTimeConversion_ToLocalTime_WithoutDST()
{
var utcDateInDstInterval = new DateTime(2012, 07, 15, 0, 0, 0, DateTimeKind.Utc);
var utcDateOutisdeDstInterval = new DateTime(2012, 02, 15, 0, 0, 0, DateTimeKind.Utc);

var roTimezone = TimeZoneInfo.FindSystemTimeZoneById("GTB Standard Time");

var convertedDateWithDst = TimeZoneInfo.ConvertTimeFromUtc(utcDateInDstInterval, roTimezone);
var convertedDateWithoutDst = TimeZoneInfo.ConvertTimeFromUtc(utcDateOutisdeDstInterval, roTimezone);

Assert.AreEqual(2, RemoveDSTFromDateTime(convertedDateWithDst, roTimezone).Hour);
Assert.AreEqual(2, RemoveDSTFromDateTime(convertedDateWithoutDst, roTimezone).Hour);
}

这个测试也通过了,表明现在 DST 的影响被取消了(无论一年中的什么时间,我们总是得到 UTC + 2h)。

在写下这些内容时,我想到了另一个似乎可行的想法:不使用任何 TimeZoneInfo.Convert...() 方法,只需将 roTimezone.BaseUtcOffset 添加到UTC 日期。

任何人都可以指出执行此操作的正确方法是什么吗?

最佳答案

解析您的问题,您似乎有两个建议的解决方案:

  1. 确定 DST 调整并将其从转换后的输出中移除。

  2. 获取 UTC DateTime 并添加 BaseUtcOffset,以便您始终处理标准时间。

由于您的问题是如何不实现夏令时,我会说您使用选项 #2 自己回答了这个问题。

也就是说,您最初的假设是有缺陷的。许多站点要求提供时区和 DST 的原因通常是因为它们的时区实现一开始就不支持 DST。他们所做的是让您选择一个基准偏移量并决定是否要在一年中的某个特定时间增加一个小时。他们可能称它为“时区”,但它远不如 .Net 的 TimeZoneInfo 类或库(如 Noda Time)强大。 .

如果您确实选择了一个“时区”,例如通过 TimeZoneInfo.GetSystemTimeZones()(您应该保存 Id 属性并显示 DisplayName 属性)那么你绝对不应该询问用户是否使用 DST。如果用户居住在不使用 DST 的地方(如亚利桑那州),则已经有相应的选择。用户通常很擅长选择正确的选项来获得他们想要的效果,尤其是如果他们住在 DST 规则奇怪的地区(如印第安纳州)。

如果您使用 IANA/Olson 风格的时区,例如 "America/New York",同样的想法也适用,无论它们是由 Noda Time 提供的或其他一些实现。您应该将 DST 决定委托(delegate)给图书馆,而不是用户。

将此委托(delegate)给图书馆的一个非常有效的论据是,这些 DST 规则可以更改,并且已经在其生命周期的许多点上更改。如果您正在编写处理过去信息的任何类型的应用程序或网站,您可能会发现今天有效的内容并不是对过去发生的事情的正确调整。此外,时区世界中有很多奇怪之处,例如澳大利亚,某些地区的时差是 30 分钟而不是整整一个小时。您真的要自己管理吗?可能不会。 :)

关于c# - 从 DateTime 中删除 DST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12266948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com