What is the difference between DateTime.ToUniversalTime and TimeZoneInfo.ConvertTimeToUtc

I'm just starting to think right about deploying a webapp that will have to do things for users at the beginning of their day, say, 6 a.m. Also at the end of their days.

Everywhere I read about people who talked a lot to use .ToUniversalTime to save time in UTC, but when I tried it (as I suspected) it didn’t work, and it just moved the time to hour (I'm in the UK, so I thought that this is due to some shift from GMT to UTC, although for me this does not make sense, since the daylight should be turned off at the moment).

I have a field in db that stores the timezone of users, so when I started using ConvertTimeToUtc and fromUtc, it started to do what I expected from it. Although again I’m not sure that I need to build my own logic in order to make daylight saving, or whether he should do it for me.

Basically, I wonder why everyone was talking about .ToUniversalTime, because it really didn’t help me, and I couldn’t understand how he could know how much it costs to compensate for the time to move it to UTC, while the second method made sense.

Can someone explain how each method can be useful?

+4
source share
3 answers

If you run the code on a computer in a different time zone, will your calculations still work? It is for this reason that people store and process all DateTimes as UTC - this eliminates any ambiguity. You will not need to store the user's time zone. Any machine, anywhere, can pull a date from a database and easily convert it to local time and local time.

If you save time in any other time zone, you need to pull it out, calculate the offset to the required time zone, including factoring in the summer and international timing considerations. In your case, you also store additional unnecessary information.

+2
source

Actually the difference between the two.

In .NET 3.5 and below , Datetime.ToUniversalTime implemented as:

 public DateTime ToUniversalTime() { return TimeZone.CurrentTimeZone.ToUniversalTime(this); } 

Since he used the TimeZone class, he suffered the same problems that were mentioned in MSDN docs :

The TimeZone class supports only one rule of daylight saving time adjustment for the local time zone. As a result, the TimeZone class can accurately report TimeZone time information or convert between GMT and local time only for the period in which the last adjustment rule applies. In contrast, the TimeZoneInfo class supports several configuration rules, which allows you to work with historical time zone data.

In .NET 4.0 and later , Datetime.ToUniversalTime is implemented as:

 public DateTime ToUniversalTime() { return TimeZoneInfo.ConvertTimeToUtc(this, TimeZoneInfoOptions.NoThrowOnInvalidTime); } 

This fixes the lack of support for historical adjustment rules, but because of the NoThrowOnInvalidTime flag NoThrowOnInvalidTime this is not the same as calling TimeZoneInfo.ConvertimeToUtc .

The method that it calls is the internal ConvertTimeToUtc overload, which accepts the TimeZoneInfoOptions flag. The public version of the method uses TimeZoneInfoOptions.None , while in this case it uses TimeZoneInfoOptions.NoThrowOnInvalidTime .

The difference can be illustrated as follows. If the time zone is set to US Pacific Time:

 DateTime dt = new DateTime(2015, 3, 8, 2, 0, 0, DateTimeKind.Local); DateTime utc = dt.ToUniversalTime(); Console.WriteLine(utc); // "3/8/2015 10:00:00 AM" 

Vs:

 DateTime dt = new DateTime(2015, 3, 8, 2, 0, 0, DateTimeKind.Local); DateTime utc = TimeZoneInfo.ConvertTimeToUtc(dt); // throws exception! Console.WriteLine(utc); 

Since on this date in this time zone, the time is scanned from 1:59:59 to 3:00:00, the delivery time of 2:00:00 is not valid. The right thing is to make an exception (as in the second case). However, since the existing Datetime.ToUniversalTime contract from earlier versions of the framework did not allow this, the structure decides to return the value instead of the metalization.

The selected value is calculated using the standard time offset, as if the DST transition was not performed.

+6
source

Edit: I was wrong. See Matt Johnson's answer for an explanation of the subtle differences between the DateTime.ToUniversalTime and TimeZoneInfo.ConvertTimeToUtc implementations.

For everyone who has a specific question formulated in the title: What is the difference between DateTime.ToUniversalTime and TimeZoneInfo.ConvertTimeToUtc ?

Answer: There is no difference .

Using JustDecompile to test the implementation of DateTime.ToUniversalTime in .NET 4.5, we see that it uses TimeZoneInfo.ConvertTimeToUtc directly:

  public DateTime ToUniversalTime() { return TimeZoneInfo.ConvertTimeToUtc(this, TimeZoneInfoOptions.NoThrowOnInvalidTime); } 
+2
source

All Articles