やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

現在日時文字列を取得する方法

現在日時文字列を取得する方法について調べてみた。

対象環境

コマンドライン

文脈 コマンド
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日"
129

おそらく、MinGW/msysのdateコマンドは、ANSI(2バイト文字コード)で出力するのだと思われる。ConEmu(Nyagos)はコンソール環境をUTF-8にしたため、日本語を含む出力がエラーになったのだろう。

所感

たかが日時文字列を取得するごときで面倒が多すぎる。GoogleIMEならきょうと入力して変換すれば一発なのに。でも、GoogleIMEは重い。

PowerShell(.NET Framework)は和暦も表示できるため別格。起動時間の遅さも別格だが。

それぞれの文脈、実装環境などに影響されて出力形式が異なる。また、フォーマット文字列もそれぞれ違う。そんなことを一々意識し、覚えて、使い分けてなどいられない。