46

I'm trying to create a DateTime object with a specific UTC timestamp in PowerShell. What's the simplest way to do this?

I tried:

Get-Date
    -Format (Get-Culture).DateTimeFormat.UniversalSortableDateTimePattern
    -Date "1970-01-01 00:00:00Z"

but I get this output:

1969-12-31 19:00:00Z

It's a few hours off. Where's my lapse in understanding?

sourcenouveau
  • 29,356
  • 35
  • 146
  • 243

6 Answers6

53

The DateTime object itself is being created with the proper UTC time. But when PowerShell prints it out it converts it to my local culture and time zone, thus the difference.

Proof:

$UtcTime = Get-Date -Date "1970-01-01 00:00:00Z"
$UtcTime.ToUniversalTime()
sourcenouveau
  • 29,356
  • 35
  • 146
  • 243
  • 1
    disproof: $UtcTime.Kind I mean, when you pass it to some other function - in most cases it will treat it as a local time, because this is what is actually stored. And PowerShell does not converts it to your local time when prints... Otherwise your ToUniversalTime() also would be local – Dmitry Gusarov Mar 09 '17 at 14:55
  • 4
    `Get-Date` converts the given UTC time to local time and stores it as a `datetime` object with `Kind` set to `Local`. It does store the correct physical point in time, but it is a local time and will be printed in local time. Note that this still IS a correct answer to the question. OP did not specifically ask for creating a `datetime` object with kind UTC. Upvoted. – Florian Winter May 26 '17 at 08:09
  • 1/1/70 12:00:00 AM Why does it not show the year? – Golden Lion Dec 23 '20 at 17:58
27
(get-date).ToUniversalTime().ToString("yyyyMMddTHHmmssfffffffZ")
2Toad
  • 14,799
  • 7
  • 42
  • 42
Ryker Abel
  • 599
  • 5
  • 4
  • 2
    The ToString value should support 24 hours, so it should have capital HH: `.ToString("yyyyMMddTHHmmssfffffffZ")` eg. 02:00:00PM should become ..140000 since UTC is timezone-agnostic – Anders Rask Jan 12 '15 at 14:43
  • This works great! `PowerShell -NoProfile -ExecutionPolicy Bypass -Command "((get-date).ToUniversalTime()).ToString(\"yyyy-MM-ddTHH:mm:ss+0000\")"` – Jay Taylor Nov 17 '16 at 19:42
  • Thank you. Finding this was surprisingly time-consuming. – Charles Burns Jan 13 '21 at 19:50
16
$utctime = New-Object DateTime 1970, 1, 1, 0, 0, 0, ([DateTimeKind]::Utc)

If you print out $utctime, then you get:

1. januar 1970 00:00:00

Also, $utctime.Kind is correctly set to Utc.

Florian Winter
  • 4,750
  • 1
  • 44
  • 69
8
$time = [DateTime]::UtcNow | get-date -Format "yyyy-MM-ddTHH:mm:ssZ"

This appears to also work

user8691702
  • 81
  • 1
  • 1
  • 1
    `[DateTime]::UtcNow.ToString('u')` is a better choice as those `MM` and `mm` might be misspelled. I filed such a bug in a system the other month. – LosManos Oct 04 '18 at 11:40
4

You can use the SpecifyKind method:

PS C:\IT\s3> $timestamp

Wednesday, July 18, 2018 7:57:14 PM

PS C:\IT\s3> $timestamp.kind

Unspecified

PS C:\IT\s3> $utctimestamp = [DateTime]::SpecifyKind($timestamp,[DateTimeKind]::Utc)

PS C:\IT\s3> $utctimestamp

Wednesday, July 18, 2018 7:57:14 PM

PS C:\IT\s3> $utctimestamp.kind

Utc

hotch
  • 41
  • 1
0

This is how it works in .NET, right? PowerShell just calls the ToUniversalTime method. From http://msdn.microsoft.com/en-us/library/system.datetime.touniversaltime.aspx

The Coordinated Universal Time (UTC) is equal to the local time minus the 
UTC offset. For more information about the UTC offset, see TimeZone.GetUtcOffset.
The conversion also takes into account the daylight saving time rule that applies 
to the time represented by the current DateTime object. 
Shay Levy
  • 121,444
  • 32
  • 184
  • 206