import datetime import pytest from ptimeparse import Parser from ptimeparse.err import MultipleSpecificationException, TokenUnhandledException def test_chinese_number(): parser = Parser() assert parser.digest_chinese_number("零") == ('', 0) assert parser.digest_chinese_number("零喵") == ('喵', 0) assert parser.digest_chinese_number("一喵") == ('喵', 1) assert parser.digest_chinese_number("十喵") == ('喵', 10) assert parser.digest_chinese_number("三千万喵") == ('喵', 3000_0000) assert parser.digest_chinese_number("三千三百万喵") == ('喵', 3300_0000) assert parser.digest_chinese_number("三千零三万喵") == ('喵', 3003_0000) assert parser.digest_chinese_number("三千零三十万喵") == ('喵', 3030_0000) assert parser.digest_chinese_number("五千四百零三万喵") == ('喵', 5403_0000) assert parser.digest_chinese_number("五百万喵") == ('喵', 500_0000) assert parser.digest_chinese_number("五万五千喵") == ('喵', 5_5000) assert parser.digest_chinese_number("五万零五百喵") == ('喵', 5_0500) assert parser.digest_chinese_number("五亿喵") == ('喵', 5_0000_0000) assert parser.digest_chinese_number("五百亿喵") == ('喵', 500_0000_0000) assert parser.digest_chinese_number("五百亿零五十喵") == ('喵', 500_0000_0050) assert parser.digest_chinese_number("五百亿五十万喵") == ('喵', 500_0050_0000) def test_hour_specification_pm(): parser = Parser(now=datetime.datetime(2025, 10, 9, 16, 34, 1, 114)) assert parser.parse("五点") == datetime.datetime(2025, 10, 9, 17, 0, 0, 0) assert parser.parse("5点") == datetime.datetime(2025, 10, 9, 17, 0, 0, 0) assert parser.parse("5 点") == datetime.datetime(2025, 10, 9, 17, 0, 0, 0) assert parser.parse("六点") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0) assert parser.parse("六点整") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0) assert parser.parse("六点钟") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0) assert parser.parse("10 时") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("10 时整") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("10点") == datetime.datetime(2025, 10, 9, 22, 0, 0, 0) assert parser.parse("10点整") == datetime.datetime(2025, 10, 9, 22, 0, 0, 0) assert parser.parse("13点") == datetime.datetime(2025, 10, 9, 13, 0, 0, 0) assert parser.parse("15点") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0) assert parser.parse("13 时") == datetime.datetime(2025, 10, 9, 13, 0, 0, 0) assert parser.parse("15 时") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0) assert parser.parse("四点") == datetime.datetime(2025, 10, 9, 16, 0, 0, 0) assert parser.parse("上午十点") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("早晨十点") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("早上十点") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("早十") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("早八") == datetime.datetime(2025, 10, 9, 8, 0, 0, 0) assert parser.parse("晚六") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0) assert parser.parse("下午三点") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0) assert parser.parse("晚上十二点") == datetime.datetime(2025, 10, 10, 0, 0, 0, 0) assert parser.parse("晚上八点") == datetime.datetime(2025, 10, 9, 20, 0, 0, 0) assert parser.parse("凌晨零点") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0) assert parser.parse("中午十二点") == datetime.datetime(2025, 10, 9, 12, 0, 0, 0) def test_hour_specification_am(): parser = Parser(now=datetime.datetime(2025, 10, 9, 2, 34, 1, 114)) assert parser.parse("五点") == datetime.datetime(2025, 10, 9, 5, 0, 0, 0) assert parser.parse("5点") == datetime.datetime(2025, 10, 9, 5, 0, 0, 0) assert parser.parse("5 点") == datetime.datetime(2025, 10, 9, 5, 0, 0, 0) assert parser.parse("六点") == datetime.datetime(2025, 10, 9, 6, 0, 0, 0) assert parser.parse("六点整") == datetime.datetime(2025, 10, 9, 6, 0, 0, 0) assert parser.parse("六点钟") == datetime.datetime(2025, 10, 9, 6, 0, 0, 0) assert parser.parse("10 时") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("10 时整") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("10点") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("10点整") == datetime.datetime(2025, 10, 9, 10, 0, 0, 0) assert parser.parse("四点") == datetime.datetime(2025, 10, 9, 4, 0, 0, 0) assert parser.parse("一点钟") == datetime.datetime(2025, 10, 9, 13, 0, 0, 0) def test_hour_with_minute(): parser = Parser(now=datetime.datetime(2025, 10, 9, 16, 34, 1, 114)) assert parser.parse("六点半") == datetime.datetime(2025, 10, 9, 18, 30, 0, 0) assert parser.parse("六点半钟") == datetime.datetime(2025, 10, 9, 18, 30, 0, 0) assert parser.parse("六点一刻") == datetime.datetime(2025, 10, 9, 18, 15, 0, 0) assert parser.parse("六点过一刻") == datetime.datetime(2025, 10, 9, 18, 15, 0, 0) def test_error(): parser = Parser(now=datetime.datetime(2025, 10, 9, 16, 34, 1, 114)) with pytest.raises(TokenUnhandledException): parser.parse("六点半整") with pytest.raises(MultipleSpecificationException): parser.parse("六点半一刻") def test_absolute_date(): now = datetime.datetime(2025, 10, 9, 16, 34, 1, 114) parser = Parser(now=now) # 完整年月日 assert parser.parse("2025年10月9日") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0) assert parser.parse("2025-10-09") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0) assert parser.parse("2025/10/09") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0) # 仅月日(默认今年) assert parser.parse("10月9日") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0) assert parser.parse("十月九日") == datetime.datetime(2025, 10, 9, 0, 0, 0, 0) # 年月日 + 时间 assert parser.parse("2025年10月9日 15点") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0) assert parser.parse("10月9日 下午3点") == datetime.datetime(2025, 10, 9, 15, 0, 0, 0) assert parser.parse("十月九日 晚上八点") == datetime.datetime(2025, 10, 9, 20, 0, 0, 0) # ISO 格式(如果支持) assert parser.parse("2025-10-09T15:30") == datetime.datetime(2025, 10, 9, 15, 30, 0, 0) def test_relative_date(): now = datetime.datetime(2025, 10, 9, 10, 0, 0) parser = Parser(now=now) assert parser.parse("明天") == datetime.datetime(2025, 10, 10, 0, 0, 0, 0) assert parser.parse("后天") == datetime.datetime(2025, 10, 11, 0, 0, 0, 0) assert parser.parse("昨天") == datetime.datetime(2025, 10, 8, 0, 0, 0, 0) assert parser.parse("大前天") == datetime.datetime(2025, 10, 6, 0, 0, 0, 0) assert parser.parse("大后天") == datetime.datetime(2025, 10, 12, 0, 0, 0, 0) assert parser.parse("三天后") == datetime.datetime(2025, 10, 12, 0, 0, 0, 0) assert parser.parse("五天前") == datetime.datetime(2025, 10, 4, 0, 0, 0, 0) assert parser.parse("下周一") == datetime.datetime(2025, 10, 13, 0, 0, 0, 0) assert parser.parse("上周五") == datetime.datetime(2025, 10, 3, 0, 0, 0, 0) assert parser.parse("本周五") == datetime.datetime(2025, 10, 10, 0, 0, 0, 0) end_of_month = datetime.datetime(2025, 10, 31, 10, 0, 0) parser2 = Parser(now=end_of_month) assert parser2.parse("两天后") == datetime.datetime(2025, 11, 2, 0, 0, 0, 0) def test_relative_time(): now = datetime.datetime(2025, 10, 9, 16, 30, 0, 0) parser = Parser(now=now) assert parser.parse("五分钟后") == datetime.datetime(2025, 10, 9, 16, 35, 0, 0) assert parser.parse("十分钟前") == datetime.datetime(2025, 10, 9, 16, 20, 0, 0) assert parser.parse("半小时后") == datetime.datetime(2025, 10, 9, 17, 0, 0, 0) assert parser.parse("一个半小时后") == datetime.datetime(2025, 10, 9, 18, 0, 0, 0) assert parser.parse("两小时后") == datetime.datetime(2025, 10, 9, 18, 30, 0, 0) assert parser.parse("一小时前") == datetime.datetime(2025, 10, 9, 15, 30, 0, 0) late_night = datetime.datetime(2025, 10, 9, 23, 50, 0, 0) parser3 = Parser(now=late_night) assert parser3.parse("二十分钟后") == datetime.datetime(2025, 10, 10, 0, 10, 0, 0) assert parser.parse("5分钟后") == datetime.datetime(2025, 10, 9, 16, 35, 0, 0) assert parser.parse("三十分钟前") == datetime.datetime(2025, 10, 9, 16, 0, 0, 0) def test_robustness_edge_cases(): parser = Parser(now=datetime.datetime(2025, 2, 28, 10, 0, 0)) assert parser.parse("明天") == datetime.datetime(2025, 3, 1, 0, 0, 0, 0) parser_leap = Parser(now=datetime.datetime(2024, 2, 28, 10, 0, 0)) assert parser_leap.parse("两天后") == datetime.datetime(2024, 3, 1, 0, 0, 0, 0) with pytest.raises(TokenUnhandledException): parser.parse("随便乱写") parser.parse(" 明天 ") def test_mixed_expressions(): now = datetime.datetime(2025, 10, 9, 14, 0, 0) parser = Parser(now=now) # 如“明天下午三点” assert parser.parse("明天下午三点") == datetime.datetime(2025, 10, 10, 15, 0, 0, 0) assert parser.parse("后天早上八点") == datetime.datetime(2025, 10, 11, 8, 0, 0, 0) assert parser.parse("大后天晚上十点") == datetime.datetime(2025, 10, 12, 22, 0, 0, 0) # “下周三上午” # 2025-10-09 是周四,下周三是 2025-10-15 assert parser.parse("下周三") == datetime.datetime(2025, 10, 15, 0, 0, 0, 0) assert parser.parse("下周三早八") == datetime.datetime(2025, 10, 15, 8, 0, 0, 0) # 默认0点?或上午9点?需根据实现 # 若实现中“上午”不指定小时则设为9点,可调整;这里假设设为0点以简化