洪星的博客(原创版,新闻除外)

信息技术 软件开发 电信 移动通信(欢迎和我交流:QQ219402,15152399197)

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  12 随笔 :: 0 文章 :: 62 评论 :: 0 引用

公告

最新评论

共4页: 1 2 3 4 下一页 
Re:C# 获取 MAC 地址 IP 地址 最简单的 David.Yang 2010-07-04 17:57  
太好了,非常感谢楼主!
[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] 怎么问?
[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] 哈,你说的也对哦。。。。。 要不,发封信去问问微软?
[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]洪星: [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的行为影响大的多。所以微软选择了后者。
[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]
[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,这一块的确很混乱。。。。
[quote]洪星: [quote]Bob-wei: 首先,Parse方法与ToString方法是逆运算关系吗? 然后,博主可以试着用DateTimeOffset对象做一遍。 [/quote] [b]我们是在讨论 DateTime 的 BUG! Parse方法与ToString方法是逆运算关系吗? 答: 有。 但是会损失精度,和/或丢失 Kind 属性。[/b][/quote] MSDN里有说他们是逆运算关系?它们只是两个不同功能的函数,甚至一个是静态的,要说共同点都支持格式化接口。又怎么会看作是BUG? 遇到时区的问题,建议使用DateTimeOffse类型。
[quote]不死鸟之魂: 这个不是bug。原理很简单: 1、.net 认为所有的 DateTime都是本地时间。 2、用ToString("U") 输出的只是本地时间的一个UTC对应时间的字符串(可以理解为image)。 3、用Parse转换的时候,DateTime其实人的后面的Z,但是你看到和使用的都是本地时间。你可以试试这时候还用ToString("U")的话,得到的和原来的一样。 [/quote] [b]注意,文章中讨论的是小写的“u”。[/b]
[quote]Teamleader:北京时间是东八区 和 格林威治差8小时 [/quote] [b]小学课本里好像有你所说的内容。[/b]
[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]Bob-wei: 首先,Parse方法与ToString方法是逆运算关系吗? 然后,博主可以试着用DateTimeOffset对象做一遍。 [/quote] [b]我们是在讨论 DateTime 的 BUG! Parse方法与ToString方法是逆运算关系吗? 答: 有。 但是会损失精度,和/或丢失 Kind 属性。[/b]
.NET Framework 2.0增加了DateTimeOffset来协助解决这个问题。
问题出在你的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 方法明确设置。
首先,Parse方法与ToString方法是逆运算关系吗? 然后,博主可以试着用DateTimeOffset对象做一遍。
北京时间是东八区 和 格林威治差8小时 ,地理上也学过,如果你用过Json系列化时间的话,通过js去反系列化json对象,你就知道改加8个小时转化为北京时间了
如果要是有bug的话,你用Parse得到的,就会使把UTC时间当成本地时间来用,这样就真的错了。
这个不是bug。原理很简单: 1、.net 认为所有的 DateTime都是本地时间。 2、用ToString("U") 输出的只是本地时间的一个UTC对应时间的字符串(可以理解为image)。 3、用Parse转换的时候,DateTime其实人的后面的Z,但是你看到和使用的都是本地时间。你可以试试这时候还用ToString("U")的话,得到的和原来的一样。
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")啊。
@辰 使用 DateTimeStyles.AdjustToUniversal 参数, 会将时间转换为 UTC 时间 2010年3月14日 20:09:15,而实际是本地时间,也就是北京时间。
共4页: 1 2 3 4 下一页