簡體   English   中英

DateTime.TryParse 中的奇怪行為

[英]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正是您要找的。

當未指定時區時,您必須使用AssumeLocalAssumeUniversal明確指示時區,然后使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM