☰
jc date 解析器实战指南:将 date 命令输出转换为结构化 JSON 时间数据
2026/9/25 2:43:52 网站建设 项目流程
  • 开发工具

【免费下载链接】jc

CLI tool and python library that converts the output of popular command-line tools, file-types, and common strings to JSON, YAML, or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.

项目地址:https://gitcode.com/gh_mirrors/jc/jc
点击查看免费下载

本篇指南聚焦于开源项目 jc(JSON Convert)中的date命令解析器,讲解如何将系统date命令输出转换为包含年月日、时分秒、时区、ISO 8601 时间戳与 epoch 时间戳等 18 个字段的结构化 JSON 数据。读完本文,你将掌握date | jc --date的 CLI 用法、Python 模块调用方式、输出 Schema 中每个字段的精确含义,以及epoch、epoch_utc、timezone_aware三个计算字段在本地时间与 UTC 场景下的行为差异。

date 解析器是什么

jc.parsers.date是 jc 项目内置的date命令输出解析器,定义于 jc/parsers/date.py。它的作用是把date命令输出的纯文本(例如Mon Aug 3 09:12:51 PDT 2020)解析为结构化的字典 / JSON 数据,方便后续通过jq等工具进行过滤、统计与自动化脚本处理。

从源码中的解析器元数据可以看到(见 jc/parsers/date.py):

  • 版本:2.6
  • 作者:Kelly Brazil
  • 兼容平台:linux、darwin、freebsd
  • 标签:command、slurpable(支持--slurp选项)

快速上手:两种调用方式

CLI 管道方式

将date命令的输出通过管道交给 jc 解析:

$ date | jc --date

也可以直接让 jc 代为执行date命令:

$ jc date

--date即指定使用名为date的解析器;jc date是 jc 的“魔法命令”形式——源码中info.magic_commands = ['date'](见 jc/parsers/date.py),表示该解析器可以直接以命令名调用。

Python 模块方式

在 Python 中调用:

import jc result = jc.parse('date', date_command_output)

其中date_command_output是date命令输出的字符串。返回值为字典类型;若传入空字符串,解析结果为空字典{}(该行为由jc.utils.has_data检查以及 tests/test_date.py 中的test_date_nodata用例验证)。

输出 Schema:18 个字段详解

parse()函数返回的字典遵循以下 Schema(完整定义见 jc/parsers/date.py):

{ "year": integer, "month": string, "month_num": integer, "day": integer, "weekday": string, "weekday_num": integer, "hour": integer, "hour_24": integer, "minute": integer, "second": integer, "period": string, "timezone": string, "utc_offset": string, "day_of_year": integer, "week_of_year": integer, "iso": string, "epoch": integer, "epoch_utc": integer, "timezone_aware": boolean }

各字段含义如下表:

字段类型说明
yearinteger年份,如 2021
monthstring月份缩写(%b),如Mar
month_numinteger月份数字,1-12
dayinteger日
weekdaystring星期缩写(%a),如Thu
weekday_numintegerISO 星期编号,1(周一)到 7(周日),由dt.isoweekday()计算
hourinteger12 小时制小时,1-12
hour_24integer24 小时制小时,0-23
minuteinteger分钟
secondinteger秒
periodstringAM/PM
timezonestring时区缩写,如UTC、PDT;找不到时区时为空值
utc_offsetstringUTC 偏移量(%z),如+0000;当 timezone 字段不是 UTC 时为null
day_of_yearinteger一年中的第几天(%j)
week_of_yearinteger一年中的第几周(%W)
isostringISO 8601 格式时间戳(dt.isoformat())
epochinteger本地时区“朴素”epoch 时间戳,见下文 [0]
epoch_utcinteger时区感知的 UTC epoch 时间戳,仅当 timezone 为 UTC 时可用,见下文 [1]
timezone_awareboolean为true时表示所有字段都基于 UTC 正确换算,见下文 [2]

三个计算字段的补充说明

  • [0]epoch(naive 时间戳):基于解析器运行时所在系统的本地时间计算,不含时区信息,即“朴素”时间戳。
  • [1]epoch_utc(时区感知时间戳):基于 UTC 计算,只有输入数据中的 timezone 字段为 UTC 时才可用;其他时区下该字段为null。
  • [2]timezone_aware:布尔值,为true表示所有字段均基于 UTC 正确生成。

实战示例与字段对照

示例一:非 UTC 时区(PDT)

输入:

$ date Mon Aug 3 09:12:51 PDT 2020

使用-p(pretty 输出)解析:

$ date | jc --date -p

输出:

{ "year": 2020, "month": "Aug", "month_num": 8, "day": 3, "weekday": "Mon", "weekday_num": 1, "hour": 9, "hour_24": 9, "minute": 12, "second": 51, "period": "AM", "timezone": "PDT", "utc_offset": null, "day_of_year": 216, "week_of_year": 31, "iso": "2020-08-03T09:12:51", "epoch": 1596471171, "epoch_utc": null, "timezone_aware": false }

(该用例与 tests/fixtures/generic/date.out 输入、tests/fixtures/generic/date.json 输出一一对应。)可以看到:由于时区是 PDT 而非 UTC,utc_offset、epoch_utc均为null,timezone_aware为false,iso字段也不含时区偏移。

示例二:UTC 时区(文档官方示例)

$ date | jc --date -p

输出:

{ "year": 2021, "month": "Mar", "month_num": 3, "day": 25, "weekday": "Thu", "weekday_num": 4, "hour": 2, "hour_24": 2, "minute": 2, "second": 26, "period": "AM", "timezone": "UTC", "utc_offset": "+0000", "day_of_year": 84, "week_of_year": 12, "iso": "2021-03-25T02:02:26+00:00", "epoch": 1616662946, "epoch_utc": 1616637746, "timezone_aware": true }

当输入中的时区为 UTC 时,utc_offset为+0000、epoch_utc有值、timezone_aware为true,iso字段带+00:00时区偏移,且iso中的时间与hour_24、minute、second完全一致。

示例三:12 小时制与 24 小时制的换算

午夜前(PM → 24 小时制),输入Wed Mar 24 11:54:47 PM UTC 2021(见 tests/fixtures/generic/date-before-midnight.out),解析结果为(见 tests/fixtures/generic/date-before-midnight.json):

{ "year": 2021, "month": "Mar", "month_num": 3, "day": 24, "weekday": "Wed", "weekday_num": 3, "hour": 11, "hour_24": 23, "minute": 54, "second": 47, "period": "PM", "timezone": "UTC", "utc_offset": "+0000", "day_of_year": 83, "week_of_year": 12, "iso": "2021-03-24T23:54:47+00:00", "epoch": 1616655287, "epoch_utc": 1616630087, "timezone_aware": true }

午夜后(AM → 24 小时制),输入Wed Mar 24 12:54:47 AM UTC 2021(见 tests/fixtures/generic/date-after-midnight.out),结果为(见 tests/fixtures/generic/date-after-midnight.json):

{ "year": 2021, "month": "Mar", "month_num": 3, "day": 24, "weekday": "Wed", "weekday_num": 3, "hour": 12, "hour_24": 0, "minute": 54, "second": 47, "period": "AM", "timezone": "UTC", "utc_offset": "+0000", "day_of_year": 83, "week_of_year": 12, "iso": "2021-03-24T00:54:47+00:00", "epoch": 1616572487, "epoch_utc": 1616547287, "timezone_aware": true }

注意这里的关键换算:11:54:47 PM→hour_24: 23,而12:54:47 AM→hour_24: 0(零点)。这两个边界用例在 tests/test_date.py 中分别被test_date_before_midnight与test_date_after_midnight覆盖,用于验证 24 小时制换算在午夜前后的正确性。

示例四:12 小时制时钟的 AM / PM(Ubuntu 20.04 环境)

在LANG=en_US.UTF-8(使用 12 小时制)的系统上,输入Tue Jan 5 01:02:04 AM UTC 2021(见 tests/fixtures/ubuntu-20.04/date.out),结果为(见 tests/fixtures/ubuntu-20.04/date.json):

{ "year": 2021, "month": "Jan", "month_num": 1, "day": 5, "weekday": "Tue", "weekday_num": 2, "hour": 1, "hour_24": 1, "minute": 2, "second": 4, "period": "AM", "timezone": "UTC", "utc_offset": "+0000", "day_of_year": 5, "week_of_year": 1, "iso": "2021-01-05T01:02:04+00:00", "epoch": 1609837324, "epoch_utc": 1609808524, "timezone_aware": true }

对应的 PM 场景输入为Tue Mar 23 08:45:29 PM UTC 2021(见 tests/fixtures/ubuntu-20.04/date2.out),hour为 8、hour_24为 20(见 tests/fixtures/ubuntu-20.04/date2.json)。这两个用例在 tests/test_date.py 中分别由test_date_am_ubuntu_20_04与test_date_pm_ubuntu_20_04覆盖。

parse() 函数签名与参数

parse()是解析器的入口函数(见 jc/parsers/date.py):

def parse(data, raw=False, quiet=False)

参数说明:

  • data(string):要解析的文本数据,即date命令的输出;
  • raw(boolean):为True时返回未处理的原始结构化数据,为False(默认)时返回经_process()处理后的数据;
  • quiet(boolean):为True时抑制警告消息(例如在不兼容平台上运行时的提示)。

返回值为字典,包含原始或处理后的结构化数据。

解析流程源码解析

从 jc/parsers/date.py 可以梳理出完整的处理链路:

  1. 兼容性检查:调用jc.utils.compatibility(),对照info.compatible = ['linux', 'darwin', 'freebsd']检查当前平台;
  2. 输入类型检查:调用jc.utils.input_type_check()校验data为字符串或字节流;
  3. 空数据检查:调用jc.utils.has_data(),数据为空时直接返回空字典{};
  4. 时区识别:维护一个庞大的时区缩写表(涵盖PDT、UTC、CET、JST等以及UTC+0800、UTC-0500这类数字偏移写法),逐个分词匹配输入字符串中的时区标记;
  5. 时间戳转换:调用jc.utils.timestamp()(定义于 jc/utils.py),并通过format_hint=(1000, 6000, 7000)提示优先尝试对应格式;timestamp对象提供naive与utc两个属性,分别对应本地时间戳与 UTC 时间戳;
  6. 字段组装:基于datetime.fromtimestamp()生成的datetime对象,用strftime格式化出月份缩写(%b)、星期缩写(%a)、12 小时制小时(%I)、AM/PM(%p)、UTC 偏移(%z)、一年中第几天(%j)、一年中第几周(%W)等字段,并用isoformat()生成iso字段;
  7. 最终处理:_process()目前不进行额外加工,直接返回原始结构化数据(见 jc/parsers/date.py)。

一个值得注意的实现细节是:utc_offset字段由dt.strftime('%z')生成,or None兜底——当 datetime 对象本身不含时区信息(即非 UTC 输入)时,%z返回空字符串,进而被转换为null,这正是 Schema 中“timezone 不是 UTC 时 utc_offset 为 null”的底层实现。

时区识别机制

解析器并不依赖固定位置的时区字段,而是“在整个字符串中查找时区标记”。源码中的实现为(见 jc/parsers/date.py):先去除输入中的括号,再按空白分词,逐词与内置的时区缩写表比对,命中即认定为时区。因此无论date输出中的时区位于末尾(如Mon Aug 3 09:12:51 PDT 2020)还是位于中间(如Wed Mar 24 11:54:47 PM UTC 2021),都能被正确识别。时区缩写表覆盖了全球主要时区缩写(如EST/EDT、CET/CEST、JST、IST、AEST等),以及UTC±HHMM这类直接带偏移的写法。

需要留意的是:时区识别用于timezone字段,而epoch_utc的可用性仍取决于时区是否为 UTC——非 UTC 时区(如 PDT)即使被识别出来,epoch_utc依然为null、timezone_aware依然为false。

与 --slurp 搭配使用

date解析器标记为slurpable(见 jc/parsers/date.py),可以配合 jc 的--slurp命令行选项使用,将多行输入聚合后一次性解析。该能力同样记录在 docs/parsers/date.md 中。关于 slurp 模式的更多用法,可参阅 jc 流式处理相关文档 docs/streaming.md。

实用技巧:与 jq 联动

将date输出转为 JSON 后,即可无缝接入jq做进一步筛选。例如:

# 查看当前时间的 24 小时制小时 $ date | jc --date | jq '.hour_24' # 查看当前是否处于 UTC 时区感知状态 $ date | jc --date | jq '.timezone_aware' # 同时输出 ISO 时间戳与 epoch $ date | jc --date | jq '{iso, epoch}'

适用前提与限制

  • 平台兼容性:该解析器官方支持linux、darwin、freebsd三个平台,在不兼容平台上运行时会输出兼容性警告(quiet=True可抑制);
  • 时区与 epoch 的关系:epoch是基于运行 jc 的系统本地时间计算的朴素时间戳;只有输入数据的 timezone 为 UTC 时,epoch_utc才有值,此时所有字段(含iso、hour_24等)均基于 UTC 生成;
  • 解析依赖date输出格式:解析器通过内置时间格式库与format_hint提示识别date命令的常见输出格式,因此建议在标准环境下使用,非标准格式(如自定义date输出模板)可能需要先规整输出再解析。

参考资料

  • 解析器官方文档:docs/parsers/date.md
  • 解析器源码:jc/parsers/date.py
  • 单元测试:tests/test_date.py
  • 测试输入与预期输出:tests/fixtures/generic/date.out、tests/fixtures/generic/date.json、tests/fixtures/generic/date-before-midnight.out、tests/fixtures/generic/date-after-midnight.out、tests/fixtures/ubuntu-20.04/date.out、tests/fixtures/ubuntu-20.04/date2.out
  • 时间戳工具类:jc/utils.py
  • 开发工具

【免费下载链接】jc

CLI tool and python library that converts the output of popular command-line tools, file-types, and common strings to JSON, YAML, or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.

项目地址:https://gitcode.com/gh_mirrors/jc/jc
点击查看免费下载
上一篇:Traefik 对接 SPIFFE:基于 Workload API 的 X.509-SVID 安全后端通信配置指南
下一篇:dromara/easy-query Kubernetes:云原生编排的集成方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询