Firewall に囲まれてて NTP が通らないので書いた。
HTTP(S)で日本標準時を文字列で返してくれるサービスが提供されているのでそちらを利用、対象 OS が Linux 系なら wget を使えばいいけど Windows にはそんなものは(標準では)無いので PowerShell から .NET を呼び出してどうにかする。
コード
# 管理者権限で実行すること
$ntpdatestring = (new-object System.Net.WebClient).DownloadString("http://ntp-a1.nict.go.jp/cgi-bin/time").Replace(" JST", " +0900").Trim()
$datetime = [DateTime]::ParseExact($ntpdatestring, "ddd MMM dd HH:mm:ss yyyy zzzz", [Globalization.CultureInfo]::CreateSpecificCulture("en-US"))
set-date $datetime
あとはタスクスケジューラにぶち込んだりすれば良いのでは。定時ダッシュの精度が高まりますね
実装時にはまった点
PowerShell 初めて書いた& そもそも .NET あんまり知らんのでそもそも全部ハマっ
WebClient#DownloadString() が 返す文字列の後ろに謎の改行文字が入ってることに気付かなくてパース出来なかった
DateTime#ParseExact() の時にロケール…じゃなくてカルチャに en-US を指定をしないといけない(自環境だとデフォルトのカルチャが ja-JP になるので ddd は "日曜" だの "月曜" だのが有効な値、"Sun" やら "Mon" は認識出来ない)ことに気付くのに大分時間が掛かった
NTPリソース
日本標準時プロジェクト 公開NTP サービス対応クライアントリスト
日本標準時プロジェクト https/http を介してアクセスされる場合
/cgi-bin/time は RFC1123 形式っぽいけど少し違う
/cgi-bin/ntp と /cgi-bin/jst は text/plain じゃないのでアレ
環境
OS: Windows 7 Pro
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.PS C:\> $PSVersionTable
Name Value
CLRVersion 2.0.50727.5485
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
書いてから気付いたけど PowerShell で JSON 読めるならそれ使ったほうが楽だったのでは…?
→ JSON 使えるやん…
→ PowerShell 3.0 からだった。Windows 7 デフォルトは V2 なのである意味セーフ
st に UNIX 時間が入ってるから new DateTime(1970, 1, 1, 9, 0, 0) に AddSeconds() で良いのかなー