Home > Net >  Get epoch time with fractions of a second PowerShell
Get epoch time with fractions of a second PowerShell

Time:02-04

I'm working with an API which I know requires a timestamp that can be successfully produced with the following line of python: str(int(1000000 * datetime.datetime.utcnow().timestamp()))

This looks like it takes a Unix epoch time (with fractions of a second in the decimal place) and multiplies it by 1000000.

My problem in powershell is that I dont know how to get the same 6 decimal places returned by Python:

datetime.datetime.utcnow().timestamp()
1643941678.401823

In PowerShell I can do

Get-Date   -UFormat %s 
1643920137  

But, this only gives me the epoch with no decimal places.

Is there any way to get the same value with decimals as returned by the Python code in PowerShell?

Also it looks like the values returned by powershell are even more off, I ran those commands within seconds and they are off by 20,000 seconds? Anyone have any idea why theres such a big time difference?

CodePudding user response:

To get the current point in time's epoch time as a seconds-with-fractions value with the full resolution that the .NET [datetime] type offers, i.e. 100-nanosecond intervals:

[decimal] ([datetime]::UtcNow - [datetime] '1970-01-01Z').Ticks / 1e7

In PowerShell (Core) 7 (.NET (Core) 2.1 ), you can simplify to:

[decimal] ([datetime]::UtcNow - [datetime]::UnixEpoch).Ticks / 1e7

The result is a [decimal] instance with 6 decimal places; e.g., 1643939471.006042

This should match the output from your Python (v3 ) command, assuming you fix it by replacing .utcnow() with .now():

# Note: Use .now(), not .utcnow() - the latter seemingly causes
#       .timestamp() to misinterpret the UTC point in time as a *local* one.
python3 -c "import datetime; print(str(datetime.datetime.now().timestamp()))

If millisecond resolution is sufficient, a simpler solution, via the [datetimeoffset] type, is possible:

[decimal] [datetimeoffset]::UtcNow.ToUnixTimeMilliseconds() / 1e3

An aside re Get-Date -UFormat %s:

  • Since the purpose of Get-Date's -Format / -UFormat parameters is to produce a formatted string representation, the return value is indeed a string rather than a number. And, as shown in your question, in PowerShell (Core) 7 , with -UFormat %s this string represents an integer (whole-seconds) values.

  • In Windows PowerShell (the legacy PowerShell edition whose latest and last version is 5.1) the value represented by the output string actually is a fractional value, but it is flawed in two respects:

    • The value returned is only correct if you pass a [datetime] instance that represents a UTC point in time explicitly (i.e. an instance whose .Kind property is Utc, such as obtained with [datetime]::UtcNow).

    • The string representation is culture-sensitive, so that in certain cultures , rather than . is used as the decimal mark.

    • See this answer for details.

  •  Tags:  
  • Related