A dátumok kezelésével kapcsolatban egy alapszabályt mindenképpen be kell tartanunk: soha ne kezdjünk el kézihajtány módszerrel dátumokat faragni, a beépített metódusok és tulajdonságok használata nem csak egyszerűbb megoldáshoz vezet, de a számtalan hibalehetőség elkerülésének érdekében egyenesen kötelező.
Mit tud a PowerShell a dátumokkal kapcsolatban? Igazság szerint nem túl sokat, mindössze két egyszerű cmdletet kapunk: A Get-Date segítségével az aktuális rendszerdátumot és időt kérdezhetjük le, valamint [datetime] típusú adatot állíthatunk elő; a Set-Date cmdlet pedig ezek beállítását képes elvégezni. A háttérben tehát mindig ott van a .NET DateTime osztálya; ennek segítségével már bármit megtehetünk.
Próbáljunk meg készíteni dátumot a következő karakterláncból: „2009. november 18.”, és alakítsuk át „2009.11.18” alakra (természetesen úgy, hogy bármilyen dátumra működjön)!
Dátumot leíró karakterláncok beolvasására a DateTime osztály statikus Parse() metódusa szolgál. A Parse() egy mindenevő metódus, ismeri és beolvassa az összes szokásos dátumformátumot:
PS C:\> PS C:\> [DateTime]::Parse("2009. november 18.")
2009. november 18. 0:00:00
A fenti kifejezés egy DateTime objektumot ad vissza (aki nem hiszi, annak Get‑Member segít), ennek egy metódusát kell meghívnunk, hogy az egyszerűbb alakot előállítsuk (az eredmény már nem dátum, hanem karakterlánc!):
[29] PS C:\> ([DateTime]::Parse("2009. november 18.")).ToShortDateString()
2009.11.18.
Megjegyzés
A [datetime] konstruktora is képes némi dátumértelmezésre, azonban nem olyan okos, mint a Parse metódus:
[31] PS C:\> $d = [datetime] "2009.11.18."
[32] PS C:\> $d
2009. november 18. 0:00:00
[33] PS C:\> $d = [datetime] "2009. május 18."
Cannot convert value "2009. május 18." to
type "System.DateTime". Error:
"The string was not recognized as a valid
DateTime. There is a unknown wo
rd starting at index 6."
At line:1 char:16
+ $d = [datetime] <<<< "2009. május 18."
+
CategoryInfo : NotSpecified: (:)
[], RuntimeException
+
FullyQualifiedErrorId : RuntimeException
A [31]-es sorban létrehozott [datetime] típusú változóban az ottani, magyar nyelvű formában szövegként megadott dátumot képes volt értelmezni, de a [33]-as sor szövegét már nem.
Hogyan lehetne megállapítani, hogy milyen napra esik az aktuális dátum 13 év múlva? A 13 évnyi időutazás a PowerShellben nem lehet probléma: egy Get-Date eredményére meg kell hívnunk az AddYears() metódust. A hét napjának nevét pedig a DayOfWeek tulajdonság adja vissza:
[36] PS C:\> (get-date).AddYears(13).DayOfWeek
Friday
A Get-Date használható [datetime]objektumok konstruktoraként is:
[37] PS C:\> $d = Get-Date -year 2009 -month 11 -day 18
[38] PS C:\> $d
2009. november 18. 11:12:06
A fenti példában a Get-Date cmdlettel majdnem ugyanazt értem el, mint a megjegyzés [31]-es sorában. Egy fontos különbség van: míg a korábbi példában a nem megadott óra, perc, másodperc érték nulla lett, addig a Get-Date használatával az aktuális óra, perc, másodperc érték helyettesítődik be, ami esetleg nem kívánatos a programunk működése szempontjából.
Ha zűrösebb formátumból szeretnénk dátum típust előállítani, használhatjuk a [datetime] osztály ParseExact metódusát is:
PS C:\> $d = "2010. év 12. hónapjának 28. napja 13. órája 17. perce 39. másodpe
rce 38. századmásodperce"
PS C:\> $f = "yyyy. év MM. \hónapjának dd. napja HH. órája mm. perce ss. \má\so
\dperce ff. \s\zá\za\d\má\so\dperce"
PS C:\> [datetime]::ParseExact($d,$f,$null)
2010. december 28. 13:17:39
Látható, hogy a dátum-idő-sztring ($d) egyes számjegyeit egy formátumsztringgel ($f) lehet „kimaszkolni”. A formátumsztring egyes szimbólumainak részletes leírása a http://msdn.microsoft.com/en-us/library/8kb3ddd4 oldalon olvasható, ezek közül én a leggyakoribbakat alkalmaztam:
Formátum-karakter |
Jelentése |
y |
Év |
M |
Hónap |
d |
Nap |
H |
Óra |
m |
Perc |
s |
Másodperc |
f |
tized és századmásodpercek |
z |
Időzóna |
Látható, hogy ha „töltelékszöveget” akarok jelezni a formátum-kifejezésben, akkor az abban előforduló, a formázás szempontjából jelentéssel bíró karaktereket „hatástalanítani” kell az „escape” karakterrel, ami jelen esetben a backslash. Sajnos nincs a [datetime] osztálynak Escape metódusa, így ezt az escape-elést nekünk kell elvégezni.
Megjegyzés
Az escape-elendő karakterek: d, f, F, g, h, H, K, m, M, s, t, y, z, :, /. Itt megint fontos a kis-nagybetű megkülönböztetése.
Most próbáljuk meg kilistázni azokat a folyamatokat, amelyek az elmúlt 1 órán belül indultak el a számítógépen! Először is le kell gyártanunk az egy órával ezelőtti időt, a változatosság kedvéért használjuk most a DateTime osztály statikus Now tulajdonságát. (Statikus tagokkal részletesebben majd a 1.3.8 .NET típusok, statikus tagok fejezetben lesz szó.) A második sor azokat a Process objektumokat válogatja le, amelyeknek StartTime tulajdonságában ennél későbbi időpont szerepel.
[54] PS C:\> $ora = [DateTime]::Now.AddHours(-1)
[55] PS C:\> Get-Process | Where-Object {$_.StartTime -ge $ora}
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
52 6 1208 3948 61 0,06 1644 notepad
A második sorban az $ora változó helyére természetesen beírhattuk volna magát a kifejezést is, a két parancs csak a jobb áttekinthetőség miatt került külön sorba.
Hogyan lehetne visszaállítani a számítógép óráját 10 perccel? A rendszeridőt a Set-Date cmdlet segítségével tologathatjuk, paraméterként TimeSpan objektumot (lásd később), vagy az adott területi beállítások mellett időintervallumként értelmezhető karakterláncot is megadhatunk. A megoldás tehát:
[56] PS C:\> Set-Date -adjust -0:10:0
2009. november 18. 11:18:38
Nézzük meg kicsit részletesebben a [datetime] adattípus tagjellemzőit:
[64] PS C:\> $d = get-date
[65] PS C:\> $d | Get-Member
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Add Method System.DateTime Add(System.TimeSpan value)
AddDays Method System.DateTime AddDays(double value)
AddHours Method System.DateTime AddHours(double value)
AddMilliseconds Method System.DateTime AddMilliseconds(double ...
AddMinutes Method System.DateTime AddMinutes(double value)
AddMonths Method System.DateTime AddMonths(int months)
AddSeconds Method System.DateTime AddSeconds(double value)
AddTicks Method System.DateTime AddTicks(long value)
AddYears Method System.DateTime AddYears(int value)
CompareTo Method int CompareTo(System.Object value), int...
Equals Method bool Equals(System.Object value), bool ...
GetDateTimeFormats Method string[] GetDateTimeFormats(), string[]...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
GetTypeCode Method System.TypeCode GetTypeCode()
IsDaylightSavingTime Method bool IsDaylightSavingTime()
Subtract Method System.TimeSpan Subtract(System.DateTim...
ToBinary Method long ToBinary()
ToFileTime Method long ToFileTime()
ToFileTimeUtc Method long ToFileTimeUtc()
ToLocalTime Method System.DateTime ToLocalTime()
ToLongDateString Method string ToLongDateString()
ToLongTimeString Method string ToLongTimeString()
ToOADate Method double ToOADate()
ToShortDateString Method string ToShortDateString()
ToShortTimeString Method string ToShortTimeString()
ToString Method string ToString(), string ToString(stri...
ToUniversalTime Method System.DateTime ToUniversalTime()
DisplayHint NoteProperty Microsoft.PowerShell.Commands.DisplayHi...
Date Property System.DateTime Date {get;}
Day Property System.Int32 Day {get;}
DayOfWeek Property System.DayOfWeek DayOfWeek {get;}
DayOfYear Property System.Int32 DayOfYear {get;}
Hour Property System.Int32 Hour {get;}
Kind Property System.DateTimeKind Kind {get;}
Millisecond Property System.Int32 Millisecond {get;}
Minute Property System.Int32 Minute {get;}
Month Property System.Int32 Month {get;}
Second Property System.Int32 Second {get;}
Ticks Property System.Int64 Ticks {get;}
TimeOfDay Property System.TimeSpan TimeOfDay {get;}
Year Property System.Int32 Year {get;}
DateTime ScriptProperty System.Object DateTime {get=if ((& { Se...
Látható, hogy számos metódus és tulajdonság áll rendelkezésünkre a dátum-idő típusú adatok kezelésére. A rendszer mélyén ezek az adatok egész számként, un. ketyegésekben vannak tárolva, ehhez a Ticks tulajdonságon keresztül férünk hozzá:
[66] PS C:\> $d.ticks
634029707852086250
Ez nem egy apró szám! Az időszámításunk óta eltelt 100 ns-okban mért idő.
Megjegyzés
Érdekes módon ez más algoritmus az AD-ben használatos „longint” formátumú időtároláshoz képest, hiszen ott 1601. január 1. 0:00 a kiindulási időpont és ehhez képest veszi 100 ns-okban az eltelt időt.