DateTime time zone conversion in .Net / C#

Converting time zone sometimes can be tricky. If we understand a few basic facts around time zone and knows the how to use it, it turns out relatively easy.

Basics of Time Zone

There are 3 concepts to know clearly about time zones.

  1. UTC (Coordinated Universal Time) : Standard time zone. When it comes to the global standard time in programming, UTC is the one we can rely on.
  2. GMT (Greenwich Mean Time) : GMT was the standard time, before the UTC is introduced. It is easy to understand GMT as London standard time zone.
  3. Local Time: Time zone in current area, where the computer is running.

What is the difference between UTC and GMT.

GMT changes time offset when daylight saving time (DST) applied. UTC does not.

How to change time zone in .Net / C#

1. Convert between UTC and Local

It’s easy to convert local time to UTC. Use ToUniversalTime() method. In .Net, ToUniversalTime() method automatically considers daylight saving when converting.

The snippet below shows that ToUniversalTime() converts Sydney local time to UTC automatically considering whether it is daylight saving time or not.

// convert local to utc
DateTime dateTimeLocal = DateTime.Now;
bool isDaylightSavingTime = dateTimeLocal.IsDaylightSavingTime(); 
if (isDaylightSavingTime)
 Assert.IsTrue(dateTimeLocal.AddHours(-11) == dateTimeLocal.ToUniversalTime());
else
 Assert.IsTrue(dateTimeLocal.AddHours(-10) == dateTimeLocal.ToUniversalTime());

To convert UTC time to local, we can use ToLocalTime() method.

One thing to know about ToUniversalTime() and ToLocalTime() is that this method has 3 different behaviour depending on the specification of the input time.

For example, when using ToLocalTime(), if the input time is UTC, it is to be converted to local time. If the input time is local time, it will be remained unchanged. If the input time is unspecified, which means the time is not UTC and not local either. ToLocalTime() assumes that input time as UTC. The same applies to ToUniversalTime().

The sample code below shows how ToLocalTime works when the input time is unspecified and local time.

// convert undefined to local. ToLocalTime assume the unspecified time as UTC
DateTime dateTimeUnspecified = DateTime.Parse(DateTime.Today.ToString());
DateTime local = dateTimeUnspecified.ToLocalTime();
Assert.IsFalse(dateTimeUnspecified == local);

// convert undefined to local. ToLocalTime doesn't change to local time
DateTime localTime = DateTime.Today;
DateTime convertedLocal = localTime.ToLocalTime();
Assert.IsTrue(localTime == convertedLocal);

 

2. Convert between 2 different time zones

To convert a time zone to another time zone, we can use TimeZoneInfo.ConvertTime(dateTime, sourceTimeZoneInfo, destinationTimeZoneInfo).

The TimeZoneInfo can be retrieved by using TimeZoneInfo.FindSystemTimeZoneById(“AUS Eastern Standard Time”).

A full list of the time zone ids can be found at here.

The use of these converting methods is straightforward. The daylight saving is automatically considered by the method, which is quite handy.

Converting local to UTC by using ConvertTime method returns the same value as using the ToUniversalTime method. The sample code below shows this.

// convert AEST to UTC
// When AEST is not DST
DateTime dtAEST = DateTime.Parse(new DateTime(2014, 4, 30, 0, 0, 0).ToString());
DateTime dtAESTtoUTC = TimeHelper.ConvertToTimezone(dtAEST, TimeHelper.AEST, TimeHelper.UTC);
Assert.IsFalse(dtAEST.IsDaylightSavingTime());
Assert.IsTrue(dtAEST == dtAESTtoUTC.AddHours(10));

// use ToUniversalTime
// When AEST is not DST and GMT is not DST, the difference between AEST and GMT is 10 hours
dtAESTtoUTC = dtAEST.ToUniversalTime();
Assert.IsTrue(dtAEST == dtAESTtoUTC.AddHours(10));

As mentioned earlier, GMT is not the same as UTC. Normally AEST is +10 hours from UTC. AEST in daylight saving season, the time offset is +11 hours. However, The time difference between GMT and AEST when GMT(London) time zone is DST and AEST is not daylight DST is 9 hours.

The sample code below is a continued test from the right above code.

// convert to GMT (Daylight saving time)
// When AEST is not DST and GMT is DST, the difference between AEST and GMT is 9 hours
DateTime dtAESTtoGMT = TimeHelper.ConvertToTimezone(dtAEST, TimeHelper.AEST, TimeHelper.GMT);
Assert.IsFalse(dtAESTtoGMT.IsDaylightSavingTime());
Assert.IsTrue(TimeHelper.GMT.IsDaylightSavingTime(dtAESTtoGMT));
Assert.IsTrue(dtAEST == dtAESTtoGMT.AddHours(9));

Hopefully, there will be no more confusion on time zone conversion.

 

 

4 comments

Leave a Reply to Joe Cancel reply

Your email address will not be published.