Pat Long - Munkii Yebee
Pat Long - Munkii Yebee

Reputation: 3629

Converting Date back to user's timezone from Azure Table Storage

It is my understanding that Azure Table Storage stores all datetime fields as UTC AKA Zulu Time.

Currently I am in the UK 11th May 2021 at 18:10. The current TimeZone here is BST (+1:00).

If I serialise that into JSON using the RoundtripKind option

string json = JsonConvert.SerializeObject(this.syncDates, Formatting.Indented, new JsonSerializerSettings
                {
                    DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind
                });

It will be sent to my Web Api as

"2021-05-11T18:10:31.740582+01:00"

However when it is deserialised into the ASP NET Core controller method arguments it appears as a DateTime with DateTimeKind of Local but no longer has any Time Zone Info.

11/05/2021 18:10:31

I then write the Date into Azure Table Storage and it will be stored as UTC which is

11/05/2021 17:10:31

When I retreive the data from the web api to display it to the originating user or someone else who wants to look at their data, it is important to know the correct date and hour in relation to the user.

  1. Should I be storing the originating Time offset\zone in a separate field and using that to convert the Date back out again?

  2. Should I not be storing as a DateTime at all and using DateTimeOffset or is that pointless as Azure Table Storage will just convert the DTO to UTC as well?

Upvotes: 2

Views: 1884

Answers (1)

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241485

To preserve the offset during serialization/deserialization, yes - you should use the DateTimeOffset type instead of DateTime.

With regard to Azure Table Storage, while the SDKs support DateTimeOffset, unfortunately the service itself does not. Thus saving a DateTimeOffset value to Azure Storage will result in the equivalent UTC DateTime being stored, as given by the .UtcDateTime property of the DateTimeOffset. When retrieving, you will have a DateTimeOffset whose date and time are the equivalent UTC date and time, and the offset will be zero.

Thus, if you really need to keep track of the offset, you'll need to store that in a separate column, and combine the two in your controller upon return. The DateTimeOffset.ToOffset method is the easiest way to do that correctly.

Alternatively, if you only need the date and time parts to be correct, you could fib a little and use a UTC DateTime even if the value isn't actually in UTC. Just call DateTime.SpecifyKind with DateTimeKind.Utc on the way in, and with DateTimeKind.Unspecified on the way out. You'll loose the offset, but if you don't need it anyway then this can work.

Upvotes: 1

Related Questions