Converting to and from datetime adds an hour?
-
02-10-2019 - |
문제
I am writing a fairly large webapp in asp.net/c#
with MSSQL 2008 r2
serving the database. The program needs to convert date/time
strings (in ISO date format) to DateTime
where they are used and later stored as smalldatetime
in sql
.
When the strings are converted to datetimes
, an hour
is mysteriously added to the result. I understand that being in the UK, we are subjected to daylight savings time (currently active) but surely the datetime
.convert method understands this? When converting back to a string, the result is as expected.
I have written a small program to illustrate the problem (also including non ISO dates for my sanity):
class Program
{
static void Main(string[] args)
{
//BB();
//Dist();
DateTime d1 = new DateTime();
DateTime d2 = new DateTime();
string d1s = "2010-09-13T09:30:01Z";
string d2s = "2010-09-13 09:30:01";
d1 = Convert.ToDateTime(d1s);
d2 = Convert.ToDateTime(d2s);
Console.WriteLine("d1s:{0} d1:{1} ", d1s, d1);
Console.WriteLine("d2s:{0} d2:{1} ", d2s, d2);
d1s = d1.ToString("u"); d2s = d2.ToString("u");
Console.WriteLine("\nd1: {0}", d1s);
Console.WriteLine("d2: {0}", d2s);
d1 = Convert.ToDateTime(d1s);
d2 = Convert.ToDateTime(d2s);
Console.WriteLine("\nd1s:{0} d1:{1} ", d1s, d1);
Console.WriteLine("d2s:{0} d2:{1} ", d2s, d2);
Console.Read();
}
}
Here are the results I get when I run the program:
d1s:2010-09-13T09:30:01Z d1:13/09/2010 10:30:01
d2s:2010-09-13 09:30:01 d2:13/09/2010 09:30:01
d1: 2010-09-13 10:30:01Z
d2: 2010-09-13 09:30:01Z
d1s:2010-09-13 10:30:01Z d1:13/09/2010 11:30:01
d2s:2010-09-13 09:30:01Z d2:13/09/2010 10:30:01
Done
Is this the correct behavior? Am I being an idiot? I would have expected converting datetime to string and then the exact string back to datetime would give back the original input. If this is the correct behavior, any ideas on how to get a consistant result but still using Convert.ToDateTime()
?
Many Thanks.
해결책
The 'Z' at the end of the datetime means "Zulu" (equivalent of UTC/GMT). By default when you convert a string with that at the end of it it will convert it to local time (+ 1 hour in your case).
Without the 'Z' .NET will assume the date is already in the correct format and not add the hour.
When you format the datetime back into a string you are using the format string of "U". This is telling .NET that it is a UTC time and should be formatted at such. Therefore it adds the 'Z' to the end. When you convert it back to a date time another hour is added to make it local.
To clarify:
d1: Starts as a UTC string -> local time (+ 1 hour) -> UTC string -> local time (+1 hour)
d2: Starts as a local string -> local time (no change) -> UTC string -> local time (+ 1 hour)