Parsing ISO8601 date/time with DateTime struct

怎甘沉沦 提交于 2019-12-04 16:59:30

Britain uses summer time (advancing their clocks by one hour) in the summer (27 August, your "now" in the examples), but not in the winter (5 January, from your parsing of "1987-01-05T08:45:30.500+0100").

Actually, in the winter Britain uses UTC. Your machine seems to have a British TimeZoneInfo. You can check with TimeZoneInfo.Local.DisplayName (since .NET 3.5) or TimeZone.CurrentTimeZone.StandardName (old).

You can check with dt.IsDaylightSavingTime().

Addition:

My answer is about .NET only (but maybe the same applies to JavaScript?). The examples you provide work entirely as expected. A date and time in January 1987 will be converted into your local zone, which is supposedly British, and in January 1987 the United Kingdom was at +0000 since it was winter. The time string you gave was stamped with +0100 (as if it was from Germany or some other country one hour to the east of Britain), and this was acknowledged when the string was parsed. A date in the summer of 1987 would correctly have converted differently because in the summer of 1987 Britain (and all of the EEC) observed summer time (daylight saving time).

To sum up: The offset indicator or zone specifier +0100 is considered when interpreting the time. This is converted into British time on your computer. If you want conversion to UTC instead of conversion to the local time of your machine, use the overload that takes a DateTimeStyles enum and include the flag DateTimeStyles.AdjustToUniversal.

If you want a value that better represents time and absolute zone, consider using the struct DateTimeOffset instead of DateTime. You can also consider NODA time instead of the .NET types.

ToLocalTime and ToUniversalTime do take into account Daylight saving time and do a very good job at it. At least in .Net, the Javascript Date object has flaws and I would recommend using moment.js and moment-timezone.js for conversions in js.

Here is my unit test and the results:

        var now = DateTime.Now;
        Console.WriteLine(now.ToLocalTime());
        Console.WriteLine(now.ToUniversalTime());

        //Test 1 TimeZone UTC+1 London, etc..
        //current day 20th July = BST

        /*  07/20/2015 01:06:43
            07/20/2015 00:06:43*/

        //set day to 20th Januray UK winter time

        /*  01/20/2015 01:07:55
            01/20/2015 01:07:55*/

For you to get the results described above in .Net you would need to a) set the time zone to UTC+2 b) run into a glitch in the ToLocalTime() which has since be fixed, MSDN mentions flaws on XP when converting dates.

Finally DateTime.Now returns the local time so using DateTime.Now.ToLocalTime() is a bit redundant and you may well get unexpected results.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!