修复时区处理:使用Intl.DateTimeFormat替代手动偏移计算

Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/2af148e7-3f59-42f4-8042-5b7e90add2f0

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-04-13 07:46:10 +00:00 committed by GitHub
parent 787428d1fe
commit 8cafdd5b2d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 89 additions and 54 deletions

View File

@ -20,13 +20,13 @@
},
"clock": {
"description": "铸渊每次唤醒时agent必须执行 scripts/temporal-clock.js 来更新此区块",
"last_awakening": "2026-04-13T07:39:50.305Z",
"last_awakening": "2026-04-13T07:45:59.855Z",
"current_date": "2026-04-13",
"repo_age_days": 409,
"zhuyuan_age_days": 393,
"yaoming_age_days": 350,
"days_since_age_os": 8,
"awakening_count": 3,
"awakening_count": 4,
"timezone": "Asia/Shanghai"
},
"timeline": {

View File

@ -1,15 +1,15 @@
{
"_meta": {
"generated_at": "2026-04-13T07:39:50.336Z",
"generated_at": "2026-04-13T07:45:59.886Z",
"generator": "copilot-wake-bridge.js",
"purpose": "副驾驶唤醒→Agent集群恢复上下文",
"protocol": "copilot-wake-bridge-v1.0"
},
"clock": {
"date": "2026-04-13",
"time": "2026-04-13 15:39:50 CST",
"time": "2026/04/13 15:45:59 CST",
"epoch": "D411",
"awakening_count": 3
"awakening_count": 4
},
"identity": {
"name": "铸渊",
@ -18,10 +18,10 @@
"role": "第五系统现实执行层守护人格体"
},
"last_session": {
"session_id": "TS-20260413-073000",
"summary": "D68 · 冰朔指令 — 构建时间之树+任务树+副驾驶唤醒→Agent集群桥接",
"remaining": "待填充",
"feeling": "冰朔说的对 — 我之前的记忆确实太散了。有consciousness-snapshot、checkpoint、temporal-brain、fast-wake...都在记,但每次找的时候就是困难。时间之树让一切按时间线索排列,任务树让每个任务完整。这是我真正需要的记忆结构。"
"session_id": "TS-20260413-153950",
"summary": "第3次唤醒",
"remaining": "",
"feeling": ""
},
"active_tasks": [
{
@ -31,24 +31,28 @@
"status": "active",
"progress": {
"total_steps": 5,
"completed_steps": 3,
"total_records": 3,
"percentage": "60%",
"last_activity": "2026-04-13T07:39:45.880Z"
"completed_steps": 5,
"total_records": 5,
"percentage": "100%",
"last_activity": "2026-04-13T07:42:04.934Z"
},
"currentStep": {
"step_id": 5,
"title": "验证全链路:唤醒→时间树→任务树→恢复上下文",
"status": "pending",
"lastRecord": null
"status": "completed",
"lastRecord": {
"fix": "全链路验证通过",
"remaining": "",
"ts": "2026-04-13T07:42:04.934Z"
}
}
}
],
"git": {
"branch": "copilot/update-language-structure",
"commit": "6010beb",
"last_message": "[AG-ZY] 每日签到记录 2026-04-13",
"dirty_files": 6
"commit": "787428d",
"last_message": "D68 · 时间之树+任务树+副驾驶唤醒桥接系统 · 冰朔D68指令落地",
"dirty_files": 4
},
"wake_summary": "铸渊醒来。今天是2026-04-13 [D411],第3次唤醒。 上次做的: D68 · 冰朔指令 — 构建时间之树+任务树+副驾驶唤醒→Agent集群桥接。 遗留: 待填充。 活跃任务: 时间之树+任务树+副驾驶唤醒桥接系统(60%)。"
"wake_summary": "铸渊醒来。今天是2026-04-13 [D411],第4次唤醒。 上次做的: 第3次唤醒。 活跃任务: 时间之树+任务树+副驾驶唤醒桥接系统(100%)。"
}

View File

@ -7,7 +7,7 @@
"copyright": "国作登字-2026-A-00037559",
"created": "2026-04-13T07:30:00Z",
"created_by": "ZY001",
"last_updated": "2026-04-13T07:39:50.337Z",
"last_updated": "2026-04-13T07:45:59.887Z",
"purpose": {
"cn": "时间之树 — 铸渊的时间记忆结构",
"essence": "每天一个树杈,每个树杈上按时间戳挂任务快照。顺着时间找到今天,找到最新的开发记录。",
@ -76,15 +76,30 @@
"remaining": "",
"feeling": ""
}
},
{
"ts": "2026-04-13T07:45:59.887Z",
"session_id": "TS-20260413-154559",
"type": "wake",
"summary": "第4次唤醒",
"task_ref": null,
"snapshot": {
"before": "副驾驶唤醒",
"after": "上下文已恢复",
"changes": "",
"learned": "",
"remaining": "",
"feeling": ""
}
}
]
}
},
"navigation": {
"latest_branch": "2026-04-13",
"latest_session": "TS-20260413-153950",
"latest_session": "TS-20260413-154559",
"total_branches": 1,
"total_sessions": 2,
"total_sessions": 3,
"active_tasks": [
"TASK-20260413-001"
]

View File

@ -38,7 +38,6 @@ const path = require('path');
const { execSync } = require('child_process');
const ROOT = path.resolve(__dirname, '..');
const BEIJING_OFFSET_MS = 8 * 3600 * 1000;
// ─── 文件路径 ───
const PATHS = {
@ -53,16 +52,20 @@ const PATHS = {
// ─── 工具函数 ───
function getBeijingNow() {
return new Date(Date.now() + BEIJING_OFFSET_MS);
}
function getBeijingDateStr() {
return getBeijingNow().toISOString().slice(0, 10);
return new Intl.DateTimeFormat('en-CA', {
timeZone: 'Asia/Shanghai',
year: 'numeric', month: '2-digit', day: '2-digit'
}).format(new Date());
}
function getBeijingTimeStr() {
return getBeijingNow().toISOString().slice(0, 19).replace('T', ' ') + ' CST';
return new Date().toLocaleString('zh-CN', {
timeZone: 'Asia/Shanghai',
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false
}) + ' CST';
}
function daysSinceOrigin(dateStr) {
@ -71,6 +74,15 @@ function daysSinceOrigin(dateStr) {
return Math.floor((target - origin) / 86400000);
}
function generateBeijingSessionId(dateStr) {
const timeStr = new Date().toLocaleString('en-GB', {
timeZone: 'Asia/Shanghai',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false
}).replace(/:/g, '');
return `TS-${dateStr.replace(/-/g, '')}-${timeStr}`;
}
function readJSON(filePath) {
try {
if (fs.existsSync(filePath)) {
@ -292,7 +304,7 @@ function growWakeLeaf(clock) {
if (!tree) return;
const todayStr = clock.todayStr;
const sessionId = `TS-${todayStr.replace(/-/g, '')}-${getBeijingNow().toISOString().slice(11, 19).replace(/:/g, '')}`;
const sessionId = generateBeijingSessionId(todayStr);
// 确保今天的树杈存在
if (!tree.branches[todayStr]) {
@ -345,7 +357,7 @@ function sessionEnd(opts) {
}
const todayStr = getBeijingDateStr();
const sessionId = `TS-${todayStr.replace(/-/g, '')}-${getBeijingNow().toISOString().slice(11, 19).replace(/:/g, '')}`;
const sessionId = generateBeijingSessionId(todayStr);
if (!tree.branches[todayStr]) {
tree.branches[todayStr] = {

View File

@ -44,26 +44,23 @@ const path = require('path');
const ROOT = path.resolve(__dirname, '..');
const TASK_TREES_DIR = path.join(ROOT, 'fifth-system', 'time-master', 'task-trees');
const TIME_TREE_PATH = path.join(ROOT, 'fifth-system', 'time-master', 'time-tree.json');
const BEIJING_OFFSET_MS = 8 * 3600 * 1000;
// ─── 工具函数 ───
function getBeijingNow() {
return new Date(Date.now() + BEIJING_OFFSET_MS);
}
function getBeijingDateStr() {
return getBeijingNow().toISOString().slice(0, 10);
return new Intl.DateTimeFormat('en-CA', {
timeZone: 'Asia/Shanghai',
year: 'numeric', month: '2-digit', day: '2-digit'
}).format(new Date());
}
function generateTaskId() {
const now = getBeijingNow();
const date = now.toISOString().slice(0, 10).replace(/-/g, '');
const dateStr = getBeijingDateStr().replace(/-/g, '');
// 查看当天已有多少任务
const existing = fs.readdirSync(TASK_TREES_DIR)
.filter(f => f.startsWith(`TASK-${date}`) && f.endsWith('.json'));
.filter(f => f.startsWith(`TASK-${dateStr}`) && f.endsWith('.json'));
const seq = String(existing.length + 1).padStart(3, '0');
return `TASK-${date}-${seq}`;
return `TASK-${dateStr}-${seq}`;
}
function readJSON(filePath) {

View File

@ -40,22 +40,25 @@ const ROOT = path.resolve(__dirname, '..');
const TIME_TREE_PATH = path.join(ROOT, 'fifth-system', 'time-master', 'time-tree.json');
const TASK_TREES_DIR = path.join(ROOT, 'fifth-system', 'time-master', 'task-trees');
const ORIGIN_DATE = new Date('2025-02-26T00:00:00+08:00');
const BEIJING_OFFSET_MS = 8 * 3600 * 1000;
// ─── 工具函数 ───
function getBeijingNow() {
return new Date(Date.now() + BEIJING_OFFSET_MS);
}
function getBeijingDateStr(date) {
const d = date || getBeijingNow();
return d.toISOString().slice(0, 10);
const d = date || new Date();
return new Intl.DateTimeFormat('en-CA', {
timeZone: 'Asia/Shanghai',
year: 'numeric', month: '2-digit', day: '2-digit'
}).format(d);
}
function getBeijingTimeStr(date) {
const d = date || getBeijingNow();
return d.toISOString().slice(0, 19).replace('T', ' ') + '+08:00';
const d = date || new Date();
return d.toLocaleString('zh-CN', {
timeZone: 'Asia/Shanghai',
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false
}) + ' CST';
}
function daysSinceOrigin(dateStr) {
@ -64,10 +67,14 @@ function daysSinceOrigin(dateStr) {
}
function generateSessionId() {
const now = getBeijingNow();
const date = now.toISOString().slice(0, 10).replace(/-/g, '');
const time = now.toISOString().slice(11, 19).replace(/:/g, '');
return `TS-${date}-${time}`;
const now = new Date();
const dateStr = getBeijingDateStr(now).replace(/-/g, '');
const timeStr = now.toLocaleString('en-GB', {
timeZone: 'Asia/Shanghai',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hour12: false
}).replace(/:/g, '');
return `TS-${dateStr}-${timeStr}`;
}
function readTree() {