将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);

根据这个约会网站:

UTC / GMT抵消

标准时区:UTC/GMT +12小时
夏令时:+1小时
当前时区偏移量:UTC/GMT +13小时

我们如何调整额外的一小时?这可以通过编程来完成吗?或者这是PC上的某种设置吗?

474311 次浏览
TimeZone.CurrentTimeZone.ToLocalTime(date);

对于Dana的建议:

代码示例现在看起来像:

string date = "Web service date"..ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(convertedDate);

原定日期是2008年8月20日;就是UTC。

convertedDate和dt都是一样的:

21/08/08 10:00:26;这种是本地的

我有一个问题,它是在一个数据集被推到电线(网络服务到客户端),它会自动改变,因为DataColumn的DateType字段被设置为本地。确保你在推数据集时检查DateType是什么。

如果不希望更改,则将其设置为Unspecified

我只是想补充一个一般性的警告。

如果你所做的只是从计算机内部时钟获取当前时间,然后将日期/时间显示在显示器或报告上,那么一切都很好。但如果你是储蓄日期/时间信息供以后参考或计算日期/时间,小心!

假设您确定一艘游轮于2007年12月20日15:00 UTC抵达檀香山。你想知道当地时间是多少
可能至少有三个“当地人”参与其中。Local可能是指檀香山,也可能是指您的计算机所在的位置,也可能是指您的客户所在的位置 2.如果你使用内置函数来进行转换,它可能是错误的。这是因为夏令时(可能)目前在您的计算机上生效,但在12月不生效。但是Windows不知道这一点……它只有一个标志来确定夏令时目前是否有效。如果它现在生效,那么它将很高兴地在12月的某个日期上增加一个小时 3.在不同的政治分区中,夏令时的实施方式不同(或根本不实施)。不要以为你的国家在某一天改变了,其他国家也会这样。

不要忘记,如果你已经有一个DateTime对象,并且不确定它是UTC还是Local,直接使用对象上的方法是很容易的:

DateTime convertedDate = DateTime.Parse(date);
DateTime localDate = convertedDate.ToLocalTime();

我们如何调整额外的一小时?

除非指定。net将使用本地pc设置。我将读取:http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx

从外观上看,代码可能是这样的:

DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges( year );

如上所述,仔细检查您的服务器设置的时区。网上有关于如何安全地影响IIS中的更改的文章。

我会考虑使用这套系统。TimeZoneInfo类,如果你在。net 3.5。看到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);

对于像2012-09-19 01:27:30.000这样的字符串,DateTime.Parse不能告诉日期和时间来自哪个时区。

DateTime有一个种类属性,它可以有三个时区选项之一:

  • 未指明的
  • 当地的
  • Utc

请注意 如果您希望表示UTC或本地时区以外的日期/时间,则应该使用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();

这将给你你需要的结果。

我遇到了这个问题,因为我有一个UTC日期的问题,你通过twitter API (created_at字段的状态);我需要将它们转换为DateTime。本页上的答案/代码示例中的答案都不足以阻止我得到“字符串不被识别为有效的DateTime”错误(但这是我在SO上找到正确答案的最接近的答案)

在这里发布这个链接,以防这有助于其他人-我需要的答案在这篇博客文章中找到:http://www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ -基本上使用DateTime。ParseExact使用格式字符串代替DateTime。解析

我知道这是一个老问题,但我遇到过类似的情况,我想分享我的发现给未来的搜索者,可能包括我自己:)。

DateTime.Parse()可能很棘手——例如,请参阅在这里

如果DateTime来自Web服务或其他具有已知格式的源,您可能需要考虑类似于

DateTime.ParseExact(dateString,
"MM/dd/yyyy HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)

或者更好的是,

DateTime.TryParseExact(...)

AssumeUniversal标志告诉解析器日期/时间已经是UTC;AssumeUniversalAdjustToUniversal的组合告诉它不要将结果转换为“本地”时间,默认情况下它会尝试这样做。(无论如何,我个人尝试在业务/应用程序/服务层专门处理UTC。但跳过转换到本地时间也会加快速度——在我的测试中,速度加快了50%或更多,见下文。)

这是我们之前所做的:

DateTime.Parse(dateString, new CultureInfo("en-US"))

我们对这款应用进行了分析,发现DateTime。解析占CPU使用的很大比例。(顺便提一下,CultureInfo构造函数是CPU使用的重要贡献者。)

所以我设置了一个控制台应用程序,以各种方式解析日期/时间字符串10000次。底线是:< br > Parse() 10 sec
ParseExact()(转换为本地)20-45 ms
ParseExact()(未转换为本地)10-15 ms
... 是的,Parse()的结果在中,而其他的结果在毫秒

DateTime对象默认具有UnspecifiedKind,为了ToLocalTime的目的,它被假定为UTC

因此,要获取Unspecified DateTime对象的本地时间,你只需要这样做:

convertedDate.ToLocalTime();

DateTimeKindUnspecified更改为UTC的步骤是不必要的。为了ToLocalTime: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx的目的,Unspecified被假定为UTC

@TimeZoneInfo.ConvertTimeFromUtc(timeUtc, TimeZoneInfo.Local)

该代码块使用通用时间转换当前DateTime对象,然后将其转换回本地DateTime。对我来说是完美的,我希望它能帮助到你!

CreatedDate.ToUniversalTime().ToLocalTime();