現在日時文字列を取得する方法について調べてみた。
対象環境
- Windows XP Pro SP3 32bit
- cmd.exe
- PowerShell 2.0.50727.3655
- .NET Framework 4.0
- ConEmu
コマンドライン
文脈 | コマンド |
---|---|
MinGW/msys | date "+%Y%m%d%H%M%S%3N" |
cmd | bash -c 'date "+%Y%m%d%H%M%S%3N"' |
PowerShell | powershell.exe -Command "& {Get-Date -Format \"yyyyMMddHHmmssfff\"}" |
Google IME | きょう で変換すると候補に出る |
Windows特殊変数
こちらを参照。感謝。
>echo %date% 2016/12/09 >echo %time% 16:53:08.09
cmd.exe上でのみ参照可能な特殊変数。書式もWindowsのバージョンなどによって異なるらしい。
インタプリタ対話モード
Ruby
>irb irb(main):001:0> Time.now => 2016-12-09 16:20:06 +0900 irb(main):002:0> Time.now.strftime("%Y%m%d%H%M%S") => "20161209162012" irb(main):003:0> Time.now.strftime("%Y%m%d%H%M%S%L") => "20161209162253515" irb(main):004:0> Time.now.strftime("%-m%-d") => "129" irb(main):005:0> Time.now.strftime("%-m月%-d日") => "12月9日" irb(main):006:0> quit
Time.now.strftime("%-m%-d")
フォーマット文字列についてはこちらを参考。感謝。
Python
>>> import datetime >>> now = datetime.datetime.now() >>> "{0:%Y%m%d%H%M%S}".format(datetime.datetime.now()) '20161209162805' >>> "{0:%Y%m%d%H%M%S%f}".format(datetime.datetime.now()) '20161209162809687000'
秒以下の桁が6桁になってしまう。なのに3桁(ミリ秒)までしか保障されておらず、4,5,6桁目(マイクロ秒)が必ず0になってしまう。無駄。
>>> "%03d" % (datetime.datetime.now().microsecond // 1000) '515' >>> "{0:%Y%m%d%H%M%S}".format(now) + "%03d" % (now.microsecond // 1000) '20161209163442343'
microsecondはあるのに、millisecondはなかった。謎。こちらを参照した。感謝。
>>> "{0:%-m%-d}".format(datetime.datetime.now()) Traceback (most recent call last): File "<stdin>", line 1, in <module> >>> now.strftime('%m%d') '1209' >>> now.strftime('%-m%-d') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: Invalid format string >>> now.strftime('%m月%d日') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'locale' codec can't encode character '\u6708' in position 2 : Illegal byte sequence >>> now.strftime(u'%m月%d日') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'locale' codec can't encode character '\u6708' in position 2 : Illegal byte sequence >>> "{0:%m%d}".format(now) '1209' >>> "{0:%-m%-d}".format(now) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: Invalid format string >>> "{0:%m月%d日}".format(now) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'locale' codec can't encode character '\u6708' in position 2 : Illegal byte sequence >>> u"{0:%m月%d日}".format(now) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'locale' codec can't encode character '\u6708' in position 2 : Illegal byte sequence
%-m
のように-
をつけるとゼロ埋めをとってくれるはずだが、動作しない。実装依存らしい。こちらを参照した。感謝。
日本語を入れると動作しなくなる。
Rubyと比べて問題が多い。
dateコマンド
ConEmu(Nyagos)
$ date "+%Y%-m%d%H%M%S%3N" 20161209163641968\ $ date "+%-m%-d" 129 $ date "+%-m月%-d日" date: write error exit status 1
ConEmu(MinGW/msys)
$ date "+%Y%-m%d%H%M%S%3N" 20161209163748609 $ date "+%-m月%-d日" 12月9日
おそらく、MinGW/msysのdateコマンドは、ANSI(2バイト文字コード)で出力するのだと思われる。ConEmu(Nyagos)はコンソール環境をUTF-8にしたため、日本語を含む出力がエラーになったのだろう。
所感
たかが日時文字列を取得するごときで面倒が多すぎる。GoogleIMEならきょう
と入力して変換すれば一発なのに。でも、GoogleIMEは重い。
PowerShell(.NET Framework)は和暦も表示できるため別格。起動時間の遅さも別格だが。
それぞれの文脈、実装環境などに影響されて出力形式が異なる。また、フォーマット文字列もそれぞれ違う。そんなことを一々意識し、覚えて、使い分けてなどいられない。