gpt4 book ai didi

c# - 替换时区

转载 作者:行者123 更新时间:2023-11-30 15:54:32 24 4
gpt4 key购买 nike

我们正在尝试构建基本的事件日历功能,允许用户创建事件并在给定的月、日、年、小时和分钟以及时区指定开始时间 (System. TimeZoneInfo.Id). CMS 系统根据我们服务器的位置生成生成的 System.DateTime,比方说 TimeZoneInfo.Id Mountain Standard Time。 CMS 的日期选择器组件不提供指定时区的选项。但是,我们确实可以控制 SQL 日期时间精度,默认设置为 7

DateTime 被格式化为 yyyyMMddTHHmmssZ,用于在 .ics/ical 中填充开始/结束时间。使用这种格式,它使 2018 年 5 月 25 日晚上 7:00(20180508T192840Z)始终看起来像服务器的山区标准时间 (MST),而不是选定的东部标准时间 (EST) 中的 2018 年 5 月 25 日晚上 7:00 .

如何在不更改年/月/日/小时/分钟的情况下将生成的 DateTime 的时区替换为 DateTimeDateTimeOffsetTimeZoneInfoNodaTime,甚至 string 函数都可以格式化为 yyyyMMddTHHmmssZ

以下内容:

TimeZoneInfo destinationTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var converted = TimeZoneInfo.ConvertTime(dateTime1, destinationTimeZone);

或:

LocalDateTime fromLocal = LocalDateTime.FromDateTime(dateTime1);
DateTimeZone fromZone = DateTimeZoneProviders.Tzdb["America/Denver"];
ZonedDateTime fromZoned = fromLocal.InZoneLeniently(fromZone);

DateTimeZone toZone = DateTimeZoneProviders.Tzdb["America/Chicago"];
ZonedDateTime toZoned = fromZoned.WithZone(toZone);
LocalDateTime toLocal = toZoned.LocalDateTime;
var result = toLocal.ToDateTimeUnspecified();

创建一个新的 DateTime,将小时从 CST 调整为 EST 这将不起作用,因为目标是让 DateTime 具有原始小时值但 TimeZoneInfo.Id 东部标准时间

DateTime 构造函数似乎没有指定 TimeZoneInfo 的构造函数,只有 DateTimeKind

如何使用一些甚至从 DateTime.Now 创建的 DateTime 来做到这一点?

最佳答案

一些事情:

  • 您的格式说明符末尾包含一个 Z。这被.Net 的字符串格式视为字 rune 字,因为它不是有效的datetime formatting specifier。 .请注意,格式化标记区分大小写。作为文字,它只是被复制到输出 - 就像 T 一样。因此,您生成的这个字符串总是会被解析它的任何东西解释为 UTC,因为这就是 ISO 8601 标准中的 Z 的含义。这最终是您面临的问题的根本原因。

    如果您想让它反射(reflect)一个不明确的本地时间(因为时区可能在您的 .ics 中的其他地方?),则完全省略 Z。但是,如果您打算包括时区偏移量,那么您可以对 DateTime 值使用 K 说明符,或者结合使用 zzz 说明符具有 DateTimeOffset 值 - 取决于您的具体需求。

  • 正如其他人所指出的,DateTime 不是时区感知的,但也要注意 DateTimeOffset 也不是,因为它只跟踪与 UTC 的偏移量而不是一个特定的时区。例如,它可以跟踪 -07:00,但它不能告诉你现在是山区时间。这就是 Noda Time 有其 ZonedDateTime 类型的原因。 .Net 本身没有任何此类内置类型。

  • 在您的代码中,而不是在对 TimeZoneInfo.ConvertTime 的调用中,dateTime1 变量的 .Kind 将被考虑在内。如果是 DateTimeKind.Utc,则结果将是确定性的。但如果它是 DateTimeKind.UnspecifiedDateTimeKind.Local,那么它将被视为就好像是根据本地计算机的时区 - 即 服务器您的时区。

  • 请注意,最好以不管服务器时区设置如何,都表现相同的方式编写代码。这通常意味着避免使用 DateTimeKind.Local,例如 DateTime.NowTimeZoneInfo.Local 等。相反,使用 DateTime.UtcNow 获取当前的 DateTime。或者,您可以使用 DateTimeOffset.NowDateTimeOffset.UtcNow,或者 Noda Time 的 IClock 实现中的方法之一。

归根结底,尽管您的问题有多种可能的解决方案,但在特定时区将当前时间生成为字符串的最简单方法是:

TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTime utcNow = DateTime.UtcNow;
DateTime converted = TimeZoneInfo.ConvertTime(utcNow, destinationTimeZone);
string s = converted.ToString("yyyyMMddTHHmmss");

或者你可能想要:

TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTimeOffset utcNow = DateTimeOffset.UtcNow;
DateTimeOffset converted = TimeZoneInfo.ConvertTime(utcNow, destinationTimeZone);
string s = converted.ToString("yyyyMMddTHHmmsszzz").Replace(":","");

请注意在末尾通过 Replace 删除了 : - 这是因为在 ISO 8601 basic 格式中,偏移量应该类似于-0500 而不是 -05:00。不幸的是,没有格式说明符可以直接获取它。 (只有 ISO 8601 扩展 格式使用冒号)。

关于c# - 替换时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50277481/

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