Nekoya Press

2013-06-10 Mon 10:33

本当は怖いstrptimeと%Y%m%dの関係

「%Y%m%d」をstrptimeで処理すると曖昧になることを今更ながらに知りました。

社内で「201312」を渡すとキモいという話が出て、

ってPostしたら@hirataraさんが「2013129と2013130もキモいぞ」と教えてくれました。

普段は%Y-%-%dを使うんだけど、URLに日付を埋め込む場合はデリミタ無しの方が自然だなーと思ったらご覧の有様だよ。

Python2.7.1

>> datetime.strptime('201312', '%Y%m%d')
datetime.datetime(2013, 1, 2, 0, 0)
>> datetime.strptime('2013129', '%Y%m%d')
datetime.datetime(2013, 12, 9, 0, 0)
>> datetime.strptime('2013130', '%Y%m%d')
datetime.datetime(2013, 1, 30, 0, 0)

なお、Pythonだけでなく他の言語でも見事にバラバラでワロタ。それぞれ最新版じゃないけど、そう変わらない気がする。

Perl5.12.2 Time::Piece

$ perl -MTime::Piece -le 'print localtime->strptime("201312", "%Y%m%d")'
Sun Dec  1 00:00:00 2013
$ perl -MTime::Piece -le 'print localtime->strptime("2013129", "%Y%m%d")'
Mon Dec  9 00:00:00 2013
$ perl -MTime::Piece -le 'print localtime->strptime("2013130", "%Y%m%d")'
Error parsing time at /Users/ryo/perl5/perlbrew/perls/perl-5.12.2/lib/5.12.2/darwin-2level/Time/Piece.pm line 469.

PHP5.3.15

$ php -r 'var_dump(new DateTime("201312"));'
object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2013-06-10 20:13:12"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(10) "Asia/Tokyo"
}
$ php -r 'var_dump(new DateTime("2013129"));'
object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2013-05-09 00:00:00"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(10) "Asia/Tokyo"
}
$ php -r 'var_dump(new DateTime("2013130"));'
object(DateTime)#1 (3) {
  ["date"]=>
  string(19) "2013-05-10 00:00:00"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(10) "Asia/Tokyo"
}

Ruby1.9.3p194

% irb
irb(main):001:0> require 'date'
=> true
irb(main):002:0> Date.strptime('201312', '%Y%m%d').to_s
ArgumentError: invalid date
        from (irb):2:in `strptime'
        from (irb):2
        from /Users/ryo/.rbenv/versions/1.9.3-p194/bin/irb:12:in `<main>'
irb(main):003:0> Date.strptime('2013129', '%Y%m%d').to_s
=> "2013-12-09"
irb(main):004:0> Date.strptime('2013130', '%Y%m%d').to_s
ArgumentError: invalid date
        from (irb):4:in `strptime'
        from (irb):4
        from /Users/ryo/.rbenv/versions/1.9.3-p194/bin/irb:12:in `<main>'

%Y%m%dを取る場合は、strptime任せにせず自分でフォーマットのチェックもしておかないと危険ですね。もしくは、おとなしくデリミタ挟むか。

nekoya.github.io