We are developing a C# application for a web-service client. This will run on Windows XP PC's.
我们正在为web服务客户端开发一个c#应用程序。这将在Windows XP电脑上运行。
One of the fields returned by the web service is a DateTime field. The server returns a field in GMT format i.e. with a "Z" at the end.
web服务返回的字段之一是DateTime字段。服务器返回一个位于GMT格式的字段,即末尾有一个“Z”。
However, we found that .NET seems to do some kind of implicit conversion and the time was always 12 hours out.
然而,我们发现。net似乎做了某种隐式转换,时间总是12个小时。
The following code sample resolves this to some extent in that the 12 hour difference has gone but it makes no allowance for NZ daylight saving.
下面的代码示例在一定程度上解决了这一点,因为12小时的差异已经消失,但它不允许NZ日光节约。
CultureInfo ci = new CultureInfo("en-NZ");
string date = "Web service date".ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
As per this date site:
根据本日期网站:
UTC/GMT Offset
UTC / GMT抵消
Standard time zone: UTC/GMT +12 hours
Daylight saving time: +1 hour
Current time zone offset: UTC/GMT +13 hours标准时区:UTC/GMT +12小时夏令时:+1小时当前时区偏移:UTC/GMT +13小时
How do we adjust for the extra hour? Can this be done programmatically or is this some kind of setting on the PC's?
我们如何调整额外的时间?这是通过编程实现的还是在PC上设置的?
11 个解决方案
#1
337
For strings such as 2012-09-19 01:27:30.000
, DateTime.Parse
cannot tell what time zone the date and time are from.
对于像2012-09-19 01:27:30 000 DateTime这样的字符串。解析不能告诉日期和时间来自哪个时区。
DateTime
has a Kind property, which can have one of three time zone options:
DateTime有一个属性,它可以有三个时区选项之一:
- Unspecified
- 未指明的
- Local
- 当地的
- Utc
- Utc
NOTE If you are wishing to represent a date/time other than UTC or your local time zone, then you should use DateTimeOffset
.
注意,如果您希望表示一个日期/时间,而不是UTC或您的本地时区,那么您应该使用DateTimeOffset。
So for the code in your question:
所以对于你的问题的代码:
DateTime convertedDate = DateTime.Parse(dateStr);
var kind = convertedDate.Kind; // will equal DateTimeKind.Unspecified
You say you know what kind it is, so tell it.
你说你知道那是什么,所以说出来。
DateTime convertedDate = DateTime.SpecifyKind(
DateTime.Parse(dateStr),
DateTimeKind.Utc);
var kind = convertedDate.Kind; // will equal DateTimeKind.Utc
Now, once the system knows its in UTC time, you can just call ToLocalTime
:
现在,一旦系统知道它在UTC时间,你可以直接调用ToLocalTime:
DateTime dt = convertedDate.ToLocalTime();
This will give you the result you require.
这将给出您所需的结果。
#2
106
I'd look into using the System.TimeZoneInfo class if you are in .NET 3.5. See http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx. This should take into account the daylight savings changes correctly.
我会考虑使用这个系统。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);
#3
43
TimeZone.CurrentTimeZone.ToLocalTime(date);
#4
15
DateTime
objects have the Kind
of Unspecified
by default, which for the purposes of ToLocalTime
is assumed to be UTC
.
在默认情况下,DateTime对象的类型是未指定的,因此,对于ToLocalTime的目的,假设是UTC。
To get the local time of an Unspecified
DateTime
object, you therefore just need to do this:
要获取未指定的DateTime对象的本地时间,您只需要这样做:
convertedDate.ToLocalTime();
The step of changing the Kind
of the DateTime
from Unspecified
to UTC
is unnecessary. Unspecified
is assumed to be UTC
for the purposes of ToLocalTime
: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx
将日期时间类型从未指定改为UTC的步骤是不必要的。假定为UTC,用于ToLocalTime: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx
#5
15
I know this is an older question, but I ran into a similar situation, and I wanted to share what I had found for future searchers, possibly including myself :).
我知道这是一个老问题,但我遇到了类似的情况,我想把我的发现告诉未来的搜索者,可能包括我自己。
DateTime.Parse()
can be tricky -- see here for example.
解析()可能很棘手,比如这里。
If the DateTime
is coming from a Web service or some other source with a known format, you might want to consider something like
如果DateTime来自Web服务或其他格式已知的源,您可以考虑使用类似的方法
DateTime.ParseExact(dateString,
"MM/dd/yyyy HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)
or, even better,
或者,更好的是,
DateTime.TryParseExact(...)
The AssumeUniversal
flag tells the parser that the date/time is already UTC; the combination of AssumeUniversal
and AdjustToUniversal
tells it not to convert the result to "local" time, which it will try to do by default. (I personally try to deal exclusively with UTC in the business / application / service layer(s) anyway. But bypassing the conversion to local time also speeds things up -- by 50% or more in my tests, see below.)
假定通用标志告诉解析器日期/时间已经是UTC;假定通用和可调遍历的组合告诉它不要将结果转换为“本地”时间,默认情况下它将尝试这样做。(无论如何,我个人尝试在业务/应用程序/服务层专门处理UTC。但绕过转换到本地时间也会加快速度——在我的测试中,速度会提高50%或更多,见下文。
Here's what we were doing before:
下面是我们之前所做的:
DateTime.Parse(dateString, new CultureInfo("en-US"))
We had profiled the app and found that the DateTime.Parse represented a significant percentage of CPU usage. (Incidentally, the CultureInfo
constructor was not a significant contributor to CPU usage.)
我们对应用进行了剖析,发现了DateTime。解析表示CPU使用率的很大百分比。(顺便说一句,CultureInfo构造函数并不是CPU使用的重要贡献者。)
So I set up a console app to parse a date/time string 10000 times in a variety of ways. Bottom line:Parse()
10 secParseExact()
(converting to local) 20-45 msParseExact()
(not converting to local) 10-15 ms
... and yes, the results for Parse()
are in seconds, whereas the others are in milliseconds.
因此,我设置了一个控制台应用程序,以各种方式解析一个日期/时间字符串10000次。底线:Parse() 10秒ParseExact()(转换为local) 20-45 ms ParseExact()(不转换为local) 10-15 ms…是的,Parse()的结果是以秒为单位的,而其他的结果是以毫秒为单位的。
#6
13
I'd just like to add a general note of caution.
我只是想补充一点提醒。
If all you are doing is getting the current time from the computer's internal clock to put a date/time on the display or a report, then all is well. But if you are saving the date/time information for later reference or are computing date/times, beware!
如果您所做的只是从计算机的内部时钟获取当前时间,以便在显示或报告中显示日期/时间,那么一切都很好。但是,如果您正在保存日期/时间信息以供以后参考或计算日期/时间,请注意!
Let's say you determine that a cruise ship arrived in Honolulu on 20 Dec 2007 at 15:00 UTC. And you want to know what local time that was.
1. There are probably at least three 'locals' involved. Local may mean Honolulu, or it may mean where your computer is located, or it may mean the location where your customer is located.
2. If you use the built-in functions to do the conversion, it will probably be wrong. This is because daylight savings time is (probably) currently in effect on your computer, but was NOT in effect in December. But Windows does not know this... all it has is one flag to determine if daylight savings time is currently in effect. And if it is currently in effect, then it will happily add an hour even to a date in December.
3. Daylight savings time is implemented differently (or not at all) in various political subdivisions. Don't think that just because your country changes on a specific date, that other countries will too.
假设你确定一艘邮轮于2007年12月20日下午3点到达檀香山。你想知道当地时间。1。可能至少有三个“本地人”参与其中。Local可能表示檀香山,也可能表示您的计算机位于何处,也可能表示您的客户位于何处。2。如果您使用内置函数进行转换,可能会出错。这是因为日光节约时间(很可能)目前在你的电脑上,但在12月没有生效。但Windows不知道这一点……它只有一个标志来确定夏令时目前是否有效。如果它现在有效,那么它会很高兴地在12月的某一天增加一个小时。在不同的政治细分中,夏令时的实施方式是不同的(或完全不同)。不要认为仅仅因为你的国家在某个特定的日期发生变化,其他国家也会改变。
#7
4
Don't forget if you already have a DateTime object and are not sure if it's UTC or Local, it's easy enough to use the methods on the object directly:
不要忘记,如果您已经有一个DateTime对象,并且不确定它是UTC还是Local,那么直接使用对象上的方法就足够简单了:
DateTime convertedDate = DateTime.Parse(date);
DateTime localDate = convertedDate.ToLocalTime();
How do we adjust for the extra hour?
我们如何适应额外的一小时?
Unless specified .net will use the local pc settings. I'd have a read of: http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx
除非指定。net将使用本地pc设置。我想读一下:http://msdn.microsoft.com/en- us/library/system.globaliz.daylighttime.aspx
By the looks the code might look something like:
从外观上看,代码可能是这样的:
DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges( year );
And as mentioned above double check what timezone setting your server is on. There are articles on the net for how to safely affect the changes in IIS.
如上所述,再次检查服务器所在的时区设置。网上有关于如何安全地影响IIS中的更改的文章。
#8
2
In answer to Dana's suggestion:
回答Dana的建议:
The code sample now looks like:
代码示例如下:
string date = "Web service date"..ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(convertedDate);
The original date was 20/08/08; the kind was UTC.
原日期为20/08/08;是UTC。
Both "convertedDate" and "dt" are the same:
“convertedDate”和“dt”都是相同的:
21/08/08 10:00:26; the kind was local
21/08/08 10:00:26;这种是当地
#9
1
I had the problem with it being in a data set being pushed across the wire (webservice to client) that it would automatically change because the DataColumn's DateType field was set to local. Make sure you check what the DateType is if your pushing DataSets across.
我遇到的问题是,在一个数据集中(从webservice推到client),它会自动更改,因为DataColumn的DateType字段被设置为local。如果您将数据集推过,请确保检查DateType是什么。
If you don't want it to change, set it to Unspecified
如果您不希望它更改,请将其设置为unknown
#10
1
I came across this question as I was having a problem with the UTC dates you get back through the twitter API (created_at field on a status); I need to convert them to DateTime. None of the answers/ code samples in the answers on this page were sufficient to stop me getting a "String was not recognized as a valid DateTime" error (but it's the closest I have got to finding the correct answer on SO)
我遇到了这个问题,因为我在UTC日期问题上遇到了一个问题,您通过twitter API(在状态上的created_at字段)返回;我需要将它们转换为DateTime。在这一页的答案中,没有一个答案/代码示例足以阻止我获得一个“不被认为是有效的DateTime”错误(但这是我最接近找到正确答案的方法)
Posting this link here in case this helps someone else - the answer I needed was found on this blog post: http://www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ - basically use DateTime.ParseExact with a format string instead of DateTime.Parse
如果这对其他人有帮助,请在这里发布这个链接——我需要的答案在这篇博文中找到:http://www.wduffy.co.uk/blog/par- date -when- aspnets-datetimeparase -does -work/——基本上使用DateTime。解析使用格式字符串而不是DateTime.Parse
#11
1
@TimeZoneInfo.ConvertTimeFromUtc(timeUtc, TimeZoneInfo.Local)
#1
337
For strings such as 2012-09-19 01:27:30.000
, DateTime.Parse
cannot tell what time zone the date and time are from.
对于像2012-09-19 01:27:30 000 DateTime这样的字符串。解析不能告诉日期和时间来自哪个时区。
DateTime
has a Kind property, which can have one of three time zone options:
DateTime有一个属性,它可以有三个时区选项之一:
- Unspecified
- 未指明的
- Local
- 当地的
- Utc
- Utc
NOTE If you are wishing to represent a date/time other than UTC or your local time zone, then you should use DateTimeOffset
.
注意,如果您希望表示一个日期/时间,而不是UTC或您的本地时区,那么您应该使用DateTimeOffset。
So for the code in your question:
所以对于你的问题的代码:
DateTime convertedDate = DateTime.Parse(dateStr);
var kind = convertedDate.Kind; // will equal DateTimeKind.Unspecified
You say you know what kind it is, so tell it.
你说你知道那是什么,所以说出来。
DateTime convertedDate = DateTime.SpecifyKind(
DateTime.Parse(dateStr),
DateTimeKind.Utc);
var kind = convertedDate.Kind; // will equal DateTimeKind.Utc
Now, once the system knows its in UTC time, you can just call ToLocalTime
:
现在,一旦系统知道它在UTC时间,你可以直接调用ToLocalTime:
DateTime dt = convertedDate.ToLocalTime();
This will give you the result you require.
这将给出您所需的结果。
#2
106
I'd look into using the System.TimeZoneInfo class if you are in .NET 3.5. See http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx. This should take into account the daylight savings changes correctly.
我会考虑使用这个系统。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);
#3
43
TimeZone.CurrentTimeZone.ToLocalTime(date);
#4
15
DateTime
objects have the Kind
of Unspecified
by default, which for the purposes of ToLocalTime
is assumed to be UTC
.
在默认情况下,DateTime对象的类型是未指定的,因此,对于ToLocalTime的目的,假设是UTC。
To get the local time of an Unspecified
DateTime
object, you therefore just need to do this:
要获取未指定的DateTime对象的本地时间,您只需要这样做:
convertedDate.ToLocalTime();
The step of changing the Kind
of the DateTime
from Unspecified
to UTC
is unnecessary. Unspecified
is assumed to be UTC
for the purposes of ToLocalTime
: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx
将日期时间类型从未指定改为UTC的步骤是不必要的。假定为UTC,用于ToLocalTime: http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx
#5
15
I know this is an older question, but I ran into a similar situation, and I wanted to share what I had found for future searchers, possibly including myself :).
我知道这是一个老问题,但我遇到了类似的情况,我想把我的发现告诉未来的搜索者,可能包括我自己。
DateTime.Parse()
can be tricky -- see here for example.
解析()可能很棘手,比如这里。
If the DateTime
is coming from a Web service or some other source with a known format, you might want to consider something like
如果DateTime来自Web服务或其他格式已知的源,您可以考虑使用类似的方法
DateTime.ParseExact(dateString,
"MM/dd/yyyy HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)
or, even better,
或者,更好的是,
DateTime.TryParseExact(...)
The AssumeUniversal
flag tells the parser that the date/time is already UTC; the combination of AssumeUniversal
and AdjustToUniversal
tells it not to convert the result to "local" time, which it will try to do by default. (I personally try to deal exclusively with UTC in the business / application / service layer(s) anyway. But bypassing the conversion to local time also speeds things up -- by 50% or more in my tests, see below.)
假定通用标志告诉解析器日期/时间已经是UTC;假定通用和可调遍历的组合告诉它不要将结果转换为“本地”时间,默认情况下它将尝试这样做。(无论如何,我个人尝试在业务/应用程序/服务层专门处理UTC。但绕过转换到本地时间也会加快速度——在我的测试中,速度会提高50%或更多,见下文。
Here's what we were doing before:
下面是我们之前所做的:
DateTime.Parse(dateString, new CultureInfo("en-US"))
We had profiled the app and found that the DateTime.Parse represented a significant percentage of CPU usage. (Incidentally, the CultureInfo
constructor was not a significant contributor to CPU usage.)
我们对应用进行了剖析,发现了DateTime。解析表示CPU使用率的很大百分比。(顺便说一句,CultureInfo构造函数并不是CPU使用的重要贡献者。)
So I set up a console app to parse a date/time string 10000 times in a variety of ways. Bottom line:Parse()
10 secParseExact()
(converting to local) 20-45 msParseExact()
(not converting to local) 10-15 ms
... and yes, the results for Parse()
are in seconds, whereas the others are in milliseconds.
因此,我设置了一个控制台应用程序,以各种方式解析一个日期/时间字符串10000次。底线:Parse() 10秒ParseExact()(转换为local) 20-45 ms ParseExact()(不转换为local) 10-15 ms…是的,Parse()的结果是以秒为单位的,而其他的结果是以毫秒为单位的。
#6
13
I'd just like to add a general note of caution.
我只是想补充一点提醒。
If all you are doing is getting the current time from the computer's internal clock to put a date/time on the display or a report, then all is well. But if you are saving the date/time information for later reference or are computing date/times, beware!
如果您所做的只是从计算机的内部时钟获取当前时间,以便在显示或报告中显示日期/时间,那么一切都很好。但是,如果您正在保存日期/时间信息以供以后参考或计算日期/时间,请注意!
Let's say you determine that a cruise ship arrived in Honolulu on 20 Dec 2007 at 15:00 UTC. And you want to know what local time that was.
1. There are probably at least three 'locals' involved. Local may mean Honolulu, or it may mean where your computer is located, or it may mean the location where your customer is located.
2. If you use the built-in functions to do the conversion, it will probably be wrong. This is because daylight savings time is (probably) currently in effect on your computer, but was NOT in effect in December. But Windows does not know this... all it has is one flag to determine if daylight savings time is currently in effect. And if it is currently in effect, then it will happily add an hour even to a date in December.
3. Daylight savings time is implemented differently (or not at all) in various political subdivisions. Don't think that just because your country changes on a specific date, that other countries will too.
假设你确定一艘邮轮于2007年12月20日下午3点到达檀香山。你想知道当地时间。1。可能至少有三个“本地人”参与其中。Local可能表示檀香山,也可能表示您的计算机位于何处,也可能表示您的客户位于何处。2。如果您使用内置函数进行转换,可能会出错。这是因为日光节约时间(很可能)目前在你的电脑上,但在12月没有生效。但Windows不知道这一点……它只有一个标志来确定夏令时目前是否有效。如果它现在有效,那么它会很高兴地在12月的某一天增加一个小时。在不同的政治细分中,夏令时的实施方式是不同的(或完全不同)。不要认为仅仅因为你的国家在某个特定的日期发生变化,其他国家也会改变。
#7
4
Don't forget if you already have a DateTime object and are not sure if it's UTC or Local, it's easy enough to use the methods on the object directly:
不要忘记,如果您已经有一个DateTime对象,并且不确定它是UTC还是Local,那么直接使用对象上的方法就足够简单了:
DateTime convertedDate = DateTime.Parse(date);
DateTime localDate = convertedDate.ToLocalTime();
How do we adjust for the extra hour?
我们如何适应额外的一小时?
Unless specified .net will use the local pc settings. I'd have a read of: http://msdn.microsoft.com/en-us/library/system.globalization.daylighttime.aspx
除非指定。net将使用本地pc设置。我想读一下:http://msdn.microsoft.com/en- us/library/system.globaliz.daylighttime.aspx
By the looks the code might look something like:
从外观上看,代码可能是这样的:
DaylightTime daylight = TimeZone.CurrentTimeZone.GetDaylightChanges( year );
And as mentioned above double check what timezone setting your server is on. There are articles on the net for how to safely affect the changes in IIS.
如上所述,再次检查服务器所在的时区设置。网上有关于如何安全地影响IIS中的更改的文章。
#8
2
In answer to Dana's suggestion:
回答Dana的建议:
The code sample now looks like:
代码示例如下:
string date = "Web service date"..ToString("R", ci);
DateTime convertedDate = DateTime.Parse(date);
DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(convertedDate);
The original date was 20/08/08; the kind was UTC.
原日期为20/08/08;是UTC。
Both "convertedDate" and "dt" are the same:
“convertedDate”和“dt”都是相同的:
21/08/08 10:00:26; the kind was local
21/08/08 10:00:26;这种是当地
#9
1
I had the problem with it being in a data set being pushed across the wire (webservice to client) that it would automatically change because the DataColumn's DateType field was set to local. Make sure you check what the DateType is if your pushing DataSets across.
我遇到的问题是,在一个数据集中(从webservice推到client),它会自动更改,因为DataColumn的DateType字段被设置为local。如果您将数据集推过,请确保检查DateType是什么。
If you don't want it to change, set it to Unspecified
如果您不希望它更改,请将其设置为unknown
#10
1
I came across this question as I was having a problem with the UTC dates you get back through the twitter API (created_at field on a status); I need to convert them to DateTime. None of the answers/ code samples in the answers on this page were sufficient to stop me getting a "String was not recognized as a valid DateTime" error (but it's the closest I have got to finding the correct answer on SO)
我遇到了这个问题,因为我在UTC日期问题上遇到了一个问题,您通过twitter API(在状态上的created_at字段)返回;我需要将它们转换为DateTime。在这一页的答案中,没有一个答案/代码示例足以阻止我获得一个“不被认为是有效的DateTime”错误(但这是我最接近找到正确答案的方法)
Posting this link here in case this helps someone else - the answer I needed was found on this blog post: http://www.wduffy.co.uk/blog/parsing-dates-when-aspnets-datetimeparse-doesnt-work/ - basically use DateTime.ParseExact with a format string instead of DateTime.Parse
如果这对其他人有帮助,请在这里发布这个链接——我需要的答案在这篇博文中找到:http://www.wduffy.co.uk/blog/par- date -when- aspnets-datetimeparase -does -work/——基本上使用DateTime。解析使用格式字符串而不是DateTime.Parse
#11
1
@TimeZoneInfo.ConvertTimeFromUtc(timeUtc, TimeZoneInfo.Local)