Convert Unix time with PowerShell
60,971
Solution 1
See Convert a Unix timestamp to a .NET DateTime.
You can easily reproduce this in PowerShell.
$origin = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0
$whatIWant = $origin.AddSeconds($unixTime)
Solution 2
Function Convert-FromUnixDate ($UnixDate) {
[timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($UnixDate))
}
$niceTime = Convert-FromUnixDate $ctime
PS C:\> $niceTime
Friday, 18 May 2012 8:24:18 p.m.
Solution 3
Use:
(([System.DateTimeOffset]::FromUnixTimeSeconds($unixTime)).DateTime).ToString("s")
FromUnixTimeMilliseconds
is also available.
ToString("s"): Sortable: "The pattern reflects a defined standard (ISO 8601)"
Ref.: Standard Date and Time Format Strings, The Sortable ("s") Format Specifier
Solution 4
$date = get-date "1/1/1970"
$date.AddSeconds($unixTime).ToLocalTime()
Solution 5
A simple one-liner:
(Get-Date "1970-01-01 00:00:00.000Z") + ([TimeSpan]::FromSeconds($unixTime))

Author by
mrwh1t3
Updated on October 09, 2021Comments
-
mrwh1t3 over 1 year
I am parsing an SQLite database using the PowerShell SQLite module, and a couple of the return values are created and modified, both of which are in Unix time.
What I would like to do is somehow convert that into "human time". I have removed some of the other SQL queries for ease of reading.
Import-Module SQLite mount-sqlite -name GoogleDrive -dataSource E:\Programming\new.db $cloud_entry = Get-ChildItem GoogleDrive:\cloud_entry foreach ($entry in $cloud_entry) { $entry.created }
The output looks like a large column of Unix timestamps:
1337329458
Update: I ultimately went with the following:
$ctime = $entry.created [datetime]$origin = '1970-01-01 00:00:00' $origin.AddSeconds($ctime)
-
mklement0 almost 4 yearsWhat you went with is ambiguous, because something like
[datetime] '1970-01-01 00:00:00'
creates a[datetime]
instance whose.Kind
property isUnspecified
. By contrast, the start of Unix epoch time is unambiguously UTC. -
mklement0 about 3 years@Thomas
[datetime] '1970-01-01Z'
, which gives you aLocal
[datetime]
instance; if you need aUtc
instance, use([datetime] '1970-01-01Z').ToUniversalTime()
-
brianary over 1 year@mklement0 Using a UTC start time for a value during daylight saving time is giving me a result that is off by an hour (the DST offset). I think using that method is doing the time zone calculation based on the start datetime, instead of the ending datetime.
-
mklement0 over 1 year@brianary You're correct: the correct solution is to get a
Utc
[datetime]
instance, add the Unix epoch time (in seconds) to it, and then convert to local time:([datetime] '1970-01-01Z').ToUniversalTime().AddSeconds($ctime).ToLocalTime()
. Alternatively, using[datetimeoffset]
(which is preferable in general):[datetimeoffset] '1970-01-01Z').AddSeconds($ctime).LocalDateTime
-
brianary over 1 year@mklement0 Just to clarify, a UTC DateTime doesn't seem to work without some extra confusing steps, see the further discussion below, stackoverflow.com/a/10781745/54323
-
-
Torbjörn Bergstedt almost 11 years
[datetime]$origin = '1970-01-01 00:00:00'
works just as well, and is maybe a little easier to understand -
mrwh1t3 almost 11 yearsI'm getting this error: Any ideas? Cannot convert argument "0", with value: "", for "AddSeconds". Some of the values are "null", in that some of the items in the database are not assiged a created/modified date. I'm assuming this is where that error is coming from.
-
bluuf over 4 yearsI feel stupid knowing that for the past years I've used [System.DateTime]::Parse('1-1-1970).AddSeconds($epoch) instead of DateTimeOffset
-
user2190601 over 4 yearsNo worries, it looks like the method is new as of .net 4.6!
-
mklement0 about 3 yearsGood idea to request a UTC time, but you can do that simply by passing another argument to the
New-Object
call:New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0, Utc
-
brianary over 1 yearThe time zone is going to be wrong unless you add
.ToLocalTime()
to the end of that second line. You can't use[datetime]'1970-01-01Z'
because that'll do the time zone offset of the start time, which will be off during daylight savings. -
brianary over 1 yearThis doesn't seem to work. For a value of
1629937097
, I'm getting2021-08-26T00:18:17
instead of2021-08-26T17:18:17
(see epochconverter.com or a similar reference converter). -
mklement0 over 1 yearGood point, @brianary:
[datetime] '1970-01-01Z'
by itself isn't enough, because it returns aLocal
[datetime]
instance, which locks in the DST offset at the start time. Instead, use([datetime] '1970-01-01Z').ToUniversalTime().AddSeconds($unixTime)
to get the time as aUTC
time stamp, and([datetime] '1970-01-01Z').ToUniversalTime().AddSeconds($unixTime).ToLocalTime()
to convert to aLocal
one. Or, using[datetimeoffset]
, which is preferable in general:([datetimeoffset] '1970-01-01Z').AddSeconds($unixTime)
, then access.UtcDateTime
or.LocalDateTime
, as needed. -
user2190601 over 1 year@brianary The powershell output will be UTC in 24h format. I'm seeing 2021-08-26T00:18:17 from powershell and from epochconverter (top field) GMT: Thursday, August 26, 2021 12:18:17 AM which is equivalent since the converter output in is 12h time.
-
brianary over 1 year@mklement0 This works fine
(Get-Date 1970-01-01).AddSeconds($unixTime).ToLocalTime()
, without the confusion of code creating a UTC DateTime and then converting that to UTC again. The DateTimeOffset approach also gave me the wrong answer. -
brianary over 1 year@Fredrick It looks like I can use
(([System.DateTimeOffset]::FromUnixTimeSeconds($unixTime)).DateTime.ToLocalTime()).ToString("s")
-
brianary over 1 year@mklement0 Correction: DateTimeOffset does work, once converted to localtime.
-
mklement0 over 1 yearYou're right @brianary (the alternative is
([datetime] '1970-01-01').AddSeconds($unixTime).ToLocalTime()
), but there is a pitfall:Get-Date 1970-01-01
(and[datetime] '1970-01-01'
) create anUnspecified
[datetime]
instance. While this happens to work with.ToLocalTime()
, if you need a local instance (because anUnspecified
instance is then treated asUTC
), it misbehaves if you call.ToUniversalTime()
(becauseUnspecified
is then likeLocal
). Working withUnspecified
instances can introduce subtle bugs. -
brianary over 1 year@mklement0
Unspecified
is exactly what you want from a start time, since you don't want the DateTime to calculate the time zone offset until you've calculated the final DateTime.([datetime] '1970-01-01').AddSeconds($unixTime).ToLocalTime().Kind
returnsLocal
, so the result of the expression isn't vulnerable to anyUnspecified
bugs. Do you have an example of a value that would cause a problem? -
mklement0 over 1 year@brianary, please see my previous comment for an example (to recap: if you want a
Utc
instance from anUnspecified
one,.ToUniversalTime()
assumes thatUnspecified
meansLocal
) - my recommendation is to stay away fromUnspecified
, for the reasons stated, and, taking a step back, to work with[datetimeoffset]
whenever possible. Yes, if you know you want a local timestamp and you're aware of the general pitfalls, you can use your shortcut - but I wouldn't recommend it. I think we've covered all angles now. -
Garric over 1 yearTime zone in function. It's great. The bulky function is easily reduced if desired. Thank you.