2

I use a legacy DMS application, who stores dates using GMT 0 (Greenwich) as default time zone and applies 1 hour spread to it. I have to display with GridView these records and I need to apply a kind of transformation according to the relative location where my system runs (as example London, Bahamas).

Looking on how the legacy system works with dates, I designed the following algorithm to display the dates properly (my code is based on asp.net / C#):

//Example for Bahamas, GMT: -5 Hours as offset, I should add 4 hours to the DB date
//Example for London,  GMT:  0 Hour  as offset, I should add 1 hour  to the DB date
DateTime dateToDisplay;
int spreadHours  = 0;

TimeZone cur = TimeZone.CurrentTimeZone;
DaylightTime daylight = cur.GetDaylightChanges(dateFromDb.Year);
DateTime start = daylight.Start;
DateTime end = daylight.End;

if (dateFromDb.CompareTo(start) <= 0 || dateFromDb.CompareTo(end) >= 0)
{
   spreadHours  = -1 - (cur.GetUtcOffset(dateFromDb).Hours);                
}
else
{
   spreadHours  = - (cur.GetUtcOffset(dateFromDb).Hours);                
}

dateToDisplay = dateFromDb.AddHours(spreadHours);

However I am not sure if with this process I can cover all the cases or whether there could be a better solution to achieve the same result.

Can anyone confirm my idea or suggest a better path?

Francesco
  • 9,947
  • 7
  • 67
  • 110

3 Answers3

1

In general from .NET 3.5 you could/should use the TimeZoneInfo class,

in fact to convert from an UtcDateTime to a local time all you need to do is this:

// here static text but you can initialize the TimeZoneInfo with any Id, check MSDN for this:
// http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx

string nzTimeZoneKey = "New Zealand Standard Time";

TimeZoneInfo nzTimeZone = TimeZoneInfo.FindSystemTimeZoneById(nzTimeZoneKey);
DateTime nzDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, nzTimeZone);

you can check this other question and answers here in SO:

Convert UTC/GMT time to local time

Community
  • 1
  • 1
Davide Piras
  • 43,984
  • 10
  • 98
  • 147
  • +1 - It works fine with: date = TimeZoneInfo.ConvertTimeFromUtc(dateFromDb, TimeZoneInfo.Local); I will use this method in a Linq query select: once for a Date field and once for the Time, referring to the same date, that I have to present as individual columns. This should work as well, since the "correct" part of the date, is taken once for the date and once for the time. – Francesco Sep 12 '11 at 12:47
  • Yes it will, no worry about that? all done for you by that class ;-) – Davide Piras Sep 13 '11 at 06:14
  • Great! Then it is all what I need. Thanks again Davide. – Francesco Sep 13 '11 at 06:17
1

Dealing with timezones is not as clear-cut as you would think.

Read the following article by Troy Hunt:

http://www.troyhunt.com/2011/08/overcoming-sql-08s-globally-insensitive.html

He's goes into great detail about dealing with time zones in .NET, it's a good writeup that quickly tells you what the pitfalls (and possible solutions) are.

Christophe Geers
  • 8,564
  • 3
  • 37
  • 53
0

A quick look at the MSDN suggests you can do something like this

DateTime dt = new DateTime(dateFromDb.Ticks, DateTimeKind.Utc);
DateTime dtLocal = dt.ToLocalTime();

Then you could display dtLocal in any format you want. It would be adjusted to local time with correct daylight saving settings

Check out MSDN DateTime.ToLocalTime for more info

Edit: I'm assuming here that dateFromDb is an instance of DateTime Class.

danishgoel
  • 3,650
  • 1
  • 18
  • 30
  • This would not work on ASP.NET because the local time of the server is NOT the same of the user connecting remotely with the browser. Would probably work on a Windows Application. – Davide Piras Sep 12 '11 at 12:23
  • As OP used `TimeZone.CurrentTimeZone`, I assumed he has a windows application. Because Both `DateTime.ToLocalTime()` and `TimeZone.CurrentTimeZone` would not work according to remote user's timezone settings in an ASP.net application – danishgoel Sep 12 '11 at 12:51
  • oops! didn't notice that. My mistake. – danishgoel Sep 12 '11 at 15:03