cob*_*nks 1 c# timezone datetime
我一直在为此苦苦挣扎,所以我会选择 SO。
我有一个应用程序,需要将字符串解析为日期时间。字符串如下所示:
"201503131557"
Run Code Online (Sandbox Code Playgroud)
(它们将始终采用“yyyyMMddHHmm”这种格式)并且始终采用中部标准时间(或中部夏令时,具体取决于日期),即使它们没有指定。
当我解析它们时,我明白它会将它们解析为本地时间。我在 Azure PaaS 上运行,并且不想为了支持此操作而将其更改为在 CST 中运行。
我如何编写同时在本地和 Azure PaaS 中运行的代码,以便将这些日期正确解析为 DateTimes 并将其时区设置为 CST?
这是我为证明 Matt Johnson 的答案而编写的快速单元测试。
[TestMethod]
public void DateTests()
{
var unSpecDt = DateTime.ParseExact("201503131557", "yyyyMMddHHmm", CultureInfo.InvariantCulture);
var tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var utcDt = TimeZoneInfo.ConvertTimeToUtc(unSpecDt, tz);
var offset = tz.GetUtcOffset(unSpecDt);
var dto =new DateTimeOffset(unSpecDt, offset);
var cstDt = dto.DateTime;
Assert.IsTrue(cstDt.Hour - utcDt.Hour == offset.Hours);
}
Run Code Online (Sandbox Code Playgroud)
要解析字符串,因为您只有日期和时间,并且您知道字符串将采用的特定格式,请执行以下操作:
DateTime dt = DateTime.ParseExact("201503131557", "yyyyMMddHHmm", CultureInfo.InvariantCulture);
Run Code Online (Sandbox Code Playgroud)
结果值将其Kind属性设置为DateTimeKind.Unspecified(不是您认为的当地时间)。这是意料之中的,因为您没有提供有关此时间戳如何与 UTC 或本地时间相关的信息。
您说该值代表中部标准时间的时间。您将需要一个TimeZoneInfo了解该时区的对象。
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
Run Code Online (Sandbox Code Playgroud)
请注意,此标识符表示在美国观察到的中部时间,包括 CST 或 CDT,具体取决于哪个对给定值有效(尽管其名称中有“标准”一词)。另请注意,它仅在 Windows 操作系统上有效。如果您想在其他操作系统上使用 .NET Core,则需要改为传递 IANA 标识符"America/Chicago"(或使用我的TimeZoneConverter库在任何平台上使用任一标识符)。
下一步是弄清楚你想用这个值做什么。你可以用它做一些不同的事情:
如果要将其转换为等效的 UTC 值,表示为 a DateTime,则可以执行以下操作:
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(dt, tz);
Run Code Online (Sandbox Code Playgroud)如果您想要一个DateTimeOffset表示包含您提供的输入以及与美国中部时间相关的 UTC 偏移量,那么您可以执行以下操作:
TimeSpan offset = tz.GetUtcOffset(dt);
DateTimeOffset dto = new DateTimeOffset(dt, offset);
Run Code Online (Sandbox Code Playgroud)
请记住,如果输入时间接近 DST 转换,则输入时间可能无效或不明确。在这种情况下,该GetUtcOffset方法将返回标准偏移量。如果你想要不同的行为,你有更多的代码要写(超出了这篇文章的范围)。
您还可以做其他事情,所有这些都由TimeZoneInfo班级提供。
请注意,“Azure PaaS”可能指的是一些不同的东西,虽然WEBSITE_TIME_ZONEAzure 应用服务中有一个名为的设置- 我不建议您依赖它。仅当您无法控制代码时才将其视为最后的手段。在大多数情况下,编写代码时最好不要依赖于它运行的系统的时区设置。这意味着永远不要调用DateTime.Now, or TimeZoneInfo.Local, DateTime.ToLocalTime, 甚至DateTime.ToUniversalTime(因为它从本地时区转换)等。相反,依赖于明确使用 UTC 或特定时区或偏移量的方法。那么您将永远不需要关心您的应用程序的托管位置。
最后,要了解 theDateTime或DateTimeOffsettypes 都没有能力理解值与特定时区相关联。为此,您需要编写自己的类,或者查看提供此类功能的Noda Time库ZonedDateTime。
| 归档时间: |
|
| 查看次数: |
1336 次 |
| 最近记录: |