pyunit-time icon indicating copy to clipboard operation
pyunit-time copied to clipboard

下午时间解析错误 - "下午七点" 被错误解析为上午时间

Open rewrz opened this issue 3 months ago • 2 comments

问题描述:

在使用 pyunit-time 库解析中文时间表达式时,发现了一个严重的解析错误:简单的"下午+时间"表达式会被错误地解析为上午时间

复现步骤:

from pyunit_time import Time

# 错误示例
current_time = '2025-10-14 00:01:00'
result = Time(current_time).parse('下午七点')
print(result)
# 输出: [{'key': '下午7点', 'keyDate': '2025-10-14 07:01:00', 'baseDate': '2025-10-14 00:01:00'}]
# 期望: '2025-10-14 19:01:00' (下午7点应该是19:01)
# 实际: '2025-10-14 07:01:00' (错误地解析为上午7点)

预期行为 vs 实际行为:

时间表达式 预期结果 实际结果 状态
下午七点 19:01 07:01 ❌ 错误
今天下午七点 19:01 07:01 ❌ 错误
明天下午七点 19:01 07:01 ❌ 错误

正常工作的表达式(对比):

时间表达式 结果 状态
晚上七点 19:01 ✅ 正确
上午七点 07:01 ✅ 正确
三天之内的下午3点 15:01 ✅ 正确

环境信息:

  • pyunit-time 版本:2024.7.3
  • Python 版本:3.12
  • 操作系统:Windows 11
  • 测试时间:2025年10月14日

影响范围:

这个问题影响了所有简单的"下午+具体时间"的表达式,但奇怪的是:

  • 复杂表达式如"三天之内的下午3点"工作正常
  • "晚上"和"上午"的时间解析都正常

可能的原因:

怀疑是在处理时间段词(下午、晚上、上次)与具体时间组合时,存在解析逻辑错误。可能是在将中文时间转换为24小时制时,没有正确处理下午时间段的偏移。

目前我自己是加了一个补丁来搭配使用。

def _fix_time_period_interpretation(self, command_content: str, target_time: dt.datetime) -> dt.datetime:
        """
        修正 pyunit-time 对时间段的错误解析
        
        Args:
            command_content: 原始时间描述
            target_time: 解析后的时间
            
        Returns:
            修正后的时间
        """
        try:
            hour = target_time.hour
            
            # 修正下午时间 - pyunit-time 有时会错误地将下午时间解析为上午
            if "下午" in command_content and hour < 12:
                # 如果是下午时间但解析为上午,则加12小时
                corrected_time = target_time + dt.timedelta(hours=12)
                return corrected_time
            
            # 修正晚上时间 - 确保晚上时间在18点之后
            elif "晚上" in command_content and hour < 18:
                if hour < 6:  # 如果解析为凌晨,可能是"今晚"被误解
                    corrected_time = target_time + dt.timedelta(hours=12)
                    return corrected_time
                else:  # 如果解析为上午,调整为晚上
                    corrected_time = target_time + dt.timedelta(hours=12)
                    if corrected_time.hour < 18:
                        corrected_time = corrected_time.replace(hour=18 + (hour % 12))
                    return corrected_time
            
            # 其他情况不需要修正
            return target_time

rewrz avatar Oct 14 '25 10:10 rewrz

@rewrz 首先十分感谢你的描述。这个库可能写的不是很清楚,这里定义的下午是按 中文 严格定义的范围。下午:一般特指 2点到5点。为了稍微兼容,特意将范围增加一个小时,参考: 标准早中晚

上午:8-11点
中午:11-13点
下午:14-17点
晚上:18-22点

这是中文语言困境,我并没有做语言的纠错能力。如果你使用 下午5点,代码是正常运行。 如果你感兴趣,可以增加语言的自动纠错能力,我很久以前尝试过,后来失败了。😭

jtyoui avatar Nov 19 '25 09:11 jtyoui