最新评论
Re:C# 获取 MAC 地址 IP 地址 最简单的 David.Yang 2010-07-04 17:57
太好了,非常感谢楼主!
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗?请高手解答! 洪星 2010-03-15 18:36
[quote]Ivony...:
[quote]洪星:
[quote]Ivony...:
[quote]洪星:
[b]你是高手![/b]
[b]在 ToString("u") 方法中,问题就是 DateTime 的 Kind 属性为 Local 时,却不返回末尾跟“Z”表示为 UTC 时间的字符串,而是返回末尾跟“Z”表示为本地时间的字符串。[/b][/quote]
这个,其实可以解释为向下兼容。。。。。
因为那啥,.NET Framework 1.x没有Kind属性,所以DateTime不知道自己是什么东东,所以ToString就只能这样,但.NET Framework 2.0增加了Kind属性,但如...[/quote]
怎么问?
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗?请高手解答! Ivony... 2010-03-15 17:16
[quote]洪星:
[quote]Ivony...:
[quote]洪星:
[b]你是高手![/b]
[b]在 ToString("u") 方法中,问题就是 DateTime 的 Kind 属性为 Local 时,却不返回末尾跟“Z”表示为 UTC 时间的字符串,而是返回末尾跟“Z”表示为本地时间的字符串。[/b][/quote]
这个,其实可以解释为向下兼容。。。。。
因为那啥,.NET Framework 1.x没有Kind属性,所以DateTime不知道自己是什么东东,所以ToString就只能这样,但.NET Framework 2.0增加了Kind属性,但如果行为不同显然会造成更大的问题,所以没改。
不过你说的...[/quote]
[b]很感谢你的回答!
但是我还是有个疑问:
如果是为了考虑兼容,可以对 Unspecified 不转换,但是为 Local 和 Utc 时,可以在 ToString("u") 时转换为 Utc,因为 .NET 1.X 的 DateTime 没有 Kind,也就不会有 Local 和 Utc 的兼容性问题。[/b][/quote]
哈,你说的也对哦。。。。。
要不,发封信去问问微软?
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗?请高手解答! 洪星 2010-03-15 17:07
[quote]Ivony...:
[quote]洪星:
[b]你是高手![/b]
[b]在 ToString("u") 方法中,问题就是 DateTime 的 Kind 属性为 Local 时,却不返回末尾跟“Z”表示为 UTC 时间的字符串,而是返回末尾跟“Z”表示为本地时间的字符串。[/b][/quote]
这个,其实可以解释为向下兼容。。。。。
因为那啥,.NET Framework 1.x没有Kind属性,所以DateTime不知道自己是什么东东,所以ToString就只能这样,但.NET Framework 2.0增加了Kind属性,但如果行为不同显然会造成更大的问题,所以没改。
不过你说的...[/quote]
[b]很感谢你的回答!
但是我还是有个疑问:
如果是为了考虑兼容,可以对 Unspecified 不转换,但是为 Local 和 Utc 时,可以在 ToString("u") 时转换为 Utc,因为 .NET 1.X 的 DateTime 没有 Kind,也就不会有 Local 和 Utc 的兼容性问题。[/b]
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗?请高手解答! Ivony... 2010-03-15 16:33
[quote]洪星:
[b]你是高手![/b]
[b]在 ToString("u") 方法中,问题就是 DateTime 的 Kind 属性为 Local 时,却不返回末尾跟“Z”表示为 UTC 时间的字符串,而是返回末尾跟“Z”表示为本地时间的字符串。[/b][/quote]
这个,其实可以解释为向下兼容。。。。。
因为那啥,.NET Framework 1.x没有Kind属性,所以DateTime不知道自己是什么东东,所以ToString就只能这样,但.NET Framework 2.0增加了Kind属性,但如果行为不同显然会造成更大的问题,所以没改。
不过你说的的确是有道理的,即使.NET Framework 1.x没有Kind属性,但根据设计思想,例如有ToUniversalTime方法,而这个方法总是会把DateTime当作本地时间,从这个方法的行为推断,微软总是将DateTime认为是本地时间的。
但还是有问题,因为DateTime.UtcNow在.NET Framework 1.x也是存在的,当然DateTime.Parse也能从UTC格式中还原DateTime。所以,微软还是可以说自己搞不清DateTime到底是本地时间。
其实研究到这里我们差不多可以知道问题出在哪里了。在.NET Framework 1.x的时候,微软存在一个设计上的失误,这个失误将导致如下代码得到令人费解的结果:
[code=csharp]
DateTime.UtcNow.ToUniversalTime()
[/code]
从这些属性和方法的行为可知,DateTime.UtcNow将会返回当前的UTC时间,而ToUniversalTime又会把这个时间当作本地时间来玩。
换言之ToUniversalTime要求用户自己清醒的知道自己在干什么,我认为这是一个很容易把用户玩晕的设计。
当然这个失误在.NET Framework 2.0得到了修正。由于Kind属性的引入,现在ToUniversalTime方法不会转换Kind为Utc的DateTime。
尽管.NET Framework 2.0带来了部分的修正,但我们还是要忍受这样复杂的语法:
[code=csharp]
dateTime.ToUniversalTime().ToString("u");
[/code]
而且,大多数的DateTime都是Unspecified的(例如从数据库读取)。
哎,这真是一个麻烦事儿,还是用DateTimeOffset吧。。。。
所以结论也可以得到了。
因为.NET Framework 1.x时代,所有的DateTime的Kind都是Unspecified的,也就是搞不清是本地时间还是哪里的时间。因为.NET Framework 1.x连Kind属性都没有。
这种情况下:
[code=csharp]
DateTime.ToUniversalTime().ToString("u");
[/code]
和
[code=csharp]
DateTime.ToString("u");//隐式调用ToUniversalTime
[/code]
都不能算是什么完美的写法。
前者在
[code=csharp]
DateTime.UtcNow.ToUniversalTime().ToString("u");
[/code]
容易造成误解
后者在
[code=csharp]
DateTime.Parse("2010-03-15 14:07:41Z").ToString("u");
[/code]
容易造成误解
当然罪魁是糟糕的设计。
而.NET Framework 2.0要来修补这个问题的时候,发现已经糟糕到没办法修补了,毕竟修改ToString("u")的行为比修改ToUniversalTime的行为影响大的多。所以微软选择了后者。
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗?请高手解答! 洪星 2010-03-15 16:15
[quote]Ivony...:
[quote]洪星:
[quote]Ivony...:
问题出在你的DateTime对象是怎么来的。
因为[b]绝大多数[/b]DateTime对象是不知道自己是本地时间还是UTC时间的,即DateTime.Kind是Unspecified。
如果你将从UTC时间Parse来的DateTime再转回去应该就没问题了。
在对DateTime进行序列化保存时,一定要明确DateTime.Kind属性。
给LZ一段参考代码:
[code=csharp]
frameData.Add
(
new XAttribute( "GUID"...[/quote]
[b]你是高手![/b]
[b]在 ToString("u") 方法中,问题就是 DateTime 的 Kind 属性为 Local 时,却不返回末尾跟“Z”表示为 UTC 时间的字符串,而是返回末尾跟“Z”表示为本地时间的字符串。[/b]
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗?请高手解答! Ivony... 2010-03-15 15:48
[quote]洪星:
[quote]Ivony...:
问题出在你的DateTime对象是怎么来的。
因为[b]绝大多数[/b]DateTime对象是不知道自己是本地时间还是UTC时间的,即DateTime.Kind是Unspecified。
如果你将从UTC时间Parse来的DateTime再转回去应该就没问题了。
在对DateTime进行序列化保存时,一定要明确DateTime.Kind属性。
给LZ一段参考代码:
[code=csharp]
frameData.Add
(
new XAttribute( "GUID", Guid.NewGuid() ),
...[/quote]
[b]DateTime.Now 的 Kind 属性为 Local。[/b][/quote]
我明白你的意思了。。。。
这个问题的确可以认为是一个缺陷,我之前也被那啥过,如果你的DateTime的Kind属性是正确的话,正确的写法是:
DateTime.ToUniversalTime().ToString("u");
当然我们可以问微软为什么不自动干这件事情,还有ToUniversalTime()也没有一个TimeZone或TimeZoneInfo参数的重载。反正我没想明白。
不过刚看帮助说Unspecified也会被认为是Local,哎,我觉得还是从源头开始,所有的时间都是Utc的最好,否则一个DateTime在时区是A的代码中创建,到时区是B的代码中转换,还是会出问题。
或者干脆用DateTimeOffset,这一块的确很混乱。。。。
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗?请高手解答! Bob-wei 2010-03-15 15:25
[quote]洪星:
[quote]Bob-wei:
首先,Parse方法与ToString方法是逆运算关系吗?
然后,博主可以试着用DateTimeOffset对象做一遍。
[/quote]
[b]我们是在讨论 DateTime 的 BUG!
Parse方法与ToString方法是逆运算关系吗?
答:
有。
但是会损失精度,和/或丢失 Kind 属性。[/b][/quote]
MSDN里有说他们是逆运算关系?它们只是两个不同功能的函数,甚至一个是静态的,要说共同点都支持格式化接口。又怎么会看作是BUG?
遇到时区的问题,建议使用DateTimeOffse类型。
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? 洪星 2010-03-15 14:39
[quote]不死鸟之魂:
这个不是bug。原理很简单:
1、.net 认为所有的 DateTime都是本地时间。
2、用ToString("U") 输出的只是本地时间的一个UTC对应时间的字符串(可以理解为image)。
3、用Parse转换的时候,DateTime其实人的后面的Z,但是你看到和使用的都是本地时间。你可以试试这时候还用ToString("U")的话,得到的和原来的一样。
[/quote]
[b]注意,文章中讨论的是小写的“u”。[/b]
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? 洪星 2010-03-15 14:37
[quote]Teamleader:北京时间是东八区 和 格林威治差8小时 [/quote]
[b]小学课本里好像有你所说的内容。[/b]
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? 洪星 2010-03-15 14:36
[quote]Ivony...:
问题出在你的DateTime对象是怎么来的。
因为[b]绝大多数[/b]DateTime对象是不知道自己是本地时间还是UTC时间的,即DateTime.Kind是Unspecified。
如果你将从UTC时间Parse来的DateTime再转回去应该就没问题了。
在对DateTime进行序列化保存时,一定要明确DateTime.Kind属性。
给LZ一段参考代码:
[code=csharp]
frameData.Add
(
new XAttribute( "GUID", Guid.NewGuid() ),
...[/quote]
[b]DateTime.Now 的 Kind 属性为 Local。[/b]
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? 洪星 2010-03-15 14:35
[quote]Bob-wei:
首先,Parse方法与ToString方法是逆运算关系吗?
然后,博主可以试着用DateTimeOffset对象做一遍。
[/quote]
[b]我们是在讨论 DateTime 的 BUG!
Parse方法与ToString方法是逆运算关系吗?
答:
有。
但是会损失精度,和/或丢失 Kind 属性。[/b]
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? Ivony... 2010-03-15 11:04
.NET Framework 2.0增加了DateTimeOffset来协助解决这个问题。
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? Ivony... 2010-03-15 11:02
问题出在你的DateTime对象是怎么来的。
因为[b]绝大多数[/b]DateTime对象是不知道自己是本地时间还是UTC时间的,即DateTime.Kind是Unspecified。
如果你将从UTC时间Parse来的DateTime再转回去应该就没问题了。
在对DateTime进行序列化保存时,一定要明确DateTime.Kind属性。
给LZ一段参考代码:
[code=csharp]
frameData.Add
(
new XAttribute( "GUID", Guid.NewGuid() ),
new XAttribute( "PublishDate", DateTime.UtcNow.ToString( "u" ) ),
new XElement( "Author", document.GetDocument().Meta.Author ),
[/code]
可以看出来,在这段代码里,明确使用了DateTime.UtcNow来获取当前的UTC时间,然后再ToString( "u" ) )。
如果你知道DateTime.Kind应该是本地时间,应使用DateTime.SpecifyKind 方法明确设置。
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? Bob-wei 2010-03-15 10:24
首先,Parse方法与ToString方法是逆运算关系吗?
然后,博主可以试着用DateTimeOffset对象做一遍。
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? Teamleader 2010-03-15 09:36
北京时间是东八区 和 格林威治差8小时 ,地理上也学过,如果你用过Json系列化时间的话,通过js去反系列化json对象,你就知道改加8个小时转化为北京时间了
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? 不死鸟之魂 2010-03-15 09:04
如果要是有bug的话,你用Parse得到的,就会使把UTC时间当成本地时间来用,这样就真的错了。
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? 不死鸟之魂 2010-03-15 09:03
这个不是bug。原理很简单:
1、.net 认为所有的 DateTime都是本地时间。
2、用ToString("U") 输出的只是本地时间的一个UTC对应时间的字符串(可以理解为image)。
3、用Parse转换的时候,DateTime其实人的后面的Z,但是你看到和使用的都是本地时间。你可以试试这时候还用ToString("U")的话,得到的和原来的一样。
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? Anders Liu 2010-03-14 23:04
string s = DateTime.Now.ToString("u");//2010-03-14 20:09:15Z
DateTime t = DateTime.Parse(s);//2010-3-15 4:09:15
你怎么打印出来的t的值?如果是t.ToString(),得到的当然是本地时间的表示方式啊。必须也用t.ToString("u")啊。
Re:.NET DateTime 格式字符串的问题,是微软的 BUG 吗? 洪星 2010-03-14 21:18
@辰
使用 DateTimeStyles.AdjustToUniversal 参数,
会将时间转换为 UTC 时间 2010年3月14日 20:09:15,而实际是本地时间,也就是北京时间。

