You are dealing with Time and Timezones. That way lies madness.
My ideal advice is to scrap this idea. This is a Calendar App. Rather then push notification, use a Distributed Database Design (they had a massive surge in use cases since Mobile Apps have become a thing) and have the client App decide when to raise alarm based on the Client Computers time and timezone.
The .NET DateTime code is exceptionally good, in that it will extract the users Timezone and Culture settings during input and output from the OS. But as you realized, this will not help you with Server Applications - you only get the Servers Timezone automagically. The best you can usually do on Server side is store a "preferred timezone" or something like that. And then adapt it during processing.
I have 3 rules for dealing with Time and Timezones:
- Always store, transmit and retrieve the date in UTC. You do not want to get timezones causing issues here.
- Never store, transmit or retrieve them as strings.
- If you got to transmit them as strings, pick a fixed Culture Format and Encoding at all endpoints. You do not want to add that to your issues. XML and JSON take care of both parts for you.
A important thing to remember when changing a DateTime, is that it is a build-in struct. And those are usually immutable and DateTime is not a exception. You can not change a instance - only create a new one with a different values. So you need to store the results of any function calls in a DateTime
variable.
This is what DateTimes Documentation says for your case:
The DateTime structure itself offers limited support for converting from one time zone to another. You can use the ToLocalTime method to convert UTC to local time, or you can use the ToUniversalTime method to convert from local time to UTC. However, a full set of time zone conversion methods is available in the TimeZoneInfo class. You convert the time in any one of the world's time zones to the time in any other time zone using these methods.
If you can move it to the user side, ToLocal()
is the droid you are looking for.
If you keep it on the server side, TimeZoneInfo.ConvertTime()
and it's overloads are what you need. Ideally you would want to have a collection of TimeZoneInfo Rulesets that you can let the user select. But I have no idea how to provide one.