Hallo zusammen,
Ich würde gerne den String "Sun Dec 13 03:52:21 +0000 2009" in eine "DateTime" parsen um ihn in einem andrerem Format darzustellen. Allerdings scheitern meine Versuche mit Parse, TryPars und TryParseExact. Hat jemand eine Idee?
Was hast du denn genau versucht?
Es gibt wirklich in .NET kaum etwas, das so gut dokumentiert ist, wie Zeitformate.
Die Dokumentation sind 44(!) Din A4 Seiten.
Custom date and time format strings
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Nebenbei ist "DateTime" veraltend: FAQ - DateTime vs. DatetimeOffset...
Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉
folgendes (unprofessionell wirkendes) habe ich versucht, das nicht fehlerfrei klappt
string[] TimeSplits= _creation_date.Split(' ', '\t','\n','\r');
string dateString = $"{TimeSplits[0].Trim()} {TimeSplits[2].Trim()} {TimeSplits[1].Trim()} {TimeSplits[3].Trim()}";
string format = "ddd dd MMM hh:mm:ss";
if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result))
{
return result.ToString();
}
else
{
return "No date time info";
}
das habe ich versucht
if (DateTime.TryParse(_creation_date, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime result))
{
return result.ToString();
}
else
{
return "No date time info";
}
das habe ich versucht
if (DateTime.TryParseExact(_creation_date, "ddd MMM dd hh:mm:ss fffzzz yyyy", new CultureInfo("en-US"),DateTimeStyles.AssumeLocal, out DateTime dateTime))
{
return dateTime.ToString("dd.MM.yyyy hh:mm:ss");
}
und einiges andere..
Das Format muss schon dem entsprechen, was Du auch rein wirfst - das tut es ja nicht. Auch stimmen die Parameter nicht (siehe Docs).
Wild rumprobieren wird da nicht helfen. AssumeLocal darst zB nur verwenden, wenn Dein String keine Zeitzone enthält. Kann also niemals klappen.
Dein fffzzz
muss einfach zzzz
entsprechen. Deine Zeitzone ist schließlich 4 stellig und Millisekunden hast keine, also macht gar kein Sinn.
Erster Versuch mit den Hinweisen aus Custom date and time format strings - bin einfach nur die Tabelle durchgegangen und hab Format für Format übernommen. Hat 20 Sekunden gekostet 😉
string date = "Sun Dec 13 03:52:21 +0000 2009";
string format = "ddd MMM dd hh:mm:ss zzzz yyyy";
CultureInfo provider = new CultureInfo("en-US");
if(DateTime.TryParseExact(date, format, provider, DateTimeStyles.None, out DateTime dt))
{
Console.WriteLine(dt.ToString("o"));
}
Klappt einwandfrei: 2009-12-13T04:52:21.0000000+01:00
Aber ja, statt einfach die Docs zu lesen kann man auch viel Zeit verschwenden und rumprobieren 😉
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Dein letzter Code sieht schon ganz gut aus, jedoch sehe ich keine Millisekunden (daher solltest du fff
löschen).
Und +0000
ist wohl der Zeitzonenoffset, jedoch erwartet zzz
diesen im Format +00:00
(s.a. Formatspezifizierer „z“ für das Offset) - das müßtest du also mal näher evaluieren.
Desweiteren solltest du daher auch DateTimeOffset
verwenden.
@Abt: Als Nachfrage zu deinem Code: Woher hast du den vierstelligen zzzz
als Format? Dies ist, soweit ich gelesen habe, nirgendwo dokumentiert.
"z" ist dokumentiert.
Hours offset from UTC, with a leading zero for a single-digit value.
also pro Digit.
Edit, verdeutlichter formuliert:
"+0" ist "zz", weil ein z für das + steht.
"+00" ist daher "zzz"
und "+0000" muss daher "z" + "zzz" = "zzzz" sein.
Siehe auch Custom date and time format strings - Offset "z" format specifier
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Vielen Dank.. Manchmal sieht man einfach den Wald vor lauter Bäumen nicht mehr. Das klappt jetzt auch schon relativ gut, jedoch immer noch nicht zuverlässig. Der Versuch
"Mon Jan 23 14:55:09 +0000 2023" zu parsen schlägt wieder fehl.
Auch hier wieder ein Blick in die Docs.
"hh" bedeutet: The hour, using a 12-hour clock from 1 to 12.
Du hast aber "14", was bedeutet dass Du keine 12 Hour Clock hast, sondern 24. Daher muss es "HH" lauten und nicht "hh".
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Vielen, vielen, vielen, herzlichen Dank für die Hilfe!
Hallo Abt,
jetzt wollte ich es doch mal genauer wissen und habe im Source-Code nachgeschaut. Das eigentliche Parsen des Formats findet in der Methode DateTimeParse.ParseByFormat
statt, für "z"
in Zeile 4122 ff.
Dort wird erst mittels GetRepeatCount()
die maximale Anzahl des gleichen Formatspezifizierers (hier also z
) ermittelt und dann die Methode ParseTimeZoneOffset aufgerufen.
Und dort ist das Entscheidende der switch
über die Anzahl: bei Werten ungleich von 1
und 2
wird dann der default
Code ausgeführt und dort ist dann der entscheidende Hinweis als Kommentar
// ':' is optional.
if (str.Match(":"))
// ...
Zusammengefaßt also:
"z"
und "zz"
werden getrennt geparst"zzz"
sowie alle weiteren Wiederholungen von z
werden gleich behandelt. Was in der Doku fehlt, ist der Hinweis auf das optionale :
Zeichen bei dem Zeitzonenoffset!Ich habe jetzt auch mal den Code selber kompiliert und ausgeführt (nur mit "zzz"
und -1230
als Zeitzonenoffset):
string date = "Sun Dec 13 03:52:21 -1230 2009";
string format = "ddd MMM dd hh:mm:ss zzz yyyy";
CultureInfo provider = new CultureInfo("en-US");
CultureInfo provider2 = new CultureInfo("de-DE");
if(DateTime.TryParseExact(date, format, provider, DateTimeStyles.None, out DateTime dt))
{
Console.WriteLine(dt.ToString("o"));
Console.WriteLine(dt.ToString("G", provider2));
}
Richtige Ausgabe:
2009-12-13T16:22:21.0000000+00:00
13.12.2009 16:22:21
(also die Zeit um 12 Stunden und 30 Minuten verschoben)
Das selbe Ergebnis gibt es auch bei -12:30
als Zeitzonenoffset.
qed.
Interessant, das wusste ich so auch nicht. Danke für die Aufklärung.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code