[英]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 ignoringDateTimeStyles.AssumeLocal
flag and OnlyAdjustToUniversal
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 handleDateTimeStyles.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
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
:当未指定时区时,您必须使用
AssumeLocal
或AssumeUniversal
明确指示时区,然后使用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.