Dátumok ([datetime], Get-Date, Set-Date)

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.



Word To HTML Converter