In PowerShell, how can I convert string of DateTime to sum of seconds?
-
1What do you mean by "sum of seconds"? UNIX time (seconds since epoch)? – Thilo Nov 16 '10 at 10:11
-
yes, I mean to UNIX time – RRR Nov 16 '10 at 10:16
20 Answers
PS H:\> (New-TimeSpan -Start $date1 -End $date2).TotalSeconds
1289923177.87462
New-TimeSpan can be used to do that. For example,
$date1 = Get-Date -Date "01/01/1970"
$date2 = Get-Date
(New-TimeSpan -Start $date1 -End $date2).TotalSeconds
Or just use this one line command
(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds
-
what are the diffrents between Get-Date and [System.DateTime]? in my apps I used by [System.DateTime]. – RRR Nov 16 '10 at 10:45
-
1Nothing, AFAIK. Get-Date is equal to [DateTime]::Now and Get-Date -Date "01/01/1970" is equal to [DateTime]::Parse("01/01/1970") – ravikanth Nov 16 '10 at 10:56
-
13Unix time is based on UTC, so the last line should use $date2.ToUniversalTime(). It would also be useful to prefix the whole thing with [int]. – Rick Yorgason Feb 06 '14 at 20:58
-
Wouldn't they both be UTC? If so, does it make a difference in the distance between two date time objects in the same time zone? – Steve Buzonas Dec 20 '18 at 19:07
-
2check this answer https://stackoverflow.com/a/57487299/4534493 - if you are using PS 5.1 – Naren Jun 26 '20 at 17:47
With .NET Framework 4.6 you can use ToUnixTimeSeconds
method of DateTimeOffset
class:
[DateTimeOffset]::Now.ToUnixTimeSeconds()
$DateTime = Get-Date #or any other command to get DateTime object
([DateTimeOffset]$DateTime).ToUnixTimeSeconds()

- 21,204
- 4
- 50
- 60
-
i ended up using this: ```$fromEpoc = [DateTimeOffset]::Now.AddHours(-1).ToUnixTimeSeconds()*1000; $toEpoc = [DateTimeOffset]::Now.ToUnixTimeSeconds()*1000``` The return values work on the https://www.epochconverter.com/ site converter to verify the correct time is returned ;) – Omzig May 24 '23 at 16:40
As mentioned, the UNIX Epoch is January 1st, 1970 at 12:00 AM (midnight) UTC. To get the current seconds-since-the-epoch in UTC in a whole-number I use this 80-character one-liner
$ED=[Math]::Floor([decimal](Get-Date(Get-Date).ToUniversalTime()-uformat "%s"))
The code above is PowerShell 2.0 compliant & rounds-down (to ensure consistent behavior w/ UNIX)

- 558
- 5
- 16
-
Just noticed my #necromancer badge was from this answer. Glad everyone likes it :) – Signal15 Jun 15 '15 at 17:22
-
This definitely does not give the correct UNIX timestamp in my Powershell v3 (neither seconds nor milliseconds). I don't know how this got so many upvotes?! – jansohn Sep 25 '15 at 08:11
-
@lazlev You may have misread; the above code returns a UNIX-compatible "Seconds since the Epoch (Jan 1st 1970 in UTC) In PowerShell v2, v3 and v4. I've just confirmed this. Keep in mind that the 80-char one-liner stores the value in a variable, so it's not updated every time you check $ED (to do that, you'd need to use a function instead) – Signal15 Oct 23 '15 at 01:36
-
That looked good, but actually it's unreliable, because the number of digits is not constant. At the beginning of my development, I had to divide $ED by 10000 to get seconds, but now it's 100000. I didn't debug, I now use the solution of Keith Hill below. – ocroquette Oct 23 '15 at 09:14
-
@ocroquette I'm not sure where you're seeing inconsistent digits in the output from above. `$ED` is going to be fixed at ten-digits since the output is a 32-bit string. Which should hold you till the year 2038 (https://en.wikipedia.org/wiki/Year_2038_problem) – Signal15 Nov 18 '15 at 18:22
-
@Signal15 like I said, at first it seemed to work, even though it wasn't neither seconds nor milliseconds. Then at some point for an unknown reason, the unit changed, and I got milliseconds. It looks like the problem lazlev had above. – ocroquette Nov 19 '15 at 17:31
-
1Problem is the cast. `Get-Date(Get-Date).ToUniversalTime() -uformat "%s"` returns `1448965807,05586` while `[decimal](Get-Date(Get-Date).ToUniversalTime() -uformat "%s")` return `144896580705586`. I recommend Keith Hills answer instead, it works and it is much more clear what happens. – hvidgaard Dec 01 '15 at 10:32
Not sure when -UFormat
was added to Get-Date
but it allows you to get the date and time in UNIX epoch timestamp format:
[int64](Get-Date -UFormat %s)
It's supported by both the PowerShell and PowerShell Core.

- 23,966
- 9
- 79
- 68

- 906
- 7
- 23
-
-
1`-uformat %s` is there in PS 5.1, not sure about earlier versions, so at least since Jan 2017 – Jason S May 12 '20 at 02:01
-
7`[int64](Get-Date(Get-Date).ToUniversalTime() -UFormat %s)` fixes the timestamp when you are not in UTC timezone. – bitdancer Dec 14 '20 at 22:02
-
Does already exist in Powershell 3.0: https://learn.microsoft.com/fr-fr/previous-versions/powershell/module/microsoft.powershell.utility/get-date?view=powershell-3.0 – usilo Sep 27 '21 at 20:04
-
This one-liner works for me (compared it to http://www.unixtimestamp.com/)
[int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds
For milliseconds
[int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalMilliseconds

- 2,246
- 2
- 28
- 40
-
-
2Your cast to int64 is unnecessary as that's already the type. – Maximilian Burszley Jun 11 '18 at 16:46
-
@MaximilianBurszley I cannot confirm this. `(([datetime]::UtcNow)-(get-date "1/1/1970")).TotalMilliseconds | Get-Member` yields `TypeName: System.Double` in my PowerShell version and displays a decimal value. – jansohn Feb 03 '21 at 08:18
To get seconds since 1970 independent of time zone, I would go with:
$unixEpochStart = new-object DateTime 1970,1,1,0,0,0,([DateTimeKind]::Utc)
[int]([DateTime]::UtcNow - $unixEpochStart).TotalSeconds

- 194,368
- 42
- 353
- 369
I just wanted to present yet another, and hopefully simpler, way to address this. Here is a one liner I used to obtain the current Unix(epoch) time in UTC:
$unixTime = [long] (Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s)
Breaking this down from the inside out:
(Get-Date).ToUniversalTime()
This gets the current date/time in UTC time zone. If you want the local time, just call Get-Date. This is then used as input to...
[long] (Get-Date -Date (UTC date/time from above) -UFormat %s)
Convert the UTC date/time (from the first step) to Unix format. The -UFormat %s tells Get-Date to return the result as Unix epoch time (seconds elapsed since January 01, 1970 00:00:00). Note that this returns a double data type (basically a decimal). By casting it to a long data type, it is automatically converted (rounded) to a 64-bit integer (no decimal). If you want the extra precision of the decimal, don't cast it to a long type.
Extra credit
Another way to convert/round a decimal number to a whole number is to use System.Math:
[System.Math]::Round(1485447337.45246)

- 297
- 4
- 10
-
Slow - you call `get-date` more than once, while you can address a `[DateTime]::Now` or `[DateTime]::UtcNow` to get current date, the use the cmdlet just for formatting, which is also not without a caveat - non-english local culture might return an incorrent conversion result. – Vesper Feb 03 '21 at 07:16
-
Powershell
$epoch = (Get-Date -Date ((Get-Date).DateTime) -UFormat %s)

- 17,050
- 1
- 20
- 48

- 185
- 1
- 6
-
Would you be able to help me out with using this in an Invoke-Expression Cmdlet ? I receive the following error ...Unexpected token '-Uformat' in expression or statement. At line:1 char:219 + ... meUtc -Uformat %s}},@{e={$_.Length}} -AutoSize | Out-String -Width 5000 + ~~ Unexpected token '%s' in expression or statement. I have posted a question on stackoverflow and I can link you to that for more information. – Dhiwakar Ravikumar Dec 03 '18 at 15:27
-
This is quite inefficient. `(Get-Date).DateTime` returns a string, which then has to be parsed again by the second call to `Get-Date -Date` (and string parsing dates is slow). – gregmac Feb 04 '20 at 15:18
-
And it's not even necessary to pass the current date and time in the `-Date` parameter because when the parameter is omitted, the cmdlet is actually using the current date and time! The parameter is needed only when you need to specify a different time than the current one. So the correct and efficient version is `Get-Date -UFormat %s`. The result is same. – David Ferenczy Rogožan Aug 13 '21 at 14:05
For sending data to Grafana I needed the Unix Epoch time as 32 bit Integer from UTC. The best solution in the end was this:
$unixtime = (get-date -Date (get-date).ToUniversalTime() -UFormat %s).Substring(0,10)
This results in a string, but can easy converted to an integer:
[int]$unixtime = (get-date -Date (get-date).ToUniversalTime() -UFormat %s).Substring(0,10)
I tested this against an Ubuntu machine. The results from the commands above and the Linux command
date +%s
are identically.

- 41
- 1
I suggest the following, which is based on ticks (Int64), rather than seconds (Int32), to avoid the Year 2038 problem. [Math]::Floor is used, as Unix time is based on the number of whole seconds since the epoch.
[long][Math]::Floor((($DateTime.ToUniversalTime() - (New-Object DateTime 1970, 1, 1, 0, 0, 0, ([DateTimeKind]::Utc))).Ticks / [timespan]::TicksPerSecond))

- 336
- 5
- 8
-
-
@thund: `$DateTime` must be set to a valid date-time before executing the above, e.g. call `$DateTime = Get-Date` then the above script. – Gary Pendlebury Sep 14 '17 at 14:20
-
Yes, that works. I didn't notice the undefined variable. I just lazily assumed my version of powershell didn't like it for some other reason. – thund Sep 14 '17 at 17:50
-
Note that the floor function doesn't return an integer type; it's still whatever type [timespan]::TicksPerSecond is, which probably means double. – Johan Boulé Sep 23 '18 at 13:55
-
johan-boulé: That's true, which is why the output from `[Math]::Floor` is cast to `long`. – Gary Pendlebury Sep 23 '18 at 14:04
Here's a script which converts both TO and FROM CTIME that I've been using for a while (longer, because it was written for a "new to scripting" type crowd, with various comments.
# Here's a very quick variant to 'get the job done'
[Int64]$ctime=1472641743
[datetime]$epoch = '1970-01-01 00:00:00'
[datetime]$result = $epoch.AddSeconds($Ctime)
write-host $result
# A few example values for you to play with:
# 1290100140 should become ... 2010-11-18 17:09:00.000
# 1457364722 should become ... 2016-03-07 15:32:02.000
# 1472641743 should become ... 31/08/2016 11:09:03
# For repeated use / calculations, functions may be preferable. Here they are.
# FROM C-time converter function
# Simple function to convert FROM Unix/Ctime into EPOCH / "friendly" time
function ConvertFromCtime ([Int64]$ctime) {
[datetime]$epoch = '1970-01-01 00:00:00'
[datetime]$result = $epoch.AddSeconds($Ctime)
return $result
}
# INTO C-time converter function
# Simple function to convert into FROM EPOCH / "friendly" into Unix/Ctime, which the Inventory Service uses.
function ConvertToCTime ([datetime]$InputEpoch) {
[datetime]$Epoch = '1970-01-01 00:00:00'
[int64]$Ctime = 0
$Ctime = (New-TimeSpan -Start $Epoch -End $InputEpoch).TotalSeconds
return $Ctime
}
Hope that helps, especially if you just want something that's a little friendlier for beginners or so :).

- 95
- 2
- 9
Below cmdlet will convert the windows uptime into Unix understandable epoch time format:
$s=Get-WmiObject win32_operatingsystem | select csname,@{LABEL='LastBootUpTime';EXPRESSION{$_.ConverttoDateTime($_.lastbootuptime)}};
[Math]::Floor([decimal](Get-Date($s.LastBootUpTime.ToUniversalTime()).ToUniversalTime()-uformat "%s"))

- 107
- 3
- 8
-
An uptime is a duration, not a date. Seems Microsoft messed up the terminology. – Johan Boulé Sep 23 '18 at 14:07
Again comparing to http://www.unixtimestamp.com and building on others above
$date1 = (Get-Date -Date "01/01/1970").ToUniversalTime()
$date2 = (Get-Date).ToUniversalTime()
$epochTime = [Math]::Floor((New-TimeSpan -Start $date1 -End $date2).TotalSeconds)

- 637
- 4
- 11
This one should also work since javascript uses milliseconds since epoch :
ConvertTo-Json (Get-Date) | ? { $_ -Match '\(([0-9]+)\)' } | % { $Matches[1]/1000 }
Step by Step :
PS P:\> Get-Date
lundi 15 janvier 2018 15:12:22
PS P:\> ConvertTo-Json (Get-Date)
{
"value": "\/Date(1516025550690)\/",
"DisplayHint": 2,
"DateTime": "lundi 15 janvier 2018 15:12:30"
}
PS P:\> (ConvertTo-Json (Get-Date)) -Match '\(([0-9]+)\)'
True
PS P:\> $Matches
Name Value
---- -----
1 1516025613718
0 (1516025613718)

- 300
- 3
- 8
-
2That's got to be the most obfuscated and fragile way to do it. M'enfin! – Johan Boulé Sep 23 '18 at 14:01
You can use the Uformat parameter of get-date. But first I like to be sure the date of a given workstation is correct (I consider a workstation connected to a company network where there is a server with a correct time set).
#Synchronize workstation time with server
cmd /c "sc config w32time start= auto"
cmd /c "w32tm /unregister"
cmd /c "w32tm /register"
cmd /c "net start w32time"
cmd /c 'tzutil.exe /s "W. Europe Standard Time"'
cmd /c 'reg add "HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" /v DisableAutoDaylightTimeSet /t REG_DWORD /d 0 /f'
cmd /c "net time \\full-servername.ru /set /yes"
Then I get the actual unix timestamp to compare objects (accounts) between actual date and creation date (account deletion tasks when unix timestamp exceeds limit date)
#Get actual unix timestamp and compare it to something
$actual_date = (get-date -UFormat "%s")
$final_date = "some unix date of the database"
if(($final_date - $actual_date) -lt 0 ){
#make deletion task
}

- 525
- 7
- 15
Signal15's answer is a bit verbose for me. I did it this way:
[int] (Get-Date (Get-Date).ToUniversalTime() -uformat '%s')

- 5,935
- 6
- 39
- 48
Late answer...
Hare are both convert functions ConvertTo-UnixTime
& ConvertFrom-UnixTime
for convenience (both pipeline capable)
function ConvertFrom-UnixTime () {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline, Position = 0)]
[Int64]$UnixTime
)
begin {
$epoch = [DateTime]::SpecifyKind('1970-01-01', 'Utc')
}
process {
$epoch.AddSeconds($UnixTime)
}
}
function ConvertTo-UnixTime {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline, Position = 0)]
[DateTime]$DateTime
)
begin {
$epoch = [DateTime]::SpecifyKind('1970-01-01', 'Utc')
}
process {
[Int64]($DateTime.ToUniversalTime() - $epoch).TotalSeconds
}
}

- 15,079
- 5
- 45
- 61
A culture-independent, and actually pretty fast answer:
[int64]([double]::Parse((get-date -uformat "%s"),[cultureinfo][system.threading.thread]::currentthread.currentculture))
This invokes some .NET "magic" when it comes to actually produce a formatted string, it gets converted to double using current thread's culture settings, then it converts to int64 which by default does exactly floor the double provided. Should you desire a UTC timestamp, use -date ([DateTime]::UtcNow)
in get-date
to use current UTC time as the time to convert.
[int64]([double]::Parse((get-date -date ([DateTime]::UtcNow) -uformat "%s"),[cultureinfo][system.threading.thread]::currentthread.currentculture))
PS: Unless you really need a string as your output, having an integer is overall better to your programming culture.

- 18,599
- 6
- 39
- 61
tested work well with different timezone:
(Get-Date).ToUniversalTime().Subtract((Get-Date "01/01/1970")).Totalseconds
# or
[DateTimeOffset]::Now.ToUnixTimeSeconds()
below is NOT recommend because it only works on timezone GMT+0
Get-Date -UFormat %s
BTW, we can also verify the EPOCH UNIX time if you installed python:
python -c "import time;print(time.time())"

- 41
- 3
If anyone is interested in getting milliseconds since Unix epoch, my approach is something like this
[int](Get-Date -UFormat %s) * 1000 + (Get-Date).Millisecond

- 905
- 11
- 28