銀月の符号

Python 使い見習いの日記・雑記

レシピ編集、文字列を日時に変換する

Python レシピ「198:文字列を日時に変換する」を編集。ここで Ruby が 'H21.01.29 0:21' のような和暦を読み込めることを知る。

irb(main):001:0> require "date"
=> true
irb(main):002:0> DateTime.parse('H21.01.29 0:21').to_s
=> "2009-01-29T00:21:00+00:00"

これは Python で再現せねば、と思った。今思い返すと理由は不明。なんで夢中になってたんだろう? ともかく、30分ほどでそれっぽいコードが完成。 re.VERBOSE をつかった正規表現は見たことはあったけれど、書いたのは始めて。これは便利と認識を改めた、そんな日。

import re
import datetime

_wareki = re.compile(ur'''
        (?P<gengou>[MTSH])
        (?P<year>\d+)
        \.
        (?P<month>\d{1,2})
        \.
        (?P<date>\d{1,2})
        (
          .+?
          (?P<hour>\d{1,2})
          (
            .*?:.*?
            (?P<minite>\d{1,2})
            (
                .*?:.*?
                (?P<second>\d{1,2})
            )?
          )?
        )?
        ''',
        re.VERBOSE | re.IGNORECASE)
_gengou = {'M': 1867, 'T': 1911, 'S': 1925, 'H': 1988}
def wareki(s):
    mo = _wareki.match(s)
    if mo:
        year = int(mo.group('year')) + _gengou[mo.group('gengou').upper()]
        month = int(mo.group('month'))
        date = int(mo.group('date'))
        hour = mo.group('hour')
        hour = int(hour) if hour else 0
        minite = mo.group('minite')
        minite = int(minite) if minite else 0
        second = mo.group('second')
        second = int(second) if second else 0
        return datetime.datetime(year, month, date, hour, minite, second)
    return None
>>> import wareki
>>> wareki.wareki(u'H21.01.29')
datetime.datetime(2009, 1, 29, 0, 0)
>>> wareki.wareki(u'H21.01.29 0')
datetime.datetime(2009, 1, 29, 0, 0)
>>> wareki.wareki(u'H21.01.29 0:21')
datetime.datetime(2009, 1, 29, 0, 21)
>>> wareki.wareki(u'H21.01.29 0:21:5')
datetime.datetime(2009, 1, 29, 0, 21, 5)