我写了一个 vscode 插件,方便在 hugo markdown 中输入 ISO 8601 格式的时间

介绍 VSCode 插件 insertisodate:在 Hugo Markdown 中一键插入 ISO 8601 时间,方便维护 date 和 lastmod 字段,并说明核心实现代码和适用场景。

作者 巴辉特

插件介绍

我们的官网静态站点 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 中维护 datelastmod,手动输入 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 中的 datelastmod 字段时,用插件插入当前时间,比手动敲完整 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 上了,地址如下 👇

https://github.com/sretalk/insertisodate

适用场景和边界

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 博客时,datelastmod 每次都手敲很容易烦,也容易出格式问题。insertisodate 用一个命令把当前 ISO 8601 时间插入到编辑器,刚好解决这个具体痛点。

Enjoy!

延伸路径

继续看解决方案和产品对比

如果你正在做监控、可观测性或故障定位相关选型,建议从解决方案和产品对比继续往下看。

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云