Parsowanie daty i czasu z formatu "yyyy-MM-ddTHH:mm:ssZ"

0

Witam,
Mam problem z prawidłowym przekształceniem pobranej daty i czasu z pewnej strony.
Odpowiedź przyjmuje jedną z dwóch możliwości i zapewne zależy od czasu letniego/zimowego:
"1700-04-01T1300Z"
"1700-12-01T1300Z"
Te dwa formaty zawsze oznaczają godzinę 1400.
Zachodzę w głowę jak prawidłowo to przerobić na godzinę 1400.

            string czaswaznosci1 = "1700-04-01T13:00:00Z";
            string czaswaznosci2 = "1700-12-01T13:00:00Z";

            var data1 = DateTime.Parse(czaswaznosci1, new CultureInfo("pl-PL")).AddHours(-1).ToString("HH:mm:ss");
            Debug.WriteLine("czas gdy 1700-04-01 (minus 1h):" + data1);

            var data2 = DateTime.Parse(czaswaznosci2, new CultureInfo("pl-PL")).AddHours(0).ToString("HH:mm:ss");
            Debug.WriteLine("czas gdy 1700-12-01...:" + data2);

Wiem, że najprościej sprawdzić czy w otrzymanym stringu jest -04- lub -12- i albo odjąć godzinę, albo jej nie odejmować. Można to jakoś zgrabniej parsować?

1
duzers napisał(a):

Witam,

Mam problem z prawidłowym przekształceniem pobranej daty i czasu z pewnej strony.
Odpowiedź przyjmuje jedną z dwóch możliwości i zapewne zależy od czasu letniego/zimowego:
"1700-04-01T1300Z"
"1700-12-01T1300Z"
Te dwa formaty zawsze oznaczają godzinę 1400.

Ja tu widzę jeden format. O co tu w ogóle chodzi? Co to za daty, skąd je masz, i na jakiej podstawie chcesz coś zamieniać?

2

Dlaczego uważasz, że te daty oznaczają zawsze godzinę 14:00?
Data, którą otrzymujesz jest zapisana w zgodzie z normą ISO 8601. Litera Z na końcu oznacza, że to jest czas UTC.
Czas zimowy u nas w kraju w odniesieniu do czasu UTC jest przesunięty o godzinę, a czas letni o dwie.
Wystarczy, że zrobisz DateTime.Parse("1700-04-01T13:00:00Z") i otrzymasz prawidłowy czas w naszym kraju.

0

@somekind: No tak, jeden format, ale otrzymywany w zależności od pory roku, w którym złożono polecenie np. uruchom coś o godzinie 1400. System wewnętrzny zapisuje to właśnie tak jak wspomniałem w poście. Chciałbym zapisać jakiś uniwersalny kod odczytujący i przekształcający na godzinę 1400.

2

Uwaga podaję rozwiązanie. Zwraca oczekiwany rezultat. Ale czuję pod skórą, że za czas jakiś, ktoś zgłosi spory problem w tym systemie związany z interpretacją dat :)

var czaswaznosci1Offset = DateTimeOffset.Parse(czaswaznosci1).ToOffset(TimeSpan.FromHours(1));
var czaswaznosci2Offset = DateTimeOffset.Parse(czaswaznosci2).ToOffset(TimeSpan.FromHours(1));
1

Może ktoś podrzuci jakiś kompleksowy tutorial jak sie obchodzić z datami (w c#, choć taki ogólny niezalezny od języka też chętnie poczytam)? Strefy, czasy letnie/zimowe, formaty itd

3
duzers napisał(a):

@somekind: No tak, jeden format, ale otrzymywany w zależności od pory roku, w którym złożono polecenie np. uruchom coś o godzinie 1400. System wewnętrzny zapisuje to właśnie tak jak wspomniałem w poście. Chciałbym zapisać jakiś uniwersalny kod odczytujący i przekształcający na godzinę 1400.

To jak dla mnie, to należy zapisać prawidłową wartość daty i czasu w momencie składania tego polecenia, najlepiej jako UTC, bo jest jednoznaczny.
A po drugie, to zamiast DateTime należy używać DateTimeOffset, bo niesie ze sobą informacje o strefach czasowych.

0

@somekind:

somekind napisał(a):

To jak dla mnie, to należy zapisać prawidłową wartość daty i czasu w momencie składania tego polecenia, najlepiej jako UTC, bo jest jednoznaczny.

No właśnie w systemie podajesz czas normalnie, a on magazynuje to sobie w pokazanej przeze mnie formie.
Pobieram całą tabelę z takimi danymi do własnych celów i chciałem wyświetlić ten czas poprawnie z użyciem
zgrabnego sposobu, którym to DateTimeOffset jest działającym :)

2

Ja nadal nie rozumiem istoty problemu, bo nadal nie wiem co to za daty i czemu uważasz, że zawsze są przesunięte o godzinę, ani czemu piszesz o rozróżnianiu po miesiącu, skoro przesunięcie jest zawsze takie samo.

Tak czy siak, to jeżeli masz jakąś sparsowaną datę w obiekcie typu DateTime albo DateTimeOffset, to wystarczy wywołać metodę ToLocalTime() aby uzyskać tę datę w czasie lokalnym.
Konwersje między różnymi strefami czasowymi to trochę bardziej zagmatwana sprawa, np.:
TimeZoneInfo.ConvertTimeFromUtc(DateTime.SpecifyKind(DateTime.Parse("1700-04-01T13:00:00Z", new System.Globalization.CultureInfo("pl-PL")), DateTimeKind.Utc), TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"))
(Będzie wyglądało znacznie lepiej po podzieleniu na zmienne.)

A tak w ogóle, to ta cała dyskusja jest bez sensu, bo te wartości, które parsujesz nic nie znaczą. Przypomnijmy:

"1700-04-01T13:00:00Z"
"1700-12-01T13:00:00Z"

W XVII wieku nie było ani czasu letniego ani zimowego, ani UTC, ani stref czasowych, ani nawet nikt o takich rzeczach nie myślał, bo Ziemia nie była powszechnie uważana za kulę.

0

@somekind: Obecnie system czas transakcji zapisuje jako "1700-04-01T1300Z" i po użyciu DateTime.Parse zwracany jest wynik 1500, co nie jest prawdą ponieważ transakcje wykonano o godzinie 1400.
Natomiast dla zapisu "1700-12-01T1300Z" DateTime.Parse zwraca prawidłową wartość 1400.
Widocznie programista systemu tak sobie to wymyślił.

0

Skoro informacja o strefie czasowej jest i tak nieprawidłowa, to najlepiej ją usuń (czyli skasuj "Z" s końca stringa). Wówczas po sparsowaniu dostaniesz w obu przypadkach godzinę 13, więc dodaj sobie jedną (używając .AddHours(1)), i będziesz miał 14:00.

1 użytkowników online, w tym zalogowanych: 0, gości: 1