簡體   English   中英

在 PowerShell 中,如何將 DateTime 轉換為 UNIX 時間?

[英]In PowerShell, how do I convert DateTime to UNIX time?

在 PowerShell 中,如何將 DateTime 字符串轉換為秒的總和?

PS H:\> (New-TimeSpan -Start $date1 -End $date2).TotalSeconds

1289923177.87462

可以使用 New-TimeSpan 來做到這一點。 例如,

$date1 = Get-Date -Date "01/01/1970"
$date2 = Get-Date
(New-TimeSpan -Start $date1 -End $date2).TotalSeconds

或者只使用這一行命令

(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalSeconds

如前所述,UNIX 時代是UTC 時間1970 年 1 月 1 日凌晨 12:00(午夜)。 要以整數形式獲取 UTC 中的當前秒數,我使用了這個 80 個字符的單行

$ED=[Math]::Floor([decimal](Get-Date(Get-Date).ToUniversalTime()-uformat "%s"))

上面的代碼符合 PowerShell 2.0 並向下舍入(以確保與 UNIX 的行為一致)

使用 .NET Framework 4.6,您可以使用DateTimeOffset類的ToUnixTimeSeconds方法:

[DateTimeOffset]::Now.ToUnixTimeSeconds()

$DateTime = Get-Date #or any other command to get DateTime object
([DateTimeOffset]$DateTime).ToUnixTimeSeconds()

這個單線對我有用(與http://www.unixtimestamp.com/相比)

[int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds

毫秒

[int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalMilliseconds

要獲得自 1970 年以來獨立於時區的秒數,我會選擇:

$unixEpochStart = new-object DateTime 1970,1,1,0,0,0,([DateTimeKind]::Utc)
[int]([DateTime]::UtcNow - $unixEpochStart).TotalSeconds

不確定何時將-UFormat添加到Get-Date但它允許您以 UNIX 紀元時間戳格式獲取日期和時間:

[int64](Get-Date -UFormat %s)

PowerShell 和 PowerShell Core 都支持它。

我只是想提出另一種希望更簡單的方法來解決這個問題。 這是我用來獲取當前 Unix(epoch) UTC 時間的單行代碼:

$unixTime = [long] (Get-Date -Date ((Get-Date).ToUniversalTime()) -UFormat %s)

從內到外分解:

(Get-Date).ToUniversalTime()

這將獲取 UTC 時區的當前日期/時間。 如果您想要本地時間,只需調用Get-Date 然后將其用作...的輸入

[long] (Get-Date -Date (UTC date/time from above) -UFormat %s)

將 UTC 日期/時間(從第一步開始)轉換為 Unix 格式。 -UFormat %s告訴Get-Date將結果返回為 Unix 紀元時間(自 1970 年 1 月 1 日 00:00:00 起經過的秒數)。 請注意,這將返回雙精度數據類型(基本上是十進制)。 通過將其轉換為long數據類型,它會自動轉換(四舍五入)為 64 位整數(無小數)。 如果您想要小數的額外精度,請不要將其強制轉換為long類型。

額外學分

另一種將十進制數轉換/四舍五入為整數的方法是使用System.Math

[System.Math]::Round(1485447337.45246)

電源外殼

$epoch = (Get-Date -Date ((Get-Date).DateTime) -UFormat %s)

我建議以下基於刻度 (Int64) 而不是秒 (Int32) 的方法,以避免出現 2038 年問題。 使用 [Math]::Floor,因為 Unix 時間基於自紀元以來的整秒數。

[long][Math]::Floor((($DateTime.ToUniversalTime() - (New-Object DateTime 1970, 1, 1, 0, 0, 0, ([DateTimeKind]::Utc))).Ticks / [timespan]::TicksPerSecond))

這是一個腳本,它同時轉換 TO 和 FROM CTIME,我已經使用了一段時間(更長的時間,因為它是為“腳本新手”類型的人群編寫的,並帶有各種注釋。

# 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
}

希望有所幫助,特別是如果您只是想要對初學者更友好的東西:)。

為了向 Grafana 發送數據,我需要 Unix Epoch 時間作為 UTC 的 32 位整數。 最后最好的解決方案是這樣的:

$unixtime = (get-date -Date (get-date).ToUniversalTime() -UFormat %s).Substring(0,10)

這會產生一個字符串,但可以輕松轉換為整數:

[int]$unixtime = (get-date -Date (get-date).ToUniversalTime() -UFormat %s).Substring(0,10)

我在 Ubuntu 機器上對此進行了測試。 以上命令和Linux命令的結果

date +%s

是相同的。

下面的 cmdlet 會將 Windows 正常運行時間轉換為 Unix 可理解的紀元時間格式:

   $s=Get-WmiObject win32_operatingsystem | select csname,@{LABEL='LastBootUpTime';EXPRESSION{$_.ConverttoDateTime($_.lastbootuptime)}};
   [Math]::Floor([decimal](Get-Date($s.LastBootUpTime.ToUniversalTime()).ToUniversalTime()-uformat "%s"))

再次比較http://www.unixtimestamp.com並建立在上面的其他人的基礎上

$date1 = (Get-Date -Date "01/01/1970").ToUniversalTime()
$date2 = (Get-Date).ToUniversalTime()
$epochTime = [Math]::Floor((New-TimeSpan -Start $date1 -End $date2).TotalSeconds)

這個也應該有效,因為 javascript 使用自 epoch 以來的毫秒數:

ConvertTo-Json (Get-Date) | ? { $_ -Match '\(([0-9]+)\)' } | % { $Matches[1]/1000 }

一步步 :

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)

您可以使用 get-date 的 Uformat 參數。 但首先我想確定給定工作站的日期是正確的(我認為工作站連接到公司網絡,其中有一台服務器設置了正確的時間)。

#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"  

然后我得到實際的unix時間戳來比較實際日期和創建日期之間的對象(帳戶)(unix時間戳超過限制日期時的帳戶刪除任務)

#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
}

Signal15 的回答對我來說有點冗長。 我是這樣做的:

[int] (Get-Date (Get-Date).ToUniversalTime() -uformat '%s')

遲到的回答...

為了方便起見,Hare 都是轉換函數ConvertTo-UnixTimeConvertFrom-UnixTime (都支持管道)

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
    }
}

一個獨立於文化的,實際上非常快的答案:

[int64]([double]::Parse((get-date -uformat "%s"),[cultureinfo][system.threading.thread]::currentthread.currentculture))

在實際生成格式化字符串時,這會調用一些 .NET“魔法”,使用當前線程的區域性設置將其轉換為雙精度值,然后轉換為 int64,默認情況下它會完全滿足所提供的雙精度值。 如果您需要 UTC 時間戳,請在get-date使用-date ([DateTime]::UtcNow)以使用當前 UTC 時間作為轉換時間。

[int64]([double]::Parse((get-date -date ([DateTime]::UtcNow) -uformat "%s"),[cultureinfo][system.threading.thread]::currentthread.currentculture))

PS:除非你真的需要一個字符串作為你的輸出,否則有一個整數對你的編程文化來說總體上更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM