You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python脚本异常:从字符串提取指定格式的起止日期时间

从多格式字符串提取日期时间的Python解决方案

看起来你在处理多种格式的日期时间字符串提取时遇到了麻烦,从你给出的测试用例来看,这些格式的多样性确实容易让普通的分割和解析逻辑出问题——有的是完整的日期时间区间,有的只有单个日期/时间,还有的是日期时间加单独的结束时间。我帮你完善了代码,能覆盖所有这些场景:

from datetime import datetime, timedelta

def extract_datetimes(date_time_str):
    # 定义所有可能用到的日期时间格式
    full_dt_format = "%a %b %d %Y at %I:%M %p"
    date_only_format = "%a %b %d %Y"
    time_only_format = "%I:%M %p"
    
    # 用" to "分割字符串,区分单段(无结束时间)和两段(有时间区间)的情况
    parts = date_time_str.split(' to ')
    start_dt = None
    end_dt = None
    
    # 处理只有单个日期/时间的情况
    if len(parts) == 1:
        part = parts[0].strip()
        # 先尝试解析完整日期时间
        try:
            start_dt = datetime.strptime(part, full_dt_format)
            end_dt = start_dt  # 无结束时间时默认与开始时间一致,可根据需求调整
        except ValueError:
            # 尝试解析仅日期格式
            try:
                start_dt = datetime.strptime(part, date_only_format)
                end_dt = start_dt
            except ValueError:
                print(f"无法解析的格式:{part}")
                return None, None
    # 处理包含时间区间的情况
    elif len(parts) == 2:
        start_part = parts[0].strip()
        end_part = parts[1].strip()
        
        # 解析开始部分
        try:
            start_dt = datetime.strptime(start_part, full_dt_format)
        except ValueError:
            try:
                start_dt = datetime.strptime(start_part, date_only_format)
            except ValueError:
                print(f"无法解析开始部分:{start_part}")
                return None, None
        
        # 解析结束部分:先试完整日期时间,再试仅时间(复用开始日期),最后试仅日期
        try:
            end_dt = datetime.strptime(end_part, full_dt_format)
        except ValueError:
            try:
                time_obj = datetime.strptime(end_part, time_only_format)
                end_dt = start_dt.replace(hour=time_obj.hour, minute=time_obj.minute)
                # 处理跨天情况:如果结束时间早于开始时间,自动加一天
                if end_dt < start_dt:
                    end_dt += timedelta(days=1)
            except ValueError:
                try:
                    end_dt = datetime.strptime(end_part, date_only_format)
                except ValueError:
                    print(f"无法解析结束部分:{end_part}")
                    return None, None
    
    return start_dt, end_dt

# 测试你给出的所有用例
test_cases = [
    'Sun Apr 22 2018 at 02:00 pm to Sun May 13 2018 at 02:00 pm',
    'Sun Apr 22 2018 at 02:00 pm',
    'Sat Apr 28 2018 at 05:00 pm to 07:00 am',
    'Fri Oct 15 2021',
    'Sat Aug 01 2020',
    'Wed Jan 22 2020 at 01:30 pm',
    'Wed Jan 01 2020 to Thu Jan 02 2020'
]

for case in test_cases:
    start, end = extract_datetimes(case)
    print(f"输入:{case}")
    print(f"开始时间:{start.strftime('%Y-%m-%d %H:%M:%S') if start else '解析失败'}")
    print(f"结束时间:{end.strftime('%Y-%m-%d %H:%M:%S') if end else '解析失败'}")
    print("-"*50)

关键细节说明:

  • 格式覆盖:预先定义了三种核心格式,完美匹配你给出的所有测试场景;
  • 容错解析:用try-except依次尝试不同格式,避免因为格式不匹配直接抛出异常;
  • 跨天处理:针对下午5点到早上7点这种跨天场景,自动给结束时间加一天,符合实际逻辑;
  • 灵活调整:如果不需要默认结束时间等于开始时间,可以把对应位置改成end_dt = None,按需调整即可。

你原代码里delim = 'to' if del...的截断部分,应该是最初尝试判断分隔符的逻辑,这里直接用split(' to ')更简洁,也能准确区分是否存在时间区间。

内容的提问来源于stack exchange,提问作者Deba

火山引擎 最新活动