javax.net.ssl日志时间戳小时显示24而非00的原因咨询
JDK/Jetty SSL日志中小时字段显示为24的原因与处理
核心原因
你遇到的时间格式异常不是日志输出错误,是JDK原生javax.net.ssl调试日志的历史遗留实现bug,Jetty本身没有修改SSL层的日志逻辑,完全复用JDK原生输出:
- JDK的SSL调试日志没有走标准的时间格式化类(比如
SimpleDateFormat),而是内部手动拼接时间字段,在JDK 8早期版本、JDK 11初始版本中,UTC时区的日界点时间计算存在偏移bug:当实际时间为当日0点0分左右时,小时字段会被错误计算为24,但日期字段不会同步进位到下一日,就出现了2022-07-01 24:00:11这种和实际时间一一对应、但不符合通用解析规则的输出。 - 该bug属于JDK内部实现问题,没有单独发布公开说明文档,仅在后续小版本更新的内部修复列表中提及过SSL日志时间显示异常的问题。
相关规范细节
- 按照ISO 8601时间表示标准,
24本身是合法的小时取值,仅用于表示自然日的结束时刻,即YYYY-MM-DD 24:00:00等价于YYYY-MM-(DD+1) 00:00:00,这种表示法多用于营业时段、排期表这类需要明确标注前一日结束节点的场景。 - 但你遇到的日志输出并不符合ISO 8601对24点的定义:它的日期字段没有进位,
24对应的是当日0点而非次日0点,属于实现偏差,不是开发者刻意遵循标准设计的格式。
处理方案说明
你目前采用的正则提取字段+小时值模24的处理逻辑是完全适配该场景的,比通用时间解析工具的可靠性更高:
- 通用时间解析器(包括Python的
datetime构造方法、dateutil.parser.parse,以及Java原生时间解析类)遇到小时值为24的情况,要么直接抛出格式错误,要么按照ISO 8601规则自动将日期加1天,得到的时间和日志实际记录的时间差24小时,不符合业务需求。 - 可以对现有正则做小幅优化,将分隔符从通配改为明确匹配冒号,降低误匹配其他日志行的概率,优化后的参考代码如下:
import re import datetime timere = re.compile(r"^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})\.(\d{3})\s+UTC.*$") if not (match := timere.match(tstr)): raise ValueError(f"Time string {tstr} is not valid") yy, mm, dd, hr, mi, se, ms = map(int, match.groups()) # 兼容JDK SSL日志24点显示bug,24取模后为0,日期保持原字段值不进位 parsed_time = datetime.datetime(yy, mm, dd, hr % 24, mi, se, ms * 1000, tzinfo=datetime.timezone.utc)
内容的提问来源于stack exchange,提问作者TimGJ
相关产品推荐
相关产品推荐

