Reputation: 185
I have a date, say "2016-10-20 20:34:60". When I create this datetime, I'm not sure how to specify that this DateTime was made based on the servers local timezone. IN this case, it's "Pacific Standard Time".
I want to present this as both a default text and data text. This data text will be used via javascript to change the date into the user's local time.
I'm new to C#, and am trying to wrap my head around how to do so. Many of the examples given are using UTC time. We store dates based on the servers localtime.
I want to ensure that the displayed default text is correct, regardless if we are in daylight saving mode or not, it should reflect what it was at that moment in time.
Upvotes: 1
Views: 7311
Reputation: 241563
In general, you shouldn't rely on the server's local time zone. It's a system-wide setting that can be easily changed without administrative permissions. Doing so makes you vulnerable to hard to track down production bugs, such as one server in a cluster having a different time zone setting than another. It also presents a problem if ever moving the server to a different location (or to the cloud) and having your data affected.
It's also very common for servers to have their time zones set to UTC intentionally, as to not have their log files affected by things like daylight saving time transitions.
If regardless you still want to assert that a DateTime
value reflected the computer's local time zone, you'd do that by ensuring DateTimeKind.Local
is set in the .Kind
property. This can be done in a constructor parameter, or with DateTimeStyles.AssumeLocal
when parsing, or with DateTime.SpecifyKind
on an existing value. You could then use .ToUniversalTime()
to convert to UTC before sending it along to the end user.
However, I strongly encourage you to use DateTimeOffset
instead. Unlike DateTime
, it will keep the offset around, and take it into consideration for most operations. If you construct a DateTimeOffset
from a DateTime
with DateTimeKind.Unspecified
, it will default to the local time zone. Similarly, if you create one via parsing (DateTimeOffset.Parse
, .TryParse
, .ParseExact
, .TryParseExact
, etc.) if there is no offset in the input string, it will default to the local time zone also.
HOWEVER - none of these objects will actually track a time zone in a way that will properly take transitions into account (such as when daylight saving time moves Pacific Time between PST and PDT and vice versa). If that's what you're looking for - sorry, you're out of luck with the built-in types. Instead you'll need to use the ZonedDateTime
class from the Noda Time open-source library.
Also, you stated:
... This data text will be used via javascript to change the date into the user's local time.
It is not impossible, but it is quite difficult to get JavaScript to convert a date and time to the user's local time zone unless you also have the offset. Serializing a DateTimeOffset
value back to browser will give you that for display, but if you're going to ask the user to change the value then you'll have to convert it back somehow.
It's all heck of a lot easier if you simply pass UTC values back and forth between the browser and the server. Then you can just convert UTC to Local time and vice versa in the browser. (At least for date+time values. Don't try to convert date-only values.)
Upvotes: 0
Reputation: 4395
You can get the current time zone with
TimeZoneInfo.Local
Alternatively, you can get the current offset like this:
DateTimeOffset.Now
You'd need to store the relevant info in the database along side your date and time.
EDIT Per the comment below and https://learn.microsoft.com/en-us/dotnet/standard/datetime/ TimeZone.CurrentTimeZone
has been superseded. Use TimeZoneInfo.Local
instead. The answer was modified to reflect this.
Upvotes: 0