将UTC / GMT时间转换为本地时间
我们正在开发一个Web服务客户端的C#应用程序。 这将在Windows XP PC上运行。
Web服务返回的一个字段是DateTime字段。 服务器以GMT格式返回一个字段,即最后一个“Z”。
但是,我们发现.NET似乎做了某种隐式转换,时间总是12个小时。
下面的代码示例在一定程度上解决了这个问题,12小时的差异已经消失了,但是不允许新西兰夏令时。
CultureInfo ci = new CultureInfo("en-NZ"); string date = "Web service date".ToString("R", ci); DateTime convertedDate = DateTime.Parse(date);
根据这个date的网站 :
UTC / GMT偏移
标准时区:UTC / GMT +12小时
夏令时:1小时
当前时区偏移: UTC / GMT +13小时
我们如何调整额外的小时? 这可以通过编程来完成吗?或者这是PC上的某种设置?
对于诸如2012-09-19 01:27:30.000
string, DateTime.Parse
无法知道date和时间来自哪个时区。
DateTime
有一个Kind属性,可以有三个时区选项之一:
- 不明
- 本地
- 世界标准时间
注意 如果您希望表示UTC以外的date/时间或当地时区,则应使用DateTimeOffset
。
所以对于你的问题中的代码:
DateTime convertedDate = DateTime.Parse(dateStr); var kind = convertedDate.Kind; // will equal DateTimeKind.Unspecified
你说你知道它是什么样的,所以告诉它。
DateTime convertedDate = DateTime.SpecifyKind( DateTime.Parse(dateStr), DateTimeKind.Utc); var kind = convertedDate.Kind; // will equal DateTimeKind.Utc
现在,一旦系统知道UTC时间,就可以调用ToLocalTime
:
DateTime dt = convertedDate.ToLocalTime();
这会给你你需要的结果。
如果你在.NET 3.5中,我会考虑使用System.TimeZoneInfo类。 请参阅http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx 。 这应该考虑夏令时更改正确。
// Coordinated Universal Time string from // DateTime.Now.ToUniversalTime().ToString("u"); string date = "2009-02-25 16:13:00Z"; // Local .NET timeZone. DateTime localDateTime = DateTime.Parse(date); DateTime utcDateTime = localDateTime.ToUniversalTime(); // ID from: // "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Time Zone" // See http://msdn.microsoft.com/en-us/library/system.timezoneinfo.id.aspx string nzTimeZoneKey = "New Zealand Standard Time"; TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(nzTimeZoneKey); DateTime nzDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, nzTimeZone);
TimeZone.CurrentTimeZone.ToLocalTime(date);
DateTime
对象默认情况下具有“ Unspecified
Kind
”,对于ToLocalTime
而言,它被假定为UTC
。
要获取Unspecified
DateTime
对象的本地时间,您只需要这样做:
convertedDate.ToLocalTime();
将DateTime
的Kind
从Unspecified
更改为UTC
是不必要的。 为了ToLocalTime
的目的, Unspecified
被假定为UTC
: http : //msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx
我知道这是一个较老的问题,但我遇到了类似的情况,我想分享我为未来的search者find的东西,可能包括我自己:)。
DateTime.Parse()
可能会非常棘手 – 请参阅这里例如。
如果DateTime
来自Web服务或其他已知格式的源,则可能需要考虑类似的东西
DateTime.ParseExact(dateString, "MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)
或者,甚至更好,
DateTime.TryParseExact(...)
AssumeUniversal
标志告诉parsing器date/时间已经是UTC; AssumeUniversal
和AdjustToUniversal
的组合告诉它不要将结果转换为“本地”时间,默认情况下它会尝试执行。 (我个人试图在业务/应用/服务层中专门处理UTC,但绕过本地时间的转换也会加快速度 – 在我的testing中速度提高了50%以上,见下文)。
以下是我们之前的工作:
DateTime.Parse(dateString, new CultureInfo("en-US"))
我们已经对应用程序进行了分析,发现DateTime.Parse代表了CPU占用率的很大一部分。 (顺便说一句, CultureInfo
构造函数不是 CPU使用率的重要贡献者。)
所以我设置了一个控制台应用程序来以各种方式parsing10000次date/时间string。 底线:
Parse()
10秒
ParseExact()
(转换为本地)20-45毫秒
ParseExact()
(不转换为本地)10-15毫秒
…是的, Parse()
的结果是以秒为单位的 ,而其他的则以毫秒为单位 。
我只想补充一点小心。
如果你只是从计算机的内部时钟获取当前时间,在显示屏或报告上inputdate/时间,那么一切都很好。 但是,如果您保存date/时间信息供以后参考或计算date/时间,请注意!
假设您确定一艘邮轮在2007年12月20日15:00 UTC抵达檀香山。 而且你想知道当地时间是什么。
1.可能至less涉及三名“本地人”。 本地可能意味着檀香山,也可能意味着您的计算机所在的位置,也可能意味着您的客户所在的位置。
2.如果使用内置函数进行转换,则可能是错误的。 这是因为夏令时(可能)目前在您的计算机上生效,但在十二月份不生效。 但Windows不知道这一切……它只有一个标志来确定夏时制是否正在生效。 如果目前正在实施,那么在十二月份的某个date,它会很乐意地增加一个小时。
夏令时在各个政治分支中的实施方式不同(或根本不同)。 不要以为只是因为你的国家在某个具体的日子发生了变化,其他国家也会这样。
不要忘记,如果你已经有了一个DateTime对象,并且不确定它是UTC还是Local,那么很容易直接使用对象的方法:
DateTime convertedDate = DateTime.Parse(date); DateTime localDate = convertedDate.ToLocalTime();
我们如何调整额外的小时?
除非指定.net将使用本地电脑设置。 我会阅读: http : //msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx
通过外观代码可能看起来像这样:
DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges( year );
如上所述,仔细检查你的服务器是在什么时区设置的。 有网上的文章如何安全地影响在IIS中的变化。
在回答达纳的build议时:
代码示例如下所示:
string date = "Web service date"..ToString("R", ci); DateTime convertedDate = DateTime.Parse(date); DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(convertedDate);
最初的date是20/08/08; 那种是UTC。
“convertedDate”和“dt”都是一样的:
21/08/08 10:00:26; 那种是当地的
我遇到了一个问题,它是在一个数据集被推送通过networking(web服务到客户端),它会自动更改,因为DataColumn的DateType字段设置为本地。 确保你检查什么DateType是如果你推动DataSets跨。
如果您不想更改,请将其设置为“未指定”
我遇到了这个问题,因为我在通过twitter API(status上的created_at字段)返回UTCdate时遇到了问题。 我需要将它们转换为DateTime。 在这个页面的答案中没有答案/代码样本足以阻止我得到一个“string不被认为是有效的DateTime”错误(但它是最接近的,我必须find正确的答案)
张贴这个链接在这里,以防万一这有助于别人 – 我需要的答案是在这篇博客上发现: http : //www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ – 基本上使用DateTime.ParseExact格式string,而不是DateTime.Parse
@TimeZoneInfo.ConvertTimeFromUtc(timeUtc, TimeZoneInfo.Local)
- 为什么DateTime.ParseExact()不能用“M / d / yyyy”parsing“9/1/2009”
- 什么时候应该使用Tracing vs Logger.NET,Enterprise Library,log4net或Ukadc.Diagnostics?
- MissingManifestResourceException意味着什么以及如何解决它?
- Marshal.SizeOf在枚举上抛出ArgumentException
- 正确使用IDisposable接口
- 在交易中使用“GO”
- 财产是否应该与其types相同?
- C#:在GPU上执行操作,而不是CPU(计算Pi)
- 如何以编程方式保存URL中的图片?