• C# i .NET
  • Jak zamienić timestamp Unix na datę w .NET?

Jak zamienić timestamp Unix na datę w .NET?

Bruno Krawczyk • 31 października 2026
Konwerter Unix Timestamp: zamienia epokę na datę i odwrotnie. Automatycznie wykrywa sekundy, ms, μs i ns. Obsługuje strefy czasowe i ISO 8601.

Spis treści

Odbierasz z API liczbę `1700000000` i chcesz zapisać ją jako datę w aplikacji .NET. To najpewniej liczba sekund od początku epoki uniksowej, ale ten sam opis pola bywa używany dla milisekund, a pomyłka zmienia wynik o rzędy wielkości.

Liczbę czasu trzeba czytać razem z jej jednostką

  • Początek epoki: 1 stycznia 1970 o północy UTC.
  • W .NET: użyj `DateTimeOffset.FromUnixTimeSeconds` albo wariantu dla milisekund.
  • Strefa: liczba wskazuje chwilę, a nie lokalny zapis daty.
  • Zakres: typowe wartości `DateTimeOffset` wykraczają poza ograniczenia starszych, 32-bitowych liczników.

W .NET konwersję wykonuje DateTimeOffset

Wartość `1700000000` opisuje liczbę sekund, które upłynęły od 1970-01-01T00:00:00Z. Litera `Z` oznacza UTC. Sam zapis nie zawiera informacji, jak wyświetlić tę chwilę w polskim czasie.

Do konwersji wybieram `DateTimeOffset`, bo przechowuje chwilę razem z przesunięciem względem UTC. Microsoft Learn dokumentuje metody `FromUnixTimeSeconds` i `ToUnixTimeSeconds`; pierwsza zwraca obiekt z przesunięciem UTC, a druga zamienia obiekt na liczbę pełnych sekund.

using System;

long timestamp = 1700000000;
DateTimeOffset instant =
    DateTimeOffset.FromUnixTimeSeconds(timestamp);

Console.WriteLine(instant); // 11/14/2023 10:13:20 PM +00:00

long secondsAgain = instant.ToUnixTimeSeconds();

Jeśli potrzebujesz czasu warszawskiego do prezentacji, przelicz gotową chwilę przez `TimeZoneInfo`, zamiast zmieniać samą liczbę. To rozdziela dwie rzeczy, które łatwo pomylić: moment zdarzenia i jego lokalny zapis.

Jednostkę rozpoznaj po kontrakcie, nie po liczbie cyfr

Współczesna wartość w sekundach często ma 10 cyfr, a w milisekundach 13, ale to tylko wskazówka. Zakres dat, dane testowe albo inna jednostka mogą złamać tę regułę, więc sprawdzam opis pola w API lub dokumentacji formatu.

Wartość lub źródłoJednostkaMetoda .NET
`1700000000`Sekundy`FromUnixTimeSeconds`
`1700000000000`Milisekundy`FromUnixTimeMilliseconds`
`DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()`Milisekundy`FromUnixTimeMilliseconds` przy odczycie

Reguła jest prosta: jeśli kontrakt mówi o sekundach, użyj metody sekundowej; jeśli mówi o milisekundach, użyj milisekundowej. Nie zgaduj na podstawie samej nazwy `timestamp` i nie mnoż ani nie dziel wartości bez potwierdzenia jednostki.

Własność precyzji też zależy od metody. `ToUnixTimeSeconds()` zwraca pełne sekundy, więc część ułamkowa chwili przepada; jeśli system ma zachować milisekundy, potrzebna jest metoda milisekundowa.

Ta sama liczba daje inny zapis w Warszawie i UTC

Przy wartości `1700000000` konwersja sekundowa daje chwilę 14 listopada 2023 o 22:13:20 UTC. W Warszawie tego dnia obowiązywał czas UTC+1, więc na ekranie lokalnym będzie to 23:13:20. Liczba się nie zmieniła, zmienił się sposób jej pokazania.

Przy pracy z API zwykle zostawiam chwilę w UTC, a strefę stosuję dopiero w warstwie prezentacji. Dzięki temu dwa serwery w różnych krajach nadal porównują to samo zdarzenie, zamiast porównywać lokalne odczyty zegara.

SytuacjaSkutekCo zrobić
Liczba wygląda jak data z 1970 rokuMilisekundy mogły zostać odczytane jako sekundy.Sprawdź jednostkę w kontrakcie i wybierz metodę milisekundową, jeśli ją określono.
Data różni się o godzinęChwila jest poprawna, lecz wyświetlono ją w innej strefie.Porównaj wartości UTC, a lokalną strefę zastosuj przy prezentacji.
`FromUnixTimeSeconds` zgłasza `ArgumentOutOfRangeException`Liczba wykracza poza zakres obsługiwany przez `DateTimeOffset`.Zweryfikuj jednostkę, znak wartości i zakres danych wejściowych.

Daty sprzed początku epoki są poprawne: mają ujemne wartości. Przykładowo minuta przed północą UTC 1 stycznia 1970 odpowiada `-60`, a nie błędowi konwersji.

Licznik 32-bitowy kończy się tam, gdzie long działa dalej

Typowe przykłady w .NET używają `long`, czyli 64-bitowej liczby całkowitej ze znakiem. Kłopot z rokiem 2038 dotyczy systemów i formatów, które nadal zapisują sekundy w 32-bitowym, podpisanym `time_t`: taki licznik osiąga granicę 19 stycznia 2038 o 03:14:07 UTC.

Open Group opisuje przepełnienie implementacji `time_t` opartej na 32-bitowej liczbie ze znakiem. Dla aplikacji .NET nie oznacza to, że każda data z przyszłości jest problemem: `DateTimeOffset` przyjmuje znacznie szerszy zakres, ale ograniczenie może siedzieć w bazie, natywnym komponencie albo kontrakcie zewnętrznego systemu.

Unix time nie uwzględnia sekund przestępnych jako osobnych kolejnych wartości. Microsoft Learn zaznacza to w opisie konwersji, a POSIX opisuje pomijanie sekund przestępnych w czasie od epoki. Do typowych logów i znaczników zdarzeń to spójna konwencja; do pomiarów wymagających ścisłego śledzenia czasu astronomicznego potrzebny jest inny model.

Najpierw ustal jednostkę, potem zapisuj chwilę

W systemie produkcyjnym zapisz jednostkę w nazwie pola lub schemacie, na przykład `createdAtUnixSeconds`, i waliduj zakres przy wejściu. Sama etykieta `timestamp` pozostawia miejsce na błąd, który może wyglądać jak problem ze strefą albo uszkodzona data.

Uważam, że najbezpieczniejszy przepływ w .NET jest czytelny: parsuj jawnie sekundy lub milisekundy do `DateTimeOffset`, trzymaj chwilę w UTC i przeliczaj ją na czas lokalny dopiero wtedy, gdy ma ją zobaczyć człowiek.

FAQ - Najczęstsze pytania

Sprawdź jednostkę w kontrakcie API lub dokumentacji formatu. Dziesięć cyfr często oznacza sekundy, a trzynaście milisekundy, ale liczba cyfr jest tylko wskazówką. W .NET użyj odpowiednio DateTimeOffset.FromUnixTimeSeconds lub DateTimeOffset.FromUnixTimeMilliseconds.

Najpierw przekonwertuj wartość na DateTimeOffset, która reprezentuje chwilę w UTC. Następnie przelicz ją przez TimeZoneInfo do strefy warszawskiej. Przykładowo 1700000000 oznacza 22:13:20 UTC, czyli 23:13:20 w Warszawie tego dnia.

Ujemna wartość oznacza chwilę sprzed początku epoki Unix, czyli 1 stycznia 1970 o północy UTC. Na przykład -60 wskazuje minutę przed tą chwilą i jest prawidłową wartością, a nie błędem konwersji.

Nie sam DateTimeOffset, który obsługuje znacznie szerszy zakres niż 32-bitowy licznik sekund. Problem może wystąpić w systemie, bazie lub komponencie używającym 32-bitowego, podpisanego time_t, którego granicą jest 19 stycznia 2038 o 03:14:07 UTC.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi

utc
strefy czasowe
czas uniksowy
datetimeoffset
Autor Bruno Krawczyk
Bruno Krawczyk
Mam na imię Bruno i od 8 lat zgłębiam tajniki programowania w ekosystemie .NET, chmury Azure oraz sztucznej inteligencji. Moja przygoda z technologią zaczęła się od ciekawości, jak złożone systemy mogą ułatwiać codzienne życie i rozwiązywać realne problemy. Dziś moją misją jest dzielenie się tą wiedzą, starając się przybliżyć nawet najbardziej skomplikowane zagadnienia w sposób zrozumiały i przystępny dla każdego. W moich artykułach na kursdotnet.pl skupiam się na praktycznych aspektach, analizuję najnowsze trendy i weryfikuję informacje, aby dostarczyć Wam treści, które są nie tylko dokładne i aktualne, ale przede wszystkim użyteczne w Waszej własnej ścieżce rozwoju technologicznego.

Udostępnij artykuł

Napisz komentarz