简体   繁体   English

DateTime.TryParse 中的奇怪行为

[英]Strange Behaviour in DateTime.TryParse

I'm trying to Parse a DateTime String "5-5-5-5" with我正在尝试解析日期时间字符串“5-5-5-5”

DateTime.TryParse("5-5-5-5", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out result);

I expect this to be converted to我希望这可以转换为

5/5/2005 5:00:00 AM 

But instead it gets converted to但相反,它被转换为

5/5/2005 10:30:00 AM.

Looks like its interpreting the supplied datetime as GMT.看起来它将提供的日期时间解释为 GMT。 Which is a bit counter-intuitive since I've already specified the AssumeLocal flag.这有点违反直觉,因为我已经指定了AssumeLocal标志。 Is this a bug in the DateTime class?这是DateTime类中的错误吗?

I understand your point and debug the dot net framework code to find out what is happening in the background.我理解您的观点并调试 dot net 框架代码以了解后台发生的情况。

TryParse method is ignoring DateTimeStyles.AssumeLocal flag and Only AdjustToUniversal flag is processed. TryParse方法忽略DateTimeStyles.AssumeLocal标志并且只处理AdjustToUniversal标志。

if ((styles & DateTimeStyles.AdjustToUniversal) != 0) {
            return (AdjustTimeZoneToUniversal(ref result));
        }
        return (AdjustTimeZoneToLocal(ref result, bTimeOnly));

On the other hand TryParseExact method is correctly implemented and it has all the required logic to handle DateTimeStyles.AssumeLocal flag.另一方面, TryParseExact方法已正确实现,它具有处理DateTimeStyles.AssumeLocal标志所需的所有逻辑。 See how additional case is handled in this implementation.查看此实现中如何处理其他案例。

            // 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;
            }

On side note, It is fun debugging Dot Net framework code.旁注,调试 Dot Net 框架代码很有趣。 If you are interested then follow steps from here .如果您有兴趣,请按照此处的步骤操作。

If you want the desired result as :如果你想要想要的结果:

5/5/2005 5:00:00 AM 2005/5/5 上午 5:00:00

AdjustToUniversal : 调整到通用

Date and time are returned as a Coordinated Universal Time (UTC).日期和时间作为协调世界时 (UTC) 返回。 If the input string denotes a local time, through a time zone specifier or AssumeLocal, the date and time are converted from the local time to UTC.如果输入字符串表示本地时间,则通过时区说明符或 AssumeLocal,日期和时间将从本地时间转换为 UTC。 If the input string denotes a UTC time, through a time zone specifier or AssumeUniversal, no conversion occurs.如果输入字符串通过时区说明符或 AssumeUniversal 表示 UTC 时间,则不会发生转换。 If the input string does not denote a local or UTC time, no conversion occurs and the resulting Kind property is Unspecified.如果输入字符串不表示本地时间或 UTC 时间,则不会发生转换,并且生成的 Kind 属性为 Unspecified。 This value cannot be used with RoundtripKind.此值不能与 RoundtripKind 一起使用。

use the below code as AdjustToUniversal :使用以下代码作为AdjustToUniversal

DateTime result;
dt= DateTime.TryParse("5-5-5-5" , CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal , out result);

DateTimeStyles.AdjustToUniversal正是您要找的。

When time zone is NOT specified, you must explicitly indicate the time zone using AssumeLocal or AssumeUniversal and then convert it to UTC using AdjustToUniversal :当未指定时区时,您必须使用AssumeLocalAssumeUniversal明确指示时区,然后使用AdjustToUniversal将其转换为 UTC:

DateTimeStyles.AssumeLocal | DateTimeStyles.AdjustToUniversal

or或者

DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal

Read more on MSDN and pay attention to the last sentence:MSDN上阅读更多内容并注意最后一句话:

AdjustToUniversal :调整到通用

If the input string denotes a local time , through a time zone specifier or AssumeLocal , the date and time are converted from the local time to UTC .如果输入字符串表示本地时间,则通过时区说明符或AssumeLocal将日期和时间从本地时间转换为 UTC

If the input string denotes a UTC time , through a time zone specifier or AssumeUniversal , no conversion occurs .如果输入字符串通过时区说明符或AssumeUniversal表示UTC 时间,则不会发生转换

If the input string does not denote a local or UTC time, no conversion occurs and the resulting Kind property is Unspecified.如果输入字符串不表示本地时间或 UTC 时间,则不会发生转换,并且生成的 Kind 属性为 Unspecified。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM