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
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
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-8Universal Time (GMT) is 12/31/2005 8:46:31 AMTarget time is 12/31/2005 8:00:00 AMTime in zipcode 00627 is 12/31/2005 4:46:31 AM which is UTC-4Required 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 -4According 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 zonepublic 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 timeDateTime RemoteDateTime = univDateTime.AddHours (offset[strNumber]);TimeSpan TimeDifference = RequiredRemoteTime.Subtract (RemoteDateTime);//Localtime relativeDateTime 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.");elseConsole.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 atConsole.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;}
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 ();}
DateTime Structure