Dowiedziałem się, jak zamienić DateTime na format ISO 8601 , ale nie ma nic o tym, jak zrobić odwrotność w C #.
Mam 2010-08-20T15:00:00Z
i chcę przekształcić go w DateTime
przedmiot.
Mógłbym sam oddzielić części struny, ale wydaje się, że to dużo pracy jak na coś, co jest już międzynarodowym standardem.
Odpowiedzi:
To rozwiązanie korzysta z wyliczenia DateTimeStyles i działa również z Z.
DateTime d2 = DateTime.Parse("2010-08-20T15:00:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);
To doskonale drukuje rozwiązanie.
źródło
DateTime d2= DateTime.Parse("2010-08-20T15:00:00Z", null, DateTimeStyles.RoundtripKind);
wydaje się działać ładnie.DateTimeStyles.RoundtripKind?
opis MSDN, jest pusty.2018-06-19T14:56:14.123Z
jest analizowany jako czas lokalny, a nie UTC. UżywamCultureInfo.InvariantCulture
zamiast null.DateTimeStyles.RoundTripKind
, zobacz stackoverflow.com/q/39572395/2014893Chociaż MSDN mówi, że formaty „s” i „o” odzwierciedlają standard, wydaje się, że są w stanie przeanalizować tylko ograniczony podzbiór. Szczególnie jest to problem, jeśli ciąg zawiera specyfikację strefy czasowej. (Ani dla podstawowych formatów ISO8601, ani dla formatów o zmniejszonej precyzji - jednak nie jest to dokładnie w twoim przypadku). Dlatego używam niestandardowych ciągów formatów, jeśli chodzi o parsowanie ISO8601. Obecnie mój preferowany fragment to:
static readonly string[] formats = { // Basic formats "yyyyMMddTHHmmsszzz", "yyyyMMddTHHmmsszz", "yyyyMMddTHHmmssZ", // Extended formats "yyyy-MM-ddTHH:mm:sszzz", "yyyy-MM-ddTHH:mm:sszz", "yyyy-MM-ddTHH:mm:ssZ", // All of the above with reduced accuracy "yyyyMMddTHHmmzzz", "yyyyMMddTHHmmzz", "yyyyMMddTHHmmZ", "yyyy-MM-ddTHH:mmzzz", "yyyy-MM-ddTHH:mmzz", "yyyy-MM-ddTHH:mmZ", // Accuracy reduced to hours "yyyyMMddTHHzzz", "yyyyMMddTHHzz", "yyyyMMddTHHZ", "yyyy-MM-ddTHHzzz", "yyyy-MM-ddTHHzz", "yyyy-MM-ddTHHZ" }; public static DateTime ParseISO8601String ( string str ) { return DateTime.ParseExact ( str, formats, CultureInfo.InvariantCulture, DateTimeStyles.None ); }
Jeśli nie masz nic przeciwko analizowaniu ciągów bez TZ (tak robię), możesz dodać wiersz „s”, aby znacznie zwiększyć liczbę objętych zmian formatu.
źródło
"yyyyMMdd"
wformats
tablicy, aby dokładność została zredukowana do dni, ponieważ czasami ma to miejsce, gdy RRULE RFC 5545 będzie polegać na DTSTART, aby zapewnić czas.K
umożliwia jednoczesne łączenie obsługi różnych stref czasowych. Mam bardziej rozbudowany wariant na stackoverflow.com/a/31246449/400547, ale jest on zbyt obszerny (akceptuje rzeczy, które są zgodne z ISO 8601, ale nie są używane w bardziej popularnych profilach), ale pokazuje, jakK
można zmniejszyć rozmiar o trzeci.using System.Globalization; DateTime d; DateTime.TryParseExact( "2010-08-20T15:00:00", "s", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out d);
źródło
Oto taki, który działa lepiej dla mnie ( wersja LINQPad ):
DateTime d; DateTime.TryParseExact( "2010-08-20T15:00:00Z", @"yyyy-MM-dd\THH:mm:ss\Z", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out d); d.ToString()
produkuje
true 8/20/2010 8:00:00 AM
źródło
Wydaje się ważne, aby dokładnie dopasować format ciągu ISO
TryParseExact
do pracy. Myślę, że Exact to Exact i ta odpowiedź jest oczywista dla większości, ale w każdym razie ...W moim przypadku odpowiedź Reb.Cabin nie działa, ponieważ mam nieco inne dane wejściowe, jak na moją „wartość” poniżej.
Wartość:
2012-08-10T14:00:00.000Z
Jest tam kilka dodatkowych tysięcy na milisekundy, a może być ich więcej.
Jeśli jednak dodam trochę
.fff
do formatu, jak pokazano poniżej, wszystko jest w porządku.Ciąg formatu:
@"yyyy-MM-dd\THH:mm:ss.fff\Z"
W oknie bezpośrednim VS2010:
DateTime.TryParseExact(value,@"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture,DateTimeStyles.AssumeUniversal, out d);
prawdziwe
Być może będziesz musiał użyć,
DateTimeStyles.AssumeLocal
w zależności od strefy, dla której jest twój czas ...źródło
AssumeUniversal
naAdjustToUniversal
.Działa to dobrze w LINQPad4:
Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00Z")); Console.WriteLine(DateTime.Parse("2010-08-20T15:00:00")); Console.WriteLine(DateTime.Parse("2010-08-20 15:00:00"));
źródło
DateTime.ParseExact(...)
pozwala powiedzieć parserowi, co reprezentuje każdy znak.źródło