How does DateTime.ToUniversalTime() work?
There is no implicit timezone attached to a DateTime
object. If you run ToUniversalTime()
on it, it uses the timezone of the context that the code is running in.
For example, if I create a DateTime
from the epoch of 1/1/1970, it gives me the same DateTime
object no matter where in the world I am.
If I run ToUniversalTime()
on it when I'm running the code in Greenwich, then I get the same time. If I do it while I live in Vancouver, then I get an offset DateTime
object of -8 hours.
This is why it's important to store time related information in your database as UTC times when you need to do any kind of date conversion or localization. Consider if your codebase got moved to a server facility in another timezone ;)
Edit: note from Joel's answer - DateTime
objects by default are typed as DateTimeKind.Local
. If you parse a date and set it as DateTimeKind.Utc
, then ToUniversalTime()
performs no conversion.
And here's an article on "Best Practices Coding with Date Times", and an article on Converting DateTimes with .Net.
What does .ToUniversalTime() really do on a DateTime instance (C#)?
The value returned by the "ToUniversalTime" method is determined by the "Kind" property of the current DateTime object. The following describes the possible results:
Kind: Utc
Results: No conversion is performed.
Kind: Local.
Results: The current DateTime object is converted to UTC.
Kind: Unspecified.
Results: The current DateTime object is assumed to be local time, and the conversion is performed as if Kind were Local.
The default is Unspecified.
The ToUniversalTime method converts a DateTime value from local time to UTC. To convert the time in a non-local time zone to UTC, use the TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) method. To convert a time whose offset from UTC is known, use the ToUniversalTime method.
How DateTime.Parse works in case to universal time format
The Parse
method sets the Kind
property of the date to DateTimeKind.Unspecified
as there is no time zone information in the string. The ToUniversalTime
method assumes that the time is local and converts it to UTC.
Ref: DateTime.Parse Method
"Generally, the Parse method returns a DateTime object whose Kind
property is DateTimeKind.Unspecified."
Ref: DateTime.ToUniversalTime Method
"Unspecified: The current DateTime object is assumed to be a local time, and the
conversion is performed as if Kind were Local."
What is the difference between DateTime.UtcNow and DateTime.Now.ToUniversalTime()
Actually it's the other way around. The Now
property is implemented as:
public static DateTime Now {
get {
return UtcNow.ToLocalTime();
}
}
DateTime.ToUniversalTime() not correct
Not sure if it's the best solution, but this certainly works:
var InputTime = new DateTime(2016, 10, 12, 12, 22, 0, DateTimeKind.Local);
var offset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
var OutputTime = DateTime.SpecifyKind(InputTime - offset, DateTimeKind.Utc);
DateTime.ToUniversalTime() gets ignored in asp.net application
The ToLocalTime
and ToUniversalTime
methods on the DateTime
object are for converting between UTC and the local time zone of the computer where the code is running. They do not belong in an ASP.Net application. Neither does DateTime.Now
.
Many servers follow a best practice of having their time zone set to UTC, so in these environments you will see no difference other than the change of the .Kind
metadata property.
In general, in an server-side environment such as ASP.Net, you should not depend on the server's local time zone to be anything in particular. Instead, you should use the TimeZoneInfo
class to convert between UTC and a specific time zone. For example:
string tzid = "Romance Standard Time"; // for Denmark
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(tzid);
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(localTime, tz);
Also, it's important to understand that time zones and culture are two different things. They are not related whatsoever.
What is the difference between DateTime.ToUniversalTime and TimeZoneInfo.ConvertTimeToUtc
If you run the code on a machine in a different timezone, are your calculations still going to work? This is the reason people store and treat all DateTimes as UTC - it removes any ambiguity. You wouldn't need to store the user's timezone. Any machine, anywhere, can pull a date from the database and convert it to and from local times with ease.
If you're storing times in some other timezone, then you have to pull it out, calculate the offset to the desired timezone, including factoring in daylight savings times and international dateline considerations. In your case, you're also storing extra unnecessary information.
Different time output for ToUniversalTime
The ToUniveralTime
method converts from the local time zone where the code is running, to UTC.
Since time zones can change their offsets from UTC at different times of the year, the value can easily be different between two different dates - especially since one date is in the winter, and the other is in the summer, due to daylight saving time.
See also, the DST tag wiki, and "time zone != offset" in the timezone tag wiki.
.ToUniversalTime(), why it works this way?
Because of daylight savings. Local time is as it appears on your clock. UTC is continuous without gaps, without ambiguous points in time.
Related Topics
Reading a Key from the Web.Config Using Configurationmanager
Owin Security - How to Implement Oauth2 Refresh Tokens
Is There Any JSON Web Token (Jwt) Example in C#
Self Referencing Loop Detected - Getting Back Data from Webapi to the Browser
.Include() VS .Load() Performance in Entityframework
How to Route Images Using ASP.NET MVC Routing
Practical Applications of Bitwise Operations
How to Add a String to a String[] Array? There's No .Add Function
Getting All Changes Made to an Object in the Entity Framework
+= New Eventhandler(Method) VS += Method
How to Find All the Classes Which Implement a Given Interface
What Does Maxdegreeofparallelism Do
Gmail Smtp via C# .Net Errors on All Ports
Using Datetime in a SQLparameter for Stored Procedure, Format Error