插件介绍
我们的官网静态站点 https://flashcat.cloud 是用 hugo 搭建的,站点里的页面都是使用 markdown 格式编辑的,尤其是博客和文档页面。页面一开始的部分如下所示:
title: "this is title"
description: ""
keywords: ["vscode"]
author: "巴辉特"
date: "2025-03-28T15:16:11.007+08:00"
lastmod: "2025-03-28T15:25:37.094+08:00"
核心摘要
- Hugo Markdown 通常会在 front matter 中维护
date和lastmod,手动输入 ISO 8601 时间容易麻烦,也容易格式不一致。 insertisodate是一个 VSCode 插件,可以在光标位置插入当前 ISO 8601 时间,也可以替换当前选中的文本。- 这个插件适合静态站点写作、博客更新、文档维护等需要频繁维护时间字段的场景。
- 核心逻辑很简单:格式化当前本地时间,然后通过 VSCode Extension API 写入当前编辑器。
- 代码已放到 GitHub,插件也可以在 VSCode 插件市场搜索
insertisodate。
为了 SEO 友好,每次新建页面的时候要配置 date 字段,每次修改页面的时候,又要更新 lastmod 字段为当前时间,每次手动输入这个时间有点麻烦,所以我写了一个 vscode 插件,方便在 hugo markdown 中输入 ISO 8601 格式的时间。如果你也需要,在 vscode 插件市场搜索 insertisodate,就能找到这个插件了。

使用方法也很简单,在你想要输出时间的地方,按下 Command + Shift + P( Windows下面可能是 Ctrl + Shift + P ),输入 Insert ISO Date,就能插入当前时间了。
可以把使用场景概括为一句话:当你正在编辑 Hugo front matter 中的 date 或 lastmod 字段时,用插件插入当前时间,比手动敲完整 ISO 8601 字符串更稳。
插件原理
插件编写非常简单,我是参考这个文章走通的整个流程。核心代码如下:
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const vscode = require('vscode');
function formatCurrentTime() {
const currentTime = new Date();
const year = currentTime.getFullYear();
const month = String(currentTime.getMonth() + 1).padStart(2, '0');
const day = String(currentTime.getDate()).padStart(2, '0');
const hours = String(currentTime.getHours()).padStart(2, '0');
const minutes = String(currentTime.getMinutes()).padStart(2, '0');
const seconds = String(currentTime.getSeconds()).padStart(2, '0');
const milliseconds = String(currentTime.getMilliseconds()).padStart(3, '0');
const timezoneOffset = -currentTime.getTimezoneOffset();
const timezoneHours = String(Math.floor(Math.abs(timezoneOffset) / 60)).padStart(2, '0');
const timezoneMinutes = String(Math.abs(timezoneOffset) % 60).padStart(2, '0');
const timezoneSign = timezoneOffset >= 0 ? '+' : '-';
const timezone = `${timezoneSign}${timezoneHours}:${timezoneMinutes}`;
return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}${timezone}`;
}
// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
/**
* @param {vscode.ExtensionContext} context
*/
function activate(context) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "insertisodate" is now active!');
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
const disposable = vscode.commands.registerCommand('insertisodate.insert', function () {
let editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
// get current date
let dateString = formatCurrentTime();
editor.edit(function (text) {
// get current selection
let selection = editor.selection;
if (!selection.isEmpty) {
// Replace selected text with dateString
text.replace(selection, dateString);
} else {
// Insert dateString at current cursor position
let startLine = selection.start.line;
let startCharacter = selection.start.character;
text.insert(new vscode.Position(startLine, startCharacter), dateString);
}
});
});
context.subscriptions.push(disposable);
}
// This method is called when your extension is deactivated
function deactivate() { }
module.exports = {
activate,
deactivate
}
其中,formatCurrentTime 是一个工具方法,让 ChatGPT 生成的,其他代码是插件框架代码,由框架脚手架生成的,最核心的逻辑是下面几行代码:
// get current date
let dateString = formatCurrentTime();
editor.edit(function (text) {
// get current selection
let selection = editor.selection;
if (!selection.isEmpty) {
// Replace selected text with dateString
text.replace(selection, dateString);
} else {
// Insert dateString at current cursor position
let startLine = selection.start.line;
let startCharacter = selection.start.character;
text.insert(new vscode.Position(startLine, startCharacter), dateString);
}
});
这段代码的意思是,如果当前有选中的文本,就用当前时间替换掉选中的文本;如果没有选中的文本,就在光标处插入当前时间。这样就能实现我们想要的功能了。这个项目的代码我放到 github 上了,地址如下 👇
适用场景和边界
insertisodate 不是一个复杂的 Hugo 管理工具,它只解决一个小问题:把当前时间按 ISO 8601 格式快速写入编辑器。它适合这些场景:
- 新建博客时填写
date字段。 - 修改文章后更新
lastmod字段。 - 在 Markdown、YAML 或其他文本文件中插入标准时间戳。
- 替换已经选中的旧时间字符串。
它不负责解析 Hugo front matter,也不自动判断你应该更新哪个字段。因此使用时仍然要确认光标位置或选中文本是正确的。
常见问题
为什么 Hugo 文章要维护 lastmod?
lastmod 可以表达内容最近修改时间。对于静态站点来说,它有助于让页面元信息更清楚,也方便后续生成站点地图或给搜索引擎提供更新信号。
插件插入的是 UTC 时间还是本地时间?
代码使用 JavaScript Date 对象读取当前本地时间,并根据本机时区偏移生成带时区的 ISO 8601 字符串,例如 +08:00。
这个插件只能用于 Hugo 吗?
不是。它只是插入时间字符串,因此任何需要 ISO 8601 时间的文本编辑场景都可以用。只是作者最初的需求来自 Hugo Markdown。
总结
这个 VSCode 插件的价值不在复杂,而在高频小动作自动化。写 Hugo 博客时,date 和 lastmod 每次都手敲很容易烦,也容易出格式问题。insertisodate 用一个命令把当前 ISO 8601 时间插入到编辑器,刚好解决这个具体痛点。
Enjoy!