Skip to content

Instantly share code, notes, and snippets.

@ooltcloud
Created December 5, 2018 10:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ooltcloud/620831658a0cd9055f53ae3ba3543ee1 to your computer and use it in GitHub Desktop.
Save ooltcloud/620831658a0cd9055f53ae3ba3543ee1 to your computer and use it in GitHub Desktop.
Powershell と NTP を使用した簡易時刻同期 (udp の ntp プロトコル使用)
#--------------
# NTP 時刻合わせ (NTP UDP:123)
#--------------
# NTP 積算秒数の起点時刻 (JST)
$ntpEpoch = New-Object System.Datetime @(1900, 1, 1, 9, 0, 0)
# Big Endian の符号なし Int32 を取得
Function getUInt32BE($bytes, $startIndex) {
# BE→LE 変換
$a = $bytes[($startIndex + 3) .. $startIndex]
# UInt32 取得
$b = [System.BitConverter]::ToUInt32($a, 0)
return $b
}
# 固定小数点(整数部 32bit / 小数部 32bit) を取得
Function getFixedPointDecimal3232($bytes, $startIndex) {
# 整数部取得
$int = getUInt32BE $bytes $startIndex
# 小数部取得
$dec = getUInt32BE $bytes ($startIndex + 4)
# 合成
$value = $int + $dec * [Math]::Pow(2,-32)
return $value
}
# タイムスタンプ値から JST を求める
Function getJST($timeSerial) {
$date = $ntpEpoch.AddSeconds($timeSerial)
return $date
}
# 送信電文作成
Function getSendBytes() {
$buf = @()
# header
$li = 0 # 空設定
$vn = 3 # Version 3
$mode = 3 # Client Mode
$buf += [byte](($li -shl 6) + ($vn -shl 3) + $mode)
# stratum
$buf += [byte]0 # 空設定
# poll
$buf += [byte]0 # 空設定
# precision
$buf += [byte]0 # 空設定
# RootDelay
$buf += @([Byte]0) * 4 # 空設定
# RootDispersion
$buf += @([Byte]0) * 4 # 空設定
# ReferenceID
$buf += @([Byte]0) * 4 # 空設定
# Reference Timestamp
$buf += @([Byte]0) * 8 # 空設定
# Origin Timestamp
$buf += @([Byte]0) * 8 # 空設定
# Receive Timestamp
$buf += @([Byte]0) * 8 # 空設定
# Transmit Timestamp
$buf += @([Byte]0) * 8 # 空設定
return $buf
}
# NTP サーバーと通信
Function inquiryNTP($ntpServerAddress, $sendBytes)
{
$udp = New-Object Net.Sockets.UdpClient
$udp.Client.ReceiveTimeout = 2000
try
{
# UDP Port 123 に送信
$a = $udp.Send($sendBytes, $sendBytes.Length, $ntpServerAddress, 123)
# 応答を受信
$recvBytes = $udp.Receive([ref]$null)
# 終了
$udp.Close()
return $recvBytes
} catch {
Throw
} finally {
$udp.Dispose()
}
}
# 受信電文解析
Function getResult($recvBytes) {
# 初期化
$result = @{}
# Transmit Timestamp
$ts = getFixedPointDecimal3232 $recvBytes 40
$jst = getJST $ts
return $jst
}
# 時刻設定 (応答送信時刻に合わせます)
Function SetNTPDate($ntpServerAddress) {
try {
$send = getSendBytes
$recv = inquiryNTP $ntpServerAddress $send
$result = getResult $recv
} catch {
Throw
}
# 時刻設定
Set-Date -Date $result
}
# 実行
SetNTPDate "ntp.nict.jp"
@ooltcloud
Copy link
Author

ooltcloud commented Dec 5, 2018

 類似品。https://gist.github.com/ooltcloud/20e7d7551007370b4b8e345499d79cb3
 上記で「いやそうじゃない、http じゃなくて ntp のままサクッと時刻合わせがしたいんである」という人向け。
 そういうひとは桜時計( https://www.vector.co.jp/soft/win95/personal/se050672.html ) を使えって話なんだけども、実行または常駐しているのが見えるのは嫌だとか Windows 標準機能でなんとかならないか(フリーソフトは持ち込めない)という人向け。
 そんなニーズがあるのかどうかは知らないが(汗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment