つらい。
datetime.strptime
の中身見てみたらものすごい武闘派だったので早々に諦めて、
ざっくり欲しいとこだけ実装することにした。
いっそもう皇紀にしたらいいんじゃないかな。
jp_era.py
import datetime
class JpEra:
def __init__(self, shorthand, era_name, begin_date, end_date=datetime.date.max):
self.shorthand = shorthand
self.era_name = era_name
self.begin_date = begin_date
self.end_date = end_date
def in_term(self, target_date):
return self.begin_date <= target_date <= self.end_date
def jp_year(self, year):
return year - (self.begin_date.year - 1)
JP_ERA = (
JpEra("M", "明治", datetime.date(1868, 9, 8), datetime.date(1912, 7, 29)),
JpEra("T", "大正", datetime.date(1912, 7, 30), datetime.date(1926, 12, 24)),
JpEra("S", "昭和", datetime.date(1926, 12, 25), datetime.date(1989, 1, 7)),
JpEra("H", "平成", datetime.date(1989, 1, 8)),
)
def parse_jp_datetime(target_str, fmt='%y.%m.%d %H:%M'):
"""
'元年' がめんどくさいのでとりあえずショートハンドのみ
:target_str: 'H30.01.15 09:52'
:fmt:
:return: datetime.datetime
"""
x, xs = target_str[0], target_str[1:]
for era in JP_ERA:
if x != era.shorthand:
continue
# 2100年以降とか元号が3桁になったりするとおかしくなるけどまぁいいや
c = datetime.datetime.strptime(xs, fmt)
y = era.begin_date.year + c.year % 100 - 1
return datetime.datetime(y, c.month, c.day, c.hour, c.minute, c.second)
raise ValueError('unknown era `%s`.' % x)
def jp_era(target_date):
"""
:target_date: datetime.date(2018, 1, 15)
:return: (shorthand, era_name, jp_year)
"""
for era in JP_ERA:
if era.in_term(target_date):
return era.shorthand, era.era_name, era.jp_year(target_date.year)
raise ValueError('should not be reached here `%s`.' % target_date)
test_jp_era.py
import unittest
import datetime
from jp_era import *
class TestJpEra(unittest.TestCase):
def test_jp_era(self):
args_and_expects = [
[[datetime.date(2018, 1, 15)], ('H', '平成', 30)],
[[datetime.date(1989, 1, 7)], ('S', '昭和', 64)],
[[datetime.date(1989, 1, 8)], ('H', '平成', 1)],
]
for args, expect in args_and_expects:
self.assertEqual(jp_era(*args), expect)
self.assertRaises(ValueError, lambda: jp_era(
datetime.date(1000, 1, 1)))
def test_parse_jp_date(self):
args_and_expects = [
[['H30.01.15 09:52'], datetime.datetime(2018, 1, 15, 9, 52)],
[['H01.01.8 10:00'], datetime.datetime(1989, 1, 8, 10, 00)],
[['S64.01.7 10:00'], datetime.datetime(1989, 1, 7, 10, 00)],
[['S90.01.15 09:52'], datetime.datetime(2015, 1, 15, 9, 52)], # NOTE: 議論の余地がある
]
for args, expect in args_and_expects:
self.assertEqual(parse_jp_datetime(*args), expect)
self.assertRaises(
ValueError, lambda: parse_jp_datetime('X10.01.15 09:52'))
if __name__ == "__main__":
unittest.main()