I wrote about unix timestamp i powershell.
I wrote : It is chockingly easy !
but I should have written : … it is not correct 🙁
PS> ./perl -e "print time.'`n'"
1331454753
PS> get-date -u %s
1331458358.05694
there is about 3605 seconds difference. 1 hour for Europe/Zurich and 5 seconds to type on a slow keyboard…
Even more confusing
PS> get-date "1970-01-01 00:00:00 +00:00" -u %s
3600
Ok, why that? this is related to the Kind
PS> (get-date "1970-01-01 00:00:00 +00:00").kind
Local
A Unix timestamp of Kind Local is useless. Don’t use this.
Unix timestamp should only refers to Utc.
PS> get-date
Sonntag, 11. März 2012 10:47:35
PS> get-date ((get-date).touniversaltime()) -u %s
1331459257.78432
still it is very confusing to using the unixformat in Windows
PS> get-date -u %c__%Z__%s
So Mrz 11 10:55:05 2012__+01__1331463305.85197
PS> get-date ((get-date).touniversaltime()) -u %c__%Z__%s
So Mrz 11 09:55:46 2012__+01__1331459746.07913
the %s does not work as expected with local (as it refers to a local 1970-01-01) and %Z does not work at all with utc (it sould be +00
OK, let’s switch to the Microsoft time. You count the time as the number of tenth of microseconds (or ticks) since 1 Jan 0001. Again it may differ if you do not use utc.
Let’s define constant $c as number of ticks until 1970-01-01, in utc
PS> $c = (get-date "1970-01-01 00:00:00 +00:00").touniversaltime().ticks
PS> $c
621355968000000000
Let’s convert it to a human readable format
PS C:\> New-Object datetime($c)
Donnerstag, 1. Januar 1970 00:00:00
So far so good.
Lets convert 1331461119 back and forth
PS> (New-Object datetime($c + 1331461119 * 10000000)).tolocaltime()
Sonntag, 11. März 2012 11:18:39
PS> (New-Object datetime($c + 1331461119 * 10000000))
Sonntag, 11. März 2012 10:18:39
PS> ( (get-date "2012-03-11 10:18:39 +00:00").touniversaltime().ticks - $c ) / 10000000
1331461119
PS> ( (get-date "2012-03-11 11:18:39 +01:00").touniversaltime().ticks - $c ) / 10000000
1331461119
BTW, what does Oracle think of the number of ticks of current date ?
PS> $d=36217;"select to_char(date '0001-01-01' + $d,'YYYY-MM-DD') from dual;"|sqlplus -s -L scot/tiger;New-Object datetime($d*864000000000)
TO_CHAR(DA
----------
0100-02-28
Sonntag, 28. Februar 0100 00:00:00
PS C:\> $d=36218;"select to_char(date '0001-01-01' + $d,'YYYY-MM-DD') from dual;"|sqlplus -s -L scot/tiger;New-Object datetime($d*864000000000)
TO_CHAR(DA
----------
0100-02-29
Montag, 1. März 0100 00:00:00
Apparently Microsoft does not have a leap year in 100AD.
Ok, whatelse to say about date?
There is one more format that is commonly used in Microsoft world, the so-called DMTF or Distributed Management Task Force. Let’s have a quick look with 1-JAN-2000.
PS C:\> [System.Management.ManagementDateTimeConverter]::TodmtfDateTime((get-date "2000-01-01 00:00:00"))
20000101000000.000000+060
PS C:\> [System.Management.ManagementDateTimeConverter]::TodmtfDateTime((get-date "2000-01-01 00:00:00 +00:00").touniversaltime())
20000101000000.000000+000
PS C:\> [System.Management.ManagementDateTimeConverter]::ToDateTime('20000101000000.000000+060')
Samstag, 1. Januar 2000 00:00:00
PS C:\> [System.Management.ManagementDateTimeConverter]::ToDateTime('20000101000000.000000+000').touniversaltime()
Samstag, 1. Januar 2000 00:00:00
Pingback: Laurent Schneider » Unix timestamp in powershell
Great stuff – thanks a lot 😉