Parsen einer Datumszeichenkette in eine bestimmte Zeitzone (Unterstützung der Sommerzeit)

Ok, ich habe sehr hart gearbeitet in den letzten Wochen und ich habe ein kleines problem. Ich glaube nicht, dass mein Geist ist ganz die Aufgabe hier und jetzt 🙂 also ich brauche ein paar Tipps/Hilfe! es ist wahrscheinlich sehr einfach, aber mein Kopf nicht Klick noch.

Benutzer ein Datum eingeben und time in AEST. Es gibt auch eine Applikation "Standard" timezone (wie könnte es ändern müssen), zur Zeit auf "AUS Eastern Standard Time"

Wir haben also ein Benutzer den string mit der keine Zeit-zone und eine definierte Zeitzone auf einem server in den USA (Also lokal nicht übereinstimmen und es kann nicht geändert oder verwendet werden)

Nun, was ich brauche ist eine Art zu sagen: "parse diese Benutzer eingegebenen Zeichenkette mit der Zeitzone X" ich kann nicht einfach geben Sie +10 oder +11 offset als das Datum kann in oder außerhalb der Sommerzeit, die ja nicht ändern, es zwischen +10 und +11 sogar für die gleiche Zeitzone!

Den aktuellen AEST Zeit kann auch in oder aus der DST-ich kann also nicht einfach konvertieren Sie ein UTC-Datum an der aktuellen AEST Zeit und Holen Sie sich die "zzz" Schnur und befestigen Sie es entweder als Termin wird um eine Stunde auf irgendetwas trat aus der aktuellen Sommerzeit-Einstellung.

Jetzt der code eigentlich macht genau das:

TimeZoneInfo ConvTo = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["DefaultTimeZone"]);
DateTimeOffset getDate = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, ConvTo);
string TimeZoneId = " " + getDate.ToString("zzz");
DateTimeOffset cvStartDate = DateTimeOffset.MinValue; DateTimeOffset.TryParse(StartDate + TimeZoneId, out cvStartDate);

Ich dann prüfen, wenn das Datum nicht gültig ist, indem Sie überprüfen, ob es noch == DateTimeOffset.MinValue-oder konvertieren es zur UTC-Zeit und der Datenbank hinzufügen, wird die zurück konvertiert werden, AEST, wenn Sie angezeigt werden. Aber ein paar Termine um eine Stunde und andere, die sind perfekt (wie erwartet) 🙂

Was ist der eleganteste Weg, um dieses Problem zu lösen?

EDIT:

Helfen, zu erklären, das problem, schrieb ich einige test-code als windows-Anwendung testen:

//User entered date
string EnteredDate = "2011/01/01 10:00:00 AM";

//Get the timezone we want to use
TimeZoneInfo myTimeZone = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");

//Find the timezone string of the selected timezone to parse the user string
//This is the part that is incorrect and what i need help with.
DateTimeOffset getDate = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, myTimeZone);
string TimeZoneId = " " + getDate.ToString("zzz");

//Parse the string into the date object
DateTimeOffset cvEnteredDate = DateTimeOffset.MinValue; DateTimeOffset.TryParse(EnteredDate + TimeZoneId, out cvEnteredDate);

//Display
textBox1.Text += "Parsed: " + cvEnteredDate.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine;

//Convert to UTC and display
cvEnteredDate = cvEnteredDate.ToUniversalTime();
textBox1.Text += "UTC: " + cvEnteredDate.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine;

//Convert back to AEST and display
cvEnteredDate = TimeZoneInfo.ConvertTime(cvEnteredDate, myTimeZone);
textBox1.Text += "Changed Back: " + cvEnteredDate.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine;

Was ist die Ausgabe dieses?

Analysiert: 2011/01/01 10:00:00 +10:00 
UTC: 2011/01/01 00:00:00 +00:00 
Wieder Zurück Geändert: 2011/01/01 11:00:00 +11:00 

Bitte beachten Sie, die Stunde ist um eins und der offset ist anders. Außerdem, was ist, wenn wir ändern Sie EINFACH das Datum eingegeben:

string EnteredDate = "2011/04/20 10:00:00 AM";

erhalten wir:

Analysiert: 2011/04/20 10:00:00 +10:00 
UTC: 2011/04/20 00:00:00 +00:00 
Wieder Zurück Geändert: 2011/04/20 10:00:00 +10:00 

Ist vollkommen gut und in Ordnung, mit dem gleichen code, nur ein anderes Datum eingegeben.

Dies geschieht, weil die aktuelle Sommerzeit-Einstellung und die DST-Einstellung des eingegebenen Datum sind unterschiedlich, das ist, was ich will, eine Lösung für 🙂

Denke es ist wie bei der Henne-und-ei-problem. Ich brauche die korrekte Zeitzone Daten für die eingegebenen string, bevor ich analysieren, die kann ich nur bekommen, nachdem ich analysiert den string (also eine aufwendige Lösung)

Oder ich brauche .NET analysiert die Zeichenfolge mit dem myTimeZone Objekt, damit es weiß, was, um es zu sich selbst, aber ich kann nicht sehen, alle Funktionen, die dies tun, werden Sie alle nehmen bereits analysiert und festgelegt datetime-oder datetimeoffset-Objekt

So, ich bin auf der Suche nach eleganten Lösungen, die andere vielleicht gemacht haben? Ich kann sicherlich nicht der einzige, der das bemerkt?

EDIT2:

Ok habe ich gemacht, ein 'Arbeits' - Funktion löst das problem, das ich denke, hier ist ein Beispiel (fügen Sie ein Textfeld, um eine c# - windows-app und verwenden Sie den folgenden code selber testen):

private void Form1_Load(object sender, EventArgs e)
{
    TimeZoneInfo myTimeZone = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");

    DateTimeOffset get1Date = ReadStringWithTimeZone("2011/01/01 10:00:00 AM", myTimeZone);
    textBox1.Text += "Read1: " + get1Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine;
    get1Date = get1Date.ToUniversalTime();
    textBox1.Text += "Read1 - UTC: " + get1Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine;
    get1Date = TimeZoneInfo.ConvertTime(get1Date, myTimeZone);
    textBox1.Text += "Changed Back: " + get1Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine + Environment.NewLine;

    DateTimeOffset get2Date = ReadStringWithTimeZone("2011/04/20 10:00:00 AM", myTimeZone);
    textBox1.Text += "Read2: " + get2Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine;
    get2Date = get2Date.ToUniversalTime();
    textBox1.Text += "Read2 - UTC: " + get2Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine;
    get2Date = TimeZoneInfo.ConvertTime(get2Date, myTimeZone);
    textBox1.Text += "Changed Back: " + get2Date.ToString("yyyy/MM/dd HH:mm:ss zzz") + Environment.NewLine + Environment.NewLine;
}

public DateTimeOffset ReadStringWithTimeZone(string EnteredDate, TimeZoneInfo tzi)
{
    DateTimeOffset cvUTCToTZI = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi);
    DateTimeOffset cvParsedDate = DateTimeOffset.MinValue; DateTimeOffset.TryParse(EnteredDate + " " + cvUTCToTZI.ToString("zzz"), out cvParsedDate);
    if (tzi.SupportsDaylightSavingTime)
    {
        TimeSpan getDiff = tzi.GetUtcOffset(cvParsedDate);
        string MakeFinalOffset = (getDiff.Hours < 0 ? "-" : "+") + (getDiff.Hours > 9 ? "" : "0") + getDiff.Hours + ":" + (getDiff.Minutes > 9 ? "" : "0") + getDiff.Minutes;
        textBox1.Text += "Diff: " + MakeFinalOffset + Environment.NewLine;
        DateTimeOffset.TryParse(EnteredDate + " " + MakeFinalOffset, out cvParsedDate);
        return cvParsedDate;
    }
    else
    {
        return cvParsedDate;
    }
}

Und die Ausgabe:

Diff: +11:00 
Read1: 2011/01/01 10:00:00 +11:00 
Read1 - UTC: 2010/12/31 23:00:00 +00:00 
Wieder Zurück Geändert: 2011/01/01 10:00:00 +11:00 

Diff: +10:00 
Read2: 2011/04/20 10:00:00 +10:00 
Read2 - UTC: 2011/04/20 00:00:00 +00:00 
Wieder Zurück Geändert: 2011/04/20 10:00:00 +10:00 

Nur die Sache ist, es könnte ein problem sein, wenn das eingegebene Datum richtig ist auf die Veränderung über die Stunde der Sommerzeit ist es immer noch die eine Stunde ab, wie es nur das Auslesen der aktuellen offset-und mit diesem, dann die Kontrolle, wenn sein soll die Sommerzeit oder nicht, und wenn Ihr da draußen es Lesen würden, falsch. Aber es ist Meilen besser als das, was ich jetzt habe.

Kann jemand vielleicht mir helfen mit dem Aufräumen diese Funktion? Dies ist die beste route gehen für das, was ich brauche? Ideen?

InformationsquelleAutor der Frage White Dragon | 2011-04-10

Schreibe einen Kommentar