Ответ 1
Я бы использовал Noda Time лично, но если вы не можете этого сделать...
Либо используйте DateTime.ParseExact
, указав точный формат, который вы ожидаете, и включите DateTimeStyles.AssumeUniversal
и DateTimeStyles.AdjustToUniversal
в код синтаксического анализа:
using System;
using System.Globalization;
class Test
{
static void Main()
{
var date = DateTime.ParseExact("2012-09-30T23:00:00.0000000Z",
"yyyy-MM-dd'T'HH:mm:ss.fffffff'Z'",
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal |
DateTimeStyles.AdjustToUniversal);
Console.WriteLine(date);
Console.WriteLine(date.Kind);
}
}
(Понятно, почему он будет настраиваться на локальный по умолчанию, если AdjustToUniversal
находится вне меня, но неважно...)
EDIT: Чтобы расширить мои возражения против предложения mattytommo, я стремился доказать, что он потеряет информацию. Я провалился до сих пор, но очень своеобразно. Взгляните на это - работайте в европейском/лондонском часовом поясе, где часы вернутся 28 октября 2012 года, в 2 часа по местному времени (1:00 по UTC):
DateTime local1 = DateTime.Parse("2012-10-28T00:30:00.0000000Z");
DateTime local2 = DateTime.Parse("2012-10-28T01:30:00.0000000Z");
Console.WriteLine(local1 == local2); // True
DateTime utc1 = TimeZoneInfo.ConvertTimeToUtc(local1);
DateTime utc2 = TimeZoneInfo.ConvertTimeToUtc(local2);
Console.WriteLine(utc1 == utc2); // False. Hmm.
Похоже, что там где-то где-то где-то хранится флаг "с или без DST", но я буду взорван, если смогу поработать где. Документы для TimeZoneInfo.ConvertTimeToUtc
state
Если dateTime соответствует неоднозначному времени, этот метод предполагает, что это стандартное время в исходном часовом поясе.
Это не выглядит здесь при преобразовании local2
...
EDIT: Хорошо, это становится еще более странным - это зависит от того, какую версию используемой структуры вы используете. Рассмотрим эту программу:
using System;
using System.Globalization;
class Test
{
static void Main()
{
DateTime local1 = DateTime.Parse("2012-10-28T00:30:00.0000000Z");
DateTime local2 = DateTime.Parse("2012-10-28T01:30:00.0000000Z");
DateTime utc1 = TimeZoneInfo.ConvertTimeToUtc(local1);
DateTime utc2 = TimeZoneInfo.ConvertTimeToUtc(local2);
Console.WriteLine(utc1);
Console.WriteLine(utc2);
DateTime utc3 = local1.ToUniversalTime();
DateTime utc4 = local2.ToUniversalTime();
Console.WriteLine(utc3);
Console.WriteLine(utc4);
}
}
Таким образом, это принимает два разных значения UTC, анализирует их с помощью DateTime.Parse
, затем преобразует их обратно в UTC двумя разными способами.
Результаты в .NET 3.5:
28/10/2012 01:30:00 // Look - we've lost information
28/10/2012 01:30:00
28/10/2012 00:30:00 // But ToUniversalTime() seems okay...
28/10/2012 01:30:00
Результаты в .NET 4.5 beta:
28/10/2012 00:30:00 // It okay!
28/10/2012 01:30:00
28/10/2012 00:30:00
28/10/2012 01:30:00