DeepSHPlugins
dsh-tool-time 项目预览
GITHUB / COMMUNITY PROJECT

dsh-tool-time

Tools & IntegrationsTypeScriptMIT

A DSH time tool: strict ISO 8601 parsing, IANA timezone conversion, UTC calendar math and fixed-duration differences — zero dependencies.

5 Starsomdsh-dev Updated 2026-09-10
Open GitHub repository
dsh-tool-time 项目预览

About this project

Chinese

A DSH time tool: strict ISO 8601 parsing, IANA timezone conversion, UTC calendar math and fixed-duration differences — zero dependencies.

English

A DSH time tool: strict ISO 8601 parsing, IANA timezone conversion, UTC calendar math and fixed-duration differences — zero dependencies.

Project details & listing signals

Snapshot 2026-09-11
Creator / organization
omdsh-dev
Repository
omdsh-dev/dsh-tool-time
GitHub Stars
5
Forks
0
Programming language
TypeScript
License
MIT
Last push
2026-09-10
Manifest
Declaration found in the catalog

A public repository does not automatically permit commercial use. Check the project's license and compatibility. Manifests and catalog scores are not security certifications.

Catalog score

71/ 100
Maintenance activity
100
Documentation & practical information
85
Community interest
22
Installation signals
100
Project declarations
100

近 1 天仍在更新;README 含完整安装与使用说明;关注度尚低(5)。

Scores use five dimensions of the catalog snapshot. They are browsing aids, not hands-on reviews or security assessments.

Install & use

The respective GitHub repositories define project information and licensing.

dsh plugin add github:omdsh-dev/dsh-tool-time

Copying a command does not execute it. Read the repository documentation and check requirements and licensing first.

Project screenshots

Repository README

GitHub 原文

Saved repository documentation. Its capture date was not recorded and it may differ from the catalog description. Check the current repository before installing.

Repository documentation is preserved in its original language.

dsh-tool-time

English

DSH 时间工具插件 —— 严格 ISO 解析、IANA 时区转换、UTC 日历运算、固定时长差。零依赖、零进程、纯函数。

License

动机

Agent 处理时间信息是最高频需求之一——"现在几点"、"3 天后是几号"、"把 UTC 转成北京时间"。当前做法 bash date 的问题:每次起进程、跨平台语法不一致(macOS 与 GNU date -d 完全不同)、时区转换靠 TZ=... 手动拼。模型心算时区偏移和闰年/DST 边界是错误高发区。

安全模型

无 eval、无 new Function。输入只经过严格校验:

  • 严格 ISO 8601 子集:仅接受 YYYY-MM-DD(UTC 零点)、YYYY-MM-DDTHH:mm:ssZ、YYYY-MM-DDTHH:mm:ss±HH:MM(±14:00 内,可选 .SSS 毫秒);不带时区的日期时间、RFC 2822、自然语言日期一律拒绝;2026-02-30 等日历溢出由查表校验拒绝(不依赖 Date 的静默归一化)
  • 时区名:IANA 名交给 Intl.DateTimeFormat 校验,非法即抛 time: unknown timezone
  • 数值:amount 必须是安全整数;unit 枚举白名单;所有字符串 ≤200 字符
  • Intl 环境固定:'en-CA' + hourCycle: 'h23'(避免午夜 24:00 与本地化数字)

架构

DSH Agent
    │ ctx.tools.register()
    ▼
src/index.ts(Cordis 插件入口 + action 分发 + 独立校验)
    │
    ▼
src/time.ts
    ├── parseStrictISO() — 严格 ISO 解析(正则 + 查表校验)
    ├── formatInTimezone() — Intl formatToParts 组装(时钟可注入)
    ├── addMonthsClamped() — 先置 1 日 → 目标年月 → 天数钳制
    └── diffBetween() — 固定时长(sign + absolute 分解)

工具声明

ctx.tools.register(defineTool({
  name: 'time',
  parameters: {
    action: { type: 'string', required: true, enum: ['now', 'convert', 'add', 'diff'] },
    value:  { type: 'string', description: 'Strict ISO 8601 timestamp' },
    timezone: { type: 'string', description: 'IANA timezone (default UTC; display only)' },
    from:   { type: 'string', description: 'diff start' },
    to:     { type: 'string', description: 'diff end' },
    amount: { type: 'integer', description: 'Signed safe integer' },
    unit:   { type: 'string', enum: ['seconds','minutes','hours','days','weeks','months','years'] },
  },
  output: { schema: { type: 'json' }, render: (_a, v) => [{ type: 'text', text: JSON.stringify(v, null, 2) }] },
  execute: (args) => Promise.resolve(executeAction(args.action, args) as JsonValue),
  timeoutMs: 1000,
}))

支持的操作

action参数返回
nowtimezone?(默认 UTC)当前时间结构化表示
convertvalue + timezone(必填)转换后的结构化时间
addvalue + amount + unit(timezone? 仅展示)加减后的结构化时间
difffrom + to固定时长差(无月份/年份)

返回结构(canonical value):

{
  "iso": "2026-08-05T06:00:00.000Z",
  "unix": 1785909600000,
  "timezone": "Asia/Shanghai",
  "timezoneSource": "explicit",
  "local": "2026-08-05T14:00:00+08:00",
  "formatted": "2026-08-05 14:00:00 (Asia/Shanghai)"
}

语义契约:

  • add 始终基于 UTC 运算(日历日语义,跨 DST 保持"日历日"直觉);timezone 仅决定 local/formatted 展示
  • 月份/年份钳制:2026-01-31 + 1 month = 2026-02-28;2028-02-29 + 1 year = 2029-02-28(先置 1 日 → 定位目标年月 → 按目标月最大天数钳制)
  • diff 仅固定时长:sign + 带符号总量 + absolute 余数分解(月/年无法从毫秒唯一推导,不提供)。字段语义(AUDIT-TIME-03):
  • milliseconds 是精确带符号总时长
  • seconds/minutes/hours/days/weeks 是 sign * floor(abs / unit)(对绝对值截断后带符号)
  • absolute 是 abs 的非负余数分解(如 -1500ms → milliseconds: -1500, seconds: -1, absolute: {seconds: 1, milliseconds: 500})
  • 差值超过安全整数范围抛 time: diff duration out of range
  • 默认 UTC:省略 timezone 时结果与运行环境无关(timezoneSource: "default-utc")

DSH 0.1.5-rc.1 兼容(已验证)

本插件已迁移到 DSH 0.1.5-rc.1 依赖线,并在 local harness 0.1.5-rc.1(npm 私有包)的隔离 consumer 中完成全链路验证:

  • 类型/运行时:peer 为 @deepseek-ai/cordis: ^4.0.1 + @deepseek-ai/dsh-tools: >=0.0.1-rc.1 <0.2.0 + @deepseek-ai/dsh-invariants: >=0.0.1-rc.1 <0.2.0;不再依赖 unscoped cordis
  • 独立构建:npm install(devDependencies 自包含 typescript/vitest/@types/node)→ npm run typecheck → npm test → npm run build → npm pack
  • 消费验证:tarball 装入 DSH 0.1.5-rc.1(npm)consumer → dsh --profile compat --dump-config 出现本插件 row → 工具真实注册与执行通过
  • 启动方式:npx -p @deepseek-ai/dsh@next dsh web(lib 生产模式;勿 install -g 全局安装)

版本适配

  • 适配 DSH: DSH 0.1.5-rc.1(npm)(profile/bundle 插件系统)
  • bundle 声明: package.json 的 dsh.bundle(patch 指向 cordis.patch.yml)+ exports 导出
  • patch 格式: cordis.patch.yml 使用 - insert: 列表(patch 是 id-targeted 语义,裸 - id: 条目会报 entry not found)
  • files: 发布 tarball 含 lib/、src/、cordis.patch.yml

安装

Profile Bundle(推荐)

将本插件作为独立 bundle 安装到 profile(DSH 0.1.5-rc.1(npm))。本仓库位于 omdsh-dev 组织,公开可访问:

# 交互式(web)profile —— 从 GitHub 仓库安装
dsh plugin --profile web add github:omdsh-dev/dsh-tool-time
# 一次性任务(headless)profile —— dsh run 默认使用 headless
dsh plugin --profile headless add github:omdsh-dev/dsh-tool-time

或使用 npm pack 生成的 tarball 安装:

npm pack     # 生成 dsh-tool-time-<version>.tgz
# 交互式(web)profile
dsh plugin --profile web add ./dsh-tool-time-<version>.tgz
# 一次性任务(headless)profile
dsh plugin --profile headless add ./dsh-tool-time-<version>.tgz

包内 dsh.bundle.patch(指向 cordis.patch.yml)会在安装后自动把插件加入 profile 的 layer stack;插件的 cordis.patch.yml 以 - insert: 插入 tool-time 条目。插件缺失的 peer 依赖(@deepseek-ai/cordis、@deepseek-ai/dsh-tools)由 profile 的 healed profiles/node_modules 回退安装提供。

⚠️ web 与 headless 是不同 profile:web 安装不会自动覆盖 headless;dsh run 默认使用 headless profile。Windows 路径使用正斜杠(C:/...)。

验证安装

dsh --profile web --dump-config | grep tool-time

运行验证

dsh run "使用 time 工具获取当前 UTC 时间"

手动安装与旧版本兼容(monorepo 旧场景)

monorepo 方式仅适用于旧场景:不支持 Profile Bundle 的旧快照或插件开发调试环境:

  1. 放入 monorepo:cp -r time ~/.dsh/source/master/packages/tools/time(开发调试)
  2. apps/cli/package.json 加 "@deepseek-ai/dsh-tool-time": "workspace:^";tsconfig.host.json references 加 { "path": "./packages/tools/time" }
  3. pnpm install && pnpm run build
  4. 在 profile 用户层 patch 插入插件(~/.dsh/profiles/<name>/cordis.patch.yml):
- insert:
    - id: tool-time
      name: '@deepseek-ai/dsh-tool-time'
  1. 验证:dsh --profile <name> --dump-config | grep tool-time
注意:patch 是 id-targeted 语义(DSH 0.1.5-rc.1(npm))——裸 - id: 条目会报 entry "xxx" not found,必须用 - insert: 列表包裹。

已知限制

  1. 分发链路:peer 依赖(如 @deepseek-ai/dsh-tools)为 npm 私有包,独立安装不依赖 monorepo workspace(monorepo 仅旧场景)
  2. add 是 UTC 日历运算,非当地墙钟语义(当地墙钟需 v2)
  3. 不支持自然语言日期("next week")与日历月/年差(v2)
  4. 时区数据来自 Node 内置 ICU:"跨平台一致" = "相同 Node/ICU 数据下一致"
  5. 输入年份范围为 1000–9999(0000–0999 拒绝:JavaScript Date.UTC 对这些年份有 1900+ 映射的历史行为)
  6. 精度契约:iso/unix 保留毫秒;local/formatted 为秒精度展示字段
  7. offset 精度到分钟:v1 只支持现代时区;历史时区(<1900)的秒级 offset 会被截断

测试

pnpm test

功能/错误/攻击载荷共 63 个用例(fake clock、时区已知向量、月末钳制、严格 ISO 边界、年份范围、offset 跨年、极端 amount、原型链时区名等)。完整清单见本地维护的设计文档。

许可

MIT

Before you begin

Check the current repository for installation, compatible versions and licensing. Stars and catalog scores are snapshot-based browsing signals.

Installation & troubleshooting · 项目问题反馈

Related projects