Get-Date w PowerShellu - formatowanie dat i UTC

Radosław Krajewski 24 sierpnia 2026
Ikona kalendarza i zegara obok tekstu "Get-Date" na tle grafiki z napisem "Date Time".

Spis treści

Gdy skrypt ma zapisać log, utworzyć nazwę pliku albo sprawdzić termin wykonania zadania, potrzebuje wiarygodnej daty i godziny. W PowerShellu służy do tego przede wszystkim polecenie Get-Date, które zwraca bieżący czas oraz pozwala go formatować, porównywać i przeliczać. Pokażę praktyczne przykłady, różnicę między datą jako obiektem a tekstem, obsługę UTC oraz zastosowanie w aplikacjach desktopowych.

Najważniejsze reguły pracy z datą w PowerShellu

  • Get-Date bez parametrów zwraca lokalną datę i godzinę komputera.
  • Parametr -Format tworzy tekst, więc nie należy używać go zbyt wcześnie w obliczeniach.
  • Do logów i nazw plików najlepiej sprawdza się format yyyy-MM-dd HH:mm:ss albo jego wariant bez znaków specjalnych.
  • Przy komunikacji między komputerami bezpieczniej przechowywać czas w UTC.
  • W aplikacjach WPF warto przekazywać do widoku obiekt DateTime, a formatowanie zostawić warstwie interfejsu.

Get-Date w PowerShellu od podstaw

Najprostsze użycie nie wymaga żadnych parametrów. Wpisuję polecenie i otrzymuję bieżącą datę oraz godzinę zgodną z ustawieniami systemu Windows.

Get-Date

Wynikiem jest obiekt typu System.DateTime, a nie zwykły tekst. To ważne, ponieważ mogę od razu korzystać z jego właściwości i metod.

$now = Get-Date

$now.Year
$now.Month
$now.Day
$now.Hour
$now.Minute
$now.DayOfWeek

W praktyce często interesuje mnie tylko konkretna informacja. Właściwość .Date usuwa część godzinową, a .TimeOfDay zwraca samą porę dnia.

$today = (Get-Date).Date
$currentTime = (Get-Date).TimeOfDay

Jeżeli potrzebuję wartości zbudowanej na podstawie konkretnych składników, mogę przekazać parametry takie jak -Year, -Month, -Day czy -Hour.

Get-Date -Year 2026 -Month 10 -Day 15 -Hour 9 -Minute 30

Do odczytywania podanej daty wygodniejszy jest parametr -Date. Przy datach wpisywanych jako tekst trzeba uważać na kulturę systemu. Zapis ISO 8601 jest zwykle bezpieczniejszy niż niejednoznaczne wartości w rodzaju 03/04/2026.

Get-Date -Date '2026-10-15T09:30:00'

Formatowanie bez utraty kontroli nad typem danych

Formatowanie jest proste, ale właśnie tutaj pojawia się jeden z częstszych błędów. Polecenie Get-Date -Format zwraca łańcuch znaków, a nie obiekt DateTime. Taki wynik dobrze wygląda na ekranie, lecz nie nadaje się już bezpośrednio do dodawania dni ani porównywania dat.

Get-Date -Format 'dd.MM.yyyy HH:mm:ss'

Gdy chcę zachować typ daty, pobieram obiekt do zmiennej, a formatuję dopiero podczas wyświetlania.

$date = Get-Date

$date.AddDays(7)
$date.ToString('dd.MM.yyyy')

W skryptach działających na komputerach z różnymi ustawieniami regionalnymi preferuję format jednoznaczny. Dzięki temu logi i nazwy plików sortują się chronologicznie, a dzień i miesiąc nie zamieniają się miejscami.

Zastosowanie Przykład Dlaczego warto
Log czytelny dla człowieka dd.MM.yyyy HH:mm:ss Naturalny zapis używany w Polsce
Log techniczny yyyy-MM-dd HH:mm:ss Jednoznaczny i łatwy do sortowania
Nazwa pliku yyyyMMdd-HHmmss Brak znaków problematycznych w systemie plików
Wymiana danych o Precyzyjny format round-trip dla .NET

Do nazw plików używam na przykład takiego zapisu:

$fileName = "raport-$(Get-Date -Format 'yyyyMMdd-HHmmss').csv"

Warto odróżnić -Format od -DisplayHint. Ten drugi wpływa głównie na sposób prezentacji wyniku w konsoli, natomiast nie jest zamiennikiem właściwego formatowania danych przekazywanych dalej.

Obliczenia, zakresy i porównywanie czasu

Obiekt zwracany przez Get-Date pozwala wykonywać obliczenia bez ręcznego przeliczania sekund czy dni. Najczęściej korzystam z metod AddDays, AddHours i AddMinutes.

$today = Get-Date

$tomorrow = $today.AddDays(1)
$inTwoHours = $today.AddHours(2)
$lastWeek = $today.AddDays(-7)

Do obliczania różnicy między datami służy odejmowanie. Wynikiem jest obiekt TimeSpan, który udostępnia między innymi liczbę dni, godzin i minut.

$start = Get-Date '2026-09-01T08:00:00'
$end = Get-Date '2026-09-03T17:30:00'

$duration = $end - $start

$duration.Days
$duration.TotalHours

Jeżeli sprawdzam termin wykonania zadania, nie formatuję daty przed porównaniem. Porównanie dwóch tekstów może dać wynik pozornie poprawny tylko wtedy, gdy oba teksty mają właściwy, sortowalny układ.

$deadline = Get-Date '2026-10-01T17:00:00'
$now = Get-Date

if ($now -lt $deadline) {
    'Termin jeszcze nie minął'
}
else {
    'Termin został przekroczony'
}

Ten schemat dobrze sprawdza się przy wygaszaniu plików tymczasowych, kontroli certyfikatów i monitorowaniu zadań Windows. Z mojego doświadczenia wynika, że więcej problemów powoduje niejednoznaczne parsowanie daty niż samo porównanie.

Czas lokalny, UTC i strefy czasowe

Domyślnie Get-Date zwraca czas lokalny komputera. Na pojedynczym stanowisku pracy zwykle to wystarcza, ale przy logach z wielu urządzeń, usługach Azure albo wymianie danych między krajami szybko pojawia się problem różnych stref czasowych.

Do uzyskania czasu UTC można użyć konwersji obiektu:

$localTime = Get-Date
$utcTime = $localTime.ToUniversalTime()

W nowszych wersjach PowerShellu dostępny jest również parametr -AsUTC.

Get-Date -AsUTC

W starszym Windows PowerShellu bezpiecznym i czytelnym rozwiązaniem pozostaje ToUniversalTime(). Alternatywnie w kodzie .NET można użyć właściwości [datetime]::UtcNow.

[datetime]::Now
[datetime]::UtcNow

Sam zapis UTC nie rozwiązuje każdego problemu. Jeśli aplikacja musi pokazać użytkownikowi czas w konkretnej strefie, trzeba wykonać jawną konwersję i uwzględnić zmianę czasu letniego. Warto też rozważyć DateTimeOffset, gdy znaczenie ma zarówno data, jak i przesunięcie względem UTC.

$offsetNow = [datetimeoffset]::Now
$offsetNow.Offset

Moja praktyczna zasada jest prosta: lokalny czas służy do prezentacji, a UTC do zapisu, porównań i komunikacji między systemami. Dzięki temu aplikacja nie zaczyna zachowywać się inaczej po zmianie strefy albo po przejściu na czas zimowy.

Daty w aplikacjach desktopowych i WPF

Przekazywanie dat do tabeli

PowerShell często przygotowuje dane dla aplikacji desktopowej albo generuje plik, który później jest ładowany do interfejsu WPF. Jeżeli data ma trafić do tabeli, lepiej przekazać prawdziwy obiekt DateTime niż tekst utworzony przez -Format. Dzięki temu sortowanie odbędzie się chronologicznie, a nie alfabetycznie.

$items = @(
    [pscustomobject]@{
        Name = 'Raport A'
        CreatedAt = Get-Date
    },
    [pscustomobject]@{
        Name = 'Raport B'
        CreatedAt = (Get-Date).AddHours(-3)
    }
)

W widoku WPF format można ustawić osobno, bez niszczenia typu danych w modelu. Przy pracy z tabelą przydatne będą również zasady opisane w materiale o tym, jak działa DataGrid w WPF, szczególnie gdy użytkownik ma sortować albo edytować wartości.

Przeczytaj również: VCRUNTIME140.dll i MSVCP140.dll - jak naprawić błąd?

Wprowadzanie daty przez użytkownika

Jeżeli data pochodzi z pola tekstowego, nie zakładam, że użytkownik zawsze wpisze poprawny format. W aplikacji warto rozdzielić trzy etapy: pobranie tekstu, jego walidację oraz konwersję do DateTime.

$text = '15.10.2026 09:30'
$format = 'dd.MM.yyyy HH:mm'

$date = [datetime]::ParseExact(
    $text,
    $format,
    [Globalization.CultureInfo]::GetCultureInfo('pl-PL')
)

ParseExact wymaga dokładnego wzorca i dobrze pasuje do formularzy, w których format jest z góry ustalony. Gdy dopuszczam kilka wariantów zapisu, używam ostrożnie TryParse albo TryParseExact, ponieważ błędny tekst nie powinien przerywać działania całej aplikacji.

W przypadku formularzy WPF szczególnie ważna jest walidacja w WPF. Powinna poinformować użytkownika o błędzie przy polu, a nie dopiero po kliknięciu przycisku zapisującego dane.

Małe decyzje, które chronią skrypt przed błędami

  • Nie formatuj daty przed wykonaniem obliczeń. Najpierw pracuj na DateTime, a tekst twórz na samym końcu.
  • Nie używaj niejednoznacznych zapisów typu 03/04/2026, jeśli skrypt może działać na komputerach z inną kulturą.
  • Do logów i komunikacji między systemami wybieraj UTC oraz format jednoznaczny dla programu.
  • Przy nazwach plików pomijaj dwukropki, ukośniki i inne znaki niedozwolone w Windows.
  • Jeśli czas pochodzi z wielu komputerów, sprawdź synchronizację zegarów systemowych. Samo Get-Date odczytuje to, co twierdzi lokalny zegar.

Najkrótsza recepta brzmi więc tak: Get-Date pobiera bieżący czas, obiekt DateTime służy do obliczeń, a -Format wykorzystuję dopiero wtedy, gdy potrzebuję gotowego tekstu. Taki podział jest prosty, dobrze skaluje się w skryptach PowerShell i ogranicza liczbę niespodzianek w aplikacjach desktopowych.

FAQ - Najczęstsze pytania

Get-Date bez parametrów zwraca obiekt System.DateTime, na którym można wykonywać obliczenia, porównywać daty i korzystać z właściwości takich jak .Year czy .DayOfWeek. Parametr -Format zamienia wynik na tekst, dlatego najlepiej stosować go dopiero podczas wyświetlania lub tworzenia nazwy pliku.

Do czytelnych logów można użyć formatu dd.MM.yyyy HH:mm:ss, a do logów technicznych yyyy-MM-dd HH:mm:ss. Nazwy plików powinny używać zapisu yyyyMMdd-HHmmss, bez znaków niedozwolonych w Windows. Przy wymianie danych warto rozważyć format o, czyli round-trip dla .NET.

Get-Date zwraca lokalny czas komputera. UTC uzyskasz przez (Get-Date).ToUniversalTime(), parametr Get-Date -AsUTC w nowszym PowerShellu albo [datetime]::UtcNow. DateTimeOffset warto wybrać wtedy, gdy oprócz daty i godziny istotne jest także przesunięcie względem UTC.

Do tabeli WPF lepiej przekazać prawdziwy obiekt DateTime, aby sortowanie odbywało się chronologicznie, a format ustawić dopiero w widoku. Tekst z formularza należy najpierw zwalidować, a następnie przekonwertować. Dla ustalonego wzorca, na przykład dd.MM.yyyy HH:mm, można użyć ParseExact z kulturą pl-PL, natomiast dla kilku wariantów zapisu ostrożnie użyć TryParse lub TryParseExact.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi

powershell
datetime
utc
wpf
strefy czasowe
Autor Radosław Krajewski
Radosław Krajewski
Nazywam się Radosław Krajewski i od 6 lat zgłębiam tajniki programowania .NET, chmury Azure oraz sztucznej inteligencji. Moja przygoda z tymi technologiami zaczęła się od fascynacji tym, jak złożone problemy można rozwiązywać za pomocą kodu i innowacyjnych narzędzi. Staram się przekazywać tę wiedzę w sposób zrozumiały, dzieląc się swoimi doświadczeniami i spostrzeżeniami na kursdotnet.pl. W moich artykułach skupiam się na praktycznych aspektach, porównuję różne rozwiązania i analizuję najnowsze trendy, aby dostarczyć Wam rzetelne i aktualne informacje, które pomogą Wam rozwijać się w tej dynamicznie zmieniającej się dziedzinie.

Udostępnij artykuł

Napisz komentarz