Python 3.8中基于argparse实现多格式日期时间转GPS周+周内时间功能并优化命令行使用提示
解决方案
我来帮你搞定这两个问题——兼容多格式日期输入和优化命令行提示,这是最便捷的实现方案:
1. 优化命令行使用提示
你遇到的重复参数名问题,是因为nargs=7时argparse默认会把每个参数位置都列出来。只需添加metavar='DATETIME_PARTS',就能让usage提示变得简洁,不再重复7次参数名。
2. 兼容多格式日期时间输入
原来的type=lambda写法有个隐藏bug:nargs=7时,lambda会被应用到每个单独的参数上,而不是整个参数列表,导致解析失败。我们改用自定义argparse Action来接收全部7个参数,统一处理格式兼容:
- 支持两位/四位年份(比如
21自动转为2021,1999直接使用) - 支持一位/两位的月、日、时、分、秒(比如
8自动补为08) - 自动将毫秒补为6位微秒(适配
datetime.strptime的%f格式要求)
完整代码示例
import argparse import datetime class ConvertToDatetimeAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): # 确保收到7个参数 if len(values) != 7: parser.error(f"Expected 7 datetime parts (year month day hour minute second ms), got {len(values)}") year, month, day, hour, minute, second, ms = values # 处理年份:兼容两位/四位 try: year_int = int(year) if year_int < 100: # 可按需调整:这里默认00-99对应2000-2099,若需19xx可加判断逻辑 year = f"20{year.zfill(2)}" except ValueError: parser.error(f"Invalid year value: {year}") # 处理月、日、时、分、秒:补前导零 for part_name, part in zip( ["month", "day", "hour", "minute", "second"], [month, day, hour, minute, second] ): try: int(part) # 验证是数字格式 locals()[part_name] = part.zfill(2) except ValueError: parser.error(f"Invalid {part_name} value: {part}") # 处理毫秒→微秒(strptime的%f需要6位) ms = ms.ljust(6, '0')[:6] # 拼接为标准格式字符串并解析 dt_str = f"{year} {month} {day} {hour} {minute} {second} {ms}" try: dt = datetime.datetime.strptime(dt_str, "%Y %m %d %H %M %S %f") # 转换为UTC(GPS时间基于UTC,若输入是本地时间需调整时区逻辑) if dt.tzinfo is None: dt = dt.replace(tzinfo=datetime.timezone.utc) # 计算GPS周和周内时间 gps_epoch = datetime.datetime(1980, 1, 6, tzinfo=datetime.timezone.utc) delta = dt - gps_epoch gps_week = delta.days // 7 time_of_week = delta.total_seconds() - gps_week * 7 * 24 * 3600 # 打印结果并退出程序 print(f"✅ GPS Week: {gps_week}") print(f"✅ Time of Week: {time_of_week:.3f} seconds") parser.exit() except ValueError as e: parser.error(f"Failed to parse datetime: {' '.join(values)}\nError: {str(e)}") # 初始化argparse解析器 parser = argparse.ArgumentParser(description="Your Python 3.8 Application") # 添加你原有其他参数 parser.add_argument('-m', '--mode', choices=['run', 'test', 'debug'], help="Application mode") parser.add_argument('-g', '--some-flag', action='store_true', help="Some flag") parser.add_argument('-v', '--verbose', action='store_true', help="Verbose output") parser.add_argument('project_config', nargs='?', help="Path to project config") # 添加转换参数 parser.add_argument( '-c', '--convert-date-time-to-gps', nargs=7, action=ConvertToDatetimeAction, metavar='DATETIME_PARTS', help='Convert datetime to GPS week & time-of-week. ' 'Supports formats like "2021 08 13 23 08 00 42" or "21 8 13 23 8 0 42"' ) # 解析参数 args = parser.parse_args()
关键说明
- 简洁提示:添加
metavar='DATETIME_PARTS'后,usage提示会变成-c DATETIME_PARTS,不再重复参数名 - 格式兼容:自定义Action自动处理所有格式补全,用户无需输入严格的两位数字
- 时区注意:当前代码假设输入时间是UTC,若你需要处理本地时间,可添加
zoneinfo或pytz进行时区转换 - 闰秒提示:基础计算未考虑GPS与UTC的闰秒差,若需极高精度,可引入专门的GPS时间库(如
gpsd)处理闰秒
内容的提问来源于stack exchange,提问作者x y
相关产品推荐
相关产品推荐

