[英]Strange Behaviour in DateTime.TryParse
我正在嘗試解析日期時間字符串“5-5-5-5”
DateTime.TryParse("5-5-5-5", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out result);
我希望這可以轉換為
5/5/2005 5:00:00 AM
但相反,它被轉換為
5/5/2005 10:30:00 AM.
看起來它將提供的日期時間解釋為 GMT。 這有點違反直覺,因為我已經指定了AssumeLocal
標志。 這是DateTime
類中的錯誤嗎?
我理解您的觀點並調試 dot net 框架代碼以了解后台發生的情況。
TryParse
方法忽略DateTimeStyles.AssumeLocal
標志並且只處理AdjustToUniversal
標志。
if ((styles & DateTimeStyles.AdjustToUniversal) != 0) {
return (AdjustTimeZoneToUniversal(ref result));
}
return (AdjustTimeZoneToLocal(ref result, bTimeOnly));
另一方面,
TryParseExact
方法已正確實現,它具有處理DateTimeStyles.AssumeLocal
標志所需的所有邏輯。 查看此實現中如何處理其他案例。
// If AssumeLocal or AssumeLocal is used, there will always be a kind specified. As in the
// case when a time zone is present, it will default to being local unless AdjustToUniversal
// is present. These comparisons determine whether setting the kind is sufficient, or if a
// time zone adjustment is required. For consistentcy with the rest of parsing, it is desirable
// to fall through to the Adjust methods below, so that there is consist handling of boundary
// cases like wrapping around on time-only dates and temporarily allowing an adjusted date
// to exceed DateTime.MaxValue
if ((styles & DateTimeStyles.AssumeLocal) != 0) {
if ((styles & DateTimeStyles.AdjustToUniversal) != 0) {
result.flags |= ParseFlags.TimeZoneUsed;
result.timeZoneOffset = TimeZoneInfo.GetLocalUtcOffset(result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime);
}
else {
result.parsedDate = DateTime.SpecifyKind(result.parsedDate, DateTimeKind.Local);
return true;
}
}
else if ((styles & DateTimeStyles.AssumeUniversal) != 0) {
if ((styles & DateTimeStyles.AdjustToUniversal) != 0) {
result.parsedDate = DateTime.SpecifyKind(result.parsedDate, DateTimeKind.Utc);
return true;
}
else {
result.flags |= ParseFlags.TimeZoneUsed;
result.timeZoneOffset = TimeSpan.Zero;
}
}
else {
// No time zone and no Assume flags, so DateTimeKind.Unspecified is fine
Contract.Assert(result.parsedDate.Kind == DateTimeKind.Unspecified, "result.parsedDate.Kind == DateTimeKind.Unspecified");
return true;
}
旁注,調試 Dot Net 框架代碼很有趣。 如果您有興趣,請按照此處的步驟操作。
如果你想要想要的結果:
2005/5/5 上午 5:00:00
日期和時間作為協調世界時 (UTC) 返回。 如果輸入字符串表示本地時間,則通過時區說明符或 AssumeLocal,日期和時間將從本地時間轉換為 UTC。 如果輸入字符串通過時區說明符或 AssumeUniversal 表示 UTC 時間,則不會發生轉換。 如果輸入字符串不表示本地時間或 UTC 時間,則不會發生轉換,並且生成的 Kind 屬性為 Unspecified。 此值不能與 RoundtripKind 一起使用。
使用以下代碼作為AdjustToUniversal
:
DateTime result;
dt= DateTime.TryParse("5-5-5-5" , CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal , out result);
DateTimeStyles.AdjustToUniversal
正是您要找的。
當未指定時區時,您必須使用AssumeLocal
或AssumeUniversal
明確指示時區,然后使用AdjustToUniversal
將其轉換為 UTC:
DateTimeStyles.AssumeLocal | DateTimeStyles.AdjustToUniversal
或者
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal
在MSDN上閱讀更多內容並注意最后一句話:
調整到通用:
如果輸入字符串表示本地時間,則通過時區說明符或
AssumeLocal
將日期和時間從本地時間轉換為 UTC 。如果輸入字符串通過時區說明符或
AssumeUniversal
表示UTC 時間,則不會發生轉換。如果輸入字符串不表示本地時間或 UTC 時間,則不會發生轉換,並且生成的 Kind 屬性為 Unspecified。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.