0

On my dev server I save a value called "ScheduledDateUtc" date to sqlserver e.g. 24-11-14 09:00:00. I also save a value called "UtcOffset" and calculate the "ScheduledDateLocal" like so:

var ScheduledDateLocal = ScheduledDateUtc.AddHours(UtcOffset); //a negative offset would be deducted and a positive offset would be added

On my dev server this works fine and its calculates the correct ScheduledDateLocal for alle timezones/UtcOffset's. However, when I deploy to a Azure server in a different timezone this calculation is a few hours off.

Can anyone explain why? I'm guessing there is some kind of setting or system specific conversion param? Thanks!

Corstiaan
  • 1,114
  • 15
  • 34
  • Do you know what timezone your Azure server is located in? – user990423 Jun 16 '15 at 19:06
  • Im in UTC+1 and the calculation is one hour too much so Im guessing UTC0 – Corstiaan Jun 16 '15 at 19:08
  • 1
    My guess would be that you're initialising ScheduledDateUtc as a Utc datetime However, I'd expect it to be incorrect n your machine not on Azure which I'd assume is on Utc. I think we need to see an example input, output on your machine and the output on Azure. – Stephen Kennedy Jun 16 '15 at 19:38
  • 1
    Stephen is likely correct, but also - if these are truly *scheduled* values in the future, then storing as UTC is incorrect to begin with. Read [here](http://stackoverflow.com/a/19627330/634824) and [here](http://stackoverflow.com/a/19170823/634824). – Matt Johnson-Pint Jun 16 '15 at 21:20

1 Answers1

1

Is it possible that the incorrect result is actually on your machine and not Azure, and is because you are initialising ScheduledDateUtc as local time and not UTC?

Consider these two lines of code:

new DateTime(2015, 6, 1, 1, 1, 1).AddHours(5).ToUniversalTime().Dump();

new DateTime(2015, 6, 1, 1, 1, 1, DateTimeKind.Utc).AddHours(5).ToUniversalTime().Dump();

Here, we are in summer time which is UTC+1. The output of the above is:

01/06/2015 05:01:01

01/06/2015 06:01:01

They're 1 hour out as I 'forgot' to specify that the input is UTC in the constructor in the first line of code.

If you don't have access to the constructor because ScheduledDateUtc is initialised by an ORM, you can use SpecifyKind:

ScheduledDateUtc = DateTime.SpecifyKind(ScheduledDateUtc, DateTimeKind.Utc)

Its unfortunate that you're storing an offset not a timezone as you may have issues with daylight savings time. If you were storing a Windows timezone name, you could use TimeZoneInfo.ConvertTimeFromUtc (no need to specify Kind here as this assumes UTC) as per this example from MSDN:

TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
ScheduledDateLocal = TimeZoneInfo.ConvertTimeFromUtc(ScheduledDateUtc, cstZone);

You could instead instantiate a "custom" timezone using your offset and still use the above function.

I faced a similar issue where I had to schedule events based on a user's local time. I ended up storing the day of the week, hour, minute, and Olson timezone string, and used Noda-Time to convert to a DateTimeOffset and from there to server time.

Community
  • 1
  • 1
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108