Преобразование в и из даты и времени добавляет час? - PullRequest
5 голосов
/ 13 сентября 2010

Я пишу довольно большое веб-приложение в asp.net/c# с MSSQL 2008 r2, обслуживающим базу данных. Программа должна преобразовать date/time строки (в формате даты ISO) в DateTime, где они используются, а затем сохранены как smalldatetime в sql.

Когда строки конвертируются в datetimes, к результату загадочным образом добавляется hour. Я понимаю, что, находясь в Великобритании, мы подвержены переходу на летнее время (в настоящее время активны), но наверняка метод datetime .convert это понимает? При преобразовании обратно в строку результат будет таким, как ожидалось.

Я написал небольшую программу, чтобы проиллюстрировать проблему (также включая даты, не относящиеся к ISO для моего здравомыслия):

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();
    }
}

Вот результаты, которые я получаю при запуске программы:

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

Это правильное поведение? Я идиот? Я ожидал бы преобразование даты и времени в строку, и тогда точная строка обратно в дату и время вернет исходный ввод. Если это правильное поведение, любые идеи о том, как получить последовательный результат, но все еще используя Convert.ToDateTime()?

Большое спасибо.

1 Ответ

11 голосов
/ 13 сентября 2010

«Z» в конце даты и времени означает «зулу» (эквивалент UTC / GMT). По умолчанию, когда вы преобразуете строку в конец, она будет преобразована в местное время (+ 1 час в вашем случае).

Без 'Z' .NET будет считать, что дата уже в правильном формате и не добавит час.

Когда вы форматируете дату и время обратно в строку, вы используете строку формата "U". Это говорит .NET, что это время UTC и должно быть отформатировано в такое время. Поэтому он добавляет «Z» в конце. При преобразовании его обратно в дату добавляется еще один час, чтобы сделать его локальным.

Для уточнения:

d1: начинается как строка UTC -> местное время (+ 1 час) -> строка UTC -> местное время (+1 час)

d2: начинается как локальная строка -> местное время (без изменений) -> строка UTC -> местное время (+ 1 час)

...