Solving an interesting TimeZone Problem

Let’s say you have a customer base spreaded across several time zones i.e. from Hawaii to Alaska, all the way across mainland US and even some remote parts of Europe. You want a service to deliver a particular message at certain time via email, in that time zone. How would you do that?


 


This problem recently came up and was discussed with some colleagues. I found it to be pretty challenging; even though it sounds simple, it gets a bit tricky if you’d want to find out things like


 



  • At what time in your local timezone the message should be sent out so it will reach the target timezone at the given local time (at target timezone say 8:00 AM)

  • Relative to your current timezone, when did the target time for message delivery occurred in the destination timezone locale?

etc etc.


 


Therefore, I started experimenting with the following data


 



















96811    P        Honolulu D        Honolulu 15003    HI       15       3320     808      Hawaii   -10


99850    P        Juneau   D        Juneau   02110    AK       02       0000     907      Alaska   -9


97840    S        Oxbow    D        Baker    41001    OR       41       0000     541      Pacific  -8


59821    S        Arlee    D        Lake     30047    MT       30       0000     406      Mountain -7


78028    S        Kerrville        DKerr    48265    TX       48       0000     830      Central  -6


48852    P        McBrides D        Montcalm 26117    MI       26       0000     989      Eastern  -5


00627    S        VISTA Verde      NCamuy   72027    PR       72       0470     787      Atlantic -4


 


A simple no brainer equation for time calculation in a particular locale is


 


LocalTime = GMT + Offset


 


where offset is the value by which a local time differs from UTC or coordinated universal time.


 


Hence, it can be said that


PacificTime = GMT + (-8)


HawaiianTime = GMT + (-10)


 


Equating both equations we get


 


PacificTime + 8 = HawaiianTime + 10


And hence


 


PacificTime = HawaiinTime + 10 – 8


 


Considering Pacific time as local timezone and Hawaiian timezone as the target one, this can be generalized as


 


LocalTimeZone = TargetTimeZone + TargetGMTOffset – LocalGMTOffset


 


I did a C# implemention of this idea which, AFAIK, provides pretty accurate results.  Like for the following PR zip 00627.


 


Local Time is 12/31/2005 12:46:31 AM Which is UTC-8
Universal Time (GMT) is 12/31/2005 8:46:31 AM
Target time is 12/31/2005 8:00:00 AM
Time in zipcode 00627 is 12/31/2005 4:46:31 AM which is UTC-4
Required Time 12/31/2005 8:00:00 AM in zipcode 00627 is in 3.00 Hrs 13.00 Mins.
Time difference between Local and Remote Zone is -4
According to local time, alert has to occur at 12/31/2005 4:00:00 AM to be seenin target locale at 12/31/2005 8:00:00 AM


 


And hence comes the following code:



class TimeZoneCalibrator
{
public static string[] strzipcode = {"96811", "99850", "97840", "59821", "78028", "48852", "00627", "IG119XW"};
public static int[] offset = {-10, -9, -8, -7, -6, -5, -4, 0};


/// <summary>
///
The driver - traverse through different time zones including GMT
/// </summary>


[STAThread]
 static void Main(string[] args)


{
DateTime RequiredRemoteTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 8, 0, 0, 0);
for (int cnt=0; cnt<strzipcode.Length; cnt++)
CalibrateTime (RequiredRemoteTime, strzipcode[cnt]);
Console.ReadLine ();
}



//Returns the local time in that time zone
public static DateTime CalibrateTime (DateTime RequiredRemoteTime, string zipcode)
{
int strIndex=0;
int strNumber = 0;
for (strNumber = 0; strNumber < strzipcode.Length; strNumber++)
{
strIndex = strzipcode[strNumber].IndexOf(zipcode);
if (strIndex >= 0)
break;
}
DateTime localDateTime = DateTime.Now;
System.DateTime univDateTime = localDateTime.ToUniversalTime();
double GMTDifferenceTimeSpan = localDateTime.Subtract(univDateTime).TotalHours;
//Find out the remote time
DateTime RemoteDateTime = univDateTime.AddHours (offset[strNumber]);
TimeSpan TimeDifference = RequiredRemoteTime.Subtract (RemoteDateTime);
//Localtime relative
DateTime LocalTimeAnticipated = RequiredRemoteTime;
int LocalRemoteTimeDiff = (int)(TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalHours - offset[strNumber]);
LocalTimeAnticipated = LocalTimeAnticipated.AddHours (LocalRemoteTimeDiff);
Console.WriteLine ("Local Time is " + localDateTime.ToString () + " Which is UTC" + TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).TotalHours);
Console.WriteLine ("Universal Time (GMT) is " + univDateTime.ToString ());
Console.WriteLine ("Target time is " + RequiredRemoteTime.ToString ());
Console.WriteLine ("Time in zipcode " + zipcode + " is " + RemoteDateTime.ToString ()+ " which is UTC" + offset[strNumber]);
//Just for fancy printing.
if (TimeDifference.TotalHours < 0)
Console.WriteLine ("Required Time " + RequiredRemoteTime + " in zipcode " + zipcode + " was "
+ Math.Abs (TimeDifference.Hours).ToString ("N") +" Hrs " + Math.Abs (TimeDifference.Minutes).ToString ("N")+" Mins ago.");
else
Console.WriteLine ("Required Time " + RequiredRemoteTime + " in zipcode " + zipcode + " is in "
+ Math.Abs (TimeDifference.Hours).ToString ("N") +" Hrs " + Math.Abs (TimeDifference.Minutes).ToString ("N") +" Mins.");
Console.WriteLine ("Time difference between Local and Remote Zone is " + LocalRemoteTimeDiff);
//According to local time, it would occur at
Console.WriteLine ("According to local time, alert has to occur at " + LocalTimeAnticipated.ToString () +" to be seen in target locale at " + RequiredRemoteTime.ToString ());
Console.WriteLine ("--------------------------------------------------------------");
return LocalTimeAnticipated;
}





DateTime Structure

Share