Laden...

Parse "Sun Dec 13 03:52:21 +0000 2009" zu DateTime

Erstellt von MMCSharp vor einem Jahr Letzter Beitrag vor einem Jahr 674 Views
M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr
Parse "Sun Dec 13 03:52:21 +0000 2009" zu DateTime

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?

16.806 Beiträge seit 2008
vor einem Jahr

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

M
368 Beiträge seit 2006
vor einem Jahr

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 😉

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

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..

16.806 Beiträge seit 2008
vor einem Jahr

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 😉

4.931 Beiträge seit 2008
vor einem Jahr

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.

16.806 Beiträge seit 2008
vor einem Jahr

"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

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

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.

16.806 Beiträge seit 2008
vor einem Jahr

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".

M
MMCSharp Themenstarter:in
84 Beiträge seit 2022
vor einem Jahr

Vielen, vielen, vielen, herzlichen Dank für die Hilfe!

4.931 Beiträge seit 2008
vor einem Jahr

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.

16.806 Beiträge seit 2008
vor einem Jahr

Interessant, das wusste ich so auch nicht. Danke für die Aufklärung.