MacOS/Ubuntu中jq-1.6的fromdateiso8601函数结果不一致原因排查
jq
fromdateiso8601跨系统时间转换差异问题 我在MacOS和Ubuntu系统上均运行以下两条jq命令:
jq -n '"1971-08-01T01:00:00Z" | fromdateiso8601' jq -n '"1972-08-01T01:00:00Z" | fromdateiso8601'
- MacOS输出:
49856400和81482400 - Ubuntu输出:
49856400和81478800
1972年的转换结果相差一小时,1971年却无差异,两个系统均使用jq-1.6版本。
更新内容
- 更新1:Windows系统的表现与MacOS一致。
- 更新2:出现差异的日期范围如下:
1972-03-20 - 1972-10-29 (inclusive) ... 2022-03-28 - 2022-10-30
可见MacOS/Windows的实现从1972年起对夏令时(DST)日期加一小时,但1969、1970、1971年无此处理;而Ubuntu的实现完全不应用夏令时调整。
差异原因解析
这个差异的核心是jq-1.6在不同操作系统上依赖的系统时间库实现不同,且UTC时间处理逻辑存在分歧:
系统时间库的平台差异
- MacOS基于
CoreFoundation、Windows基于win32时间API,这些框架解析ISO8601格式的UTC时间时,会依据本地时区的历史夏令时规则自动调整特定时间段的日期。但1972年之前部分地区的夏令时规则未被纳入这些库的历史数据,所以1971年的转换无差异。 - Ubuntu等Linux系统使用
glibc库的时间处理函数,jq-1.6在Linux下直接调用相关UTC转换接口,而该接口默认不对UTC时间应用夏令时调整(UTC本身是无夏令时的标准时间),因此输出严格的UTC时间戳。
- MacOS基于
jq内部实现的逻辑分歧
jq的fromdateiso8601函数在不同平台的底层实现未完全统一:- MacOS/Windows版本的jq可能错误地将UTC时间当作本地时间处理,触发了本地时区的夏令时调整逻辑,导致符合夏令时的时间段多增加一小时。
- Linux版本的jq严格遵循UTC时间定义,直接将ISO8601格式的UTC时间转换为Unix时间戳,无额外时区调整。
历史夏令时规则的时间节点影响
1972年是部分地区夏令时规则正式标准化或大范围启用的年份,MacOS/Windows的系统时间库包含这之后的夏令时历史数据,而1971年及之前的规则未被收录,所以1971年转换不会触发调整,与Linux结果一致。
内容的提问来源于stack exchange,提问作者Philippe
相关产品推荐
相关产品推荐

