Manage TimeZone for Applications on Windows Azure


I am writing this blog as a response to the number of issues I have seen where the PAAS VM might seem to have recycled abruptly. On a quite a number of occurrences I found that users manually doing an RDP to the VM instances and changing the machine time. Based on some blogs users are leveraging“TZUTIL” from the command prompt to accomplish this. While the changes will not persist beyond a reincarnation of the VM some enterprising users have conjured up script that can be used as part of the start-up task and hence mitigate the re-creation of the VM.

But I would strongly advice against it. The Fabric Controller maintains operating system time synchronization for the system when roles are first booted. If you utilize administrative access startup scripts to change the localization settings (including local server time), but it is not recommended you do so. Doing so will introduce instability and the fabric controller may determine your role is out of sync. You will likely end up cycling your roles as fabric attempts to bring them to goal state in such a case. A better strategy is to write your applications to be aware that they actually run with UTC and default US CultureInfo settings.

WINDOWS AZURE ROLES

------------------------------------------------------

While it may be very tempting to change the server time on the Azure Virtual Machines using a startup task, it is not recommended, you should rather use methods like TimeZoneInfo.ConvertTimeFromUTCTime in your code.

This is a good reference article (Coding Best Practices Using DateTime in the .NET Framework).

All the machines in PAAS (Web Role or Worker Role) should always be in UTC. Changing that will lead to unpredictable situations since the internal heartbeat, ping from load balancer all depend on time. For application requirement please use the application APIs to convert the time in the code. For example below is how a time zone conversion should be done.  

In case you are using .Net applications you can use the following after fetching the myUtcDateTime from the System. Use the web.config file to manage the number of hours you want to go forward or backward, this way you can set it to zero(GMT),
positive (GMT+ like EMEA and Asia) or negative values (North and South America) as per the applications/end user required time zones.  

Set the double hour using the System.Configuration.ConfigurationManager AppSetting Collection. This will let the application be configurable for different time offsets.

Then use the following code

  DateTime myUtcDateTime = DateTime.Now;

  DateTime myLocalDate = myUtcDateTime.AddHours(hour);

  In case the application will only ever need one of the standard timezone(accuracy of 30 mins is sufficient) then .Net even caters to do that. This suits lazy people like me and is actually the main usecase. 

DateTime myUtcDateTime = DateTime.Now;
DateTime myConvertedDateTime = TimeZoneInfo.ConvertTime(
 myUtcDateTime,TimeZoneInfo.FindSystemTimeZoneById("Indian Standard Time"))

 

 SQL Azure

 --------------------

Regardless of the datacenter location chosen, your SQL Azure server is set to the UTC timezone. The current version of SQL Azure does not support changing the timezone. So the same programmatic technique should be used in case there is a WebRole/WorkerRole which will serve the data to the end user/applications.

In case there is none then the following blog depicts the technique on how to convert the time in the SQL query itself.  http://wely-lau.net/2011/07/10/managing-timezone-in-sql-azure-2/

 Devices

 --------------------

 In case you are developing mobile application then the webroles or worker roles (WFC/OData service) should always return UTC time. The client application should convert the time based on the user location.

 WP8           : http://stackoverflow.com/questions/14230393/convert-datetime-to-another-timezone

 iPhone®   : http://stackoverflow.com/questions/11504843/get-current-iphone-device-timezone-date-and-time-from-utc-5-timezone-date-and-ti  

 Android™   : http://stackoverflow.com/questions/6088778/converting-utc-dates-to-other-timezones

 

Further reads

----------------------------

http://msdn.microsoft.com/en-us/library/bb382770.aspx

http://msdn.microsoft.com/en-us/library/system.timezoneinfo.findsystemtimezonebyid.aspx

http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx

 

Disclaimer

-----------------------

ANY SAMPLE CODE AND ANY RELATED INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. THESE ARE MY PERSONAL VIEWS AND MICROSOFT CORPORATION MAKES NO WARRANTY, IMPLIED OR OTHERWISE, ABOUT THE RELIABILITY OR PERFORMANCE OF THESE ARTICLES AND CODE SNIPPETS.

"iPhone® is a trademark of Apple Inc."

"Android™ is a trademark of Google Inc."

 

 

Comments (4)

  1. Joel says:

    UTC time does not work for reporting when using grouping functions based on date. Your EOF results will vary from reality.

  2. Mick says:

    In the first part of your article – you're against people using TZUtil to modify the time.

    No one is actually changing the time – we are changing the *timezone*.

    Big difference.

    Yes apps should be datetime aware, but while in a blog it sounds perfect… in the real world many apps just 'come as they are' and within 6 months you'll have many many applications cloud based, remote apps etc, utilities, services, stubs to services, proxies etc.

    Taking the path that they all should be GMT/UTC aware = good luck.

    Not practical.

  3. mark says:

    > Changing that will lead to unpredictable situations since the internal heartbeat, ping from load balancer all depend on time.

    That’s funny. You’re recommending user apps to use UTC and Azure heartbeats use local time?! I doubt that.

  4. for Azure SQL now you can use the AT TIMEZONE clause when using the CONVERT function …. this will obviously have better performance then the offered solution.

Skip to main content