diff --git a/_includes/post.njk b/_includes/post.njk index cfc157f..7520321 100644 --- a/_includes/post.njk +++ b/_includes/post.njk @@ -6,7 +6,7 @@ layout: base.njk

{{ title }}

- {% if updatedAt %} + {% if updatedAt and (updatedAt | isMoreThanHourAfter(createdAt)) %}

Updated:

{% endif %}
diff --git a/eleventy.config.js b/eleventy.config.js index ccf1548..0d12675 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -4,6 +4,7 @@ const markdownItFootnote = require("markdown-it-footnote"); const markdownItMermaid = require('markdown-it-mermaid').default const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); const fs = require("fs"); +const { DateTime } = require("luxon"); const tagPattern = /(?<=^|\s)#([a-zA-Z][a-zA-Z0-9_]*)(?![a-zA-Z0-9_-])/g; @@ -111,18 +112,30 @@ module.exports = (eleventyConfig) => { eleventyConfig.setLibrary("md", md); eleventyConfig.addFilter("dateFormat", (date) => { - const d = new Date(date); - return d.toLocaleDateString('en-US', { - year: 'numeric', - month: 'long', - day: 'numeric', - timeZone: 'UTC' - }); + const dt = date instanceof Date + ? DateTime.fromJSDate(date) + : DateTime.fromISO(date); + return dt.toFormat('MMMM d, yyyy'); }); eleventyConfig.addFilter("isoDate", (date) => { - const d = new Date(date); - return d.toISOString().split('T')[0]; + const dt = date instanceof Date + ? DateTime.fromJSDate(date) + : DateTime.fromISO(date); + return dt.toISODate(); + }); + + eleventyConfig.addFilter("isMoreThanHourAfter", (date1, date2) => { + if (!date1 || !date2) return false; + const toDateTime = (d) => { + if (DateTime.isDateTime(d)) return d; + if (d instanceof Date) return DateTime.fromJSDate(d); + return DateTime.fromISO(d); + }; + const dt1 = toDateTime(date1); + const dt2 = toDateTime(date2); + const diff = dt1.diff(dt2, 'hours').hours; + return Math.abs(diff) > 1; }); eleventyConfig.addCollection("posts", (collectionApi) => { diff --git a/package.json b/package.json index e70f9f2..425d60c 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dependencies": { "@11ty/eleventy": "^3.1.2", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2", + "luxon": "^3.7.2", "markdown-it": "^14.1.0", "markdown-it-container": "^4.0.0", "markdown-it-footnote": "^4.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a06652..fc839f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@11ty/eleventy-plugin-syntaxhighlight': specifier: ^5.0.2 version: 5.0.2 + luxon: + specifier: ^3.7.2 + version: 3.7.2 markdown-it: specifier: ^14.1.0 version: 14.1.0 diff --git a/posts/posts.11tydata.js b/posts/posts.11tydata.js index c4a9da2..814dfdc 100644 --- a/posts/posts.11tydata.js +++ b/posts/posts.11tydata.js @@ -1,6 +1,7 @@ const path = require("path"); const fs = require("fs"); const { execSync } = require("child_process"); +const { DateTime } = require("luxon"); const getGitCreatedTime = (filePath) => { try { @@ -9,7 +10,7 @@ const getGitCreatedTime = (filePath) => { { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] } ).trim(); if (result) { - return new Date(result); + return DateTime.fromISO(result); } } catch (e) { // Git command failed, return null @@ -24,7 +25,7 @@ const getGitModifiedTime = (filePath) => { { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] } ).trim(); if (result) { - return new Date(result); + return DateTime.fromISO(result); } } catch (e) { // Git command failed, return null @@ -43,7 +44,8 @@ const getTitleFromFilename = (filePath) => { const getFileCreatedTime = (filePath) => { try { const stats = fs.statSync(filePath); - return stats.birthtime || stats.mtime; + const time = stats.birthtime ?? stats.mtime; + return DateTime.fromJSDate(time); } catch (e) { return null; } @@ -52,7 +54,7 @@ const getFileCreatedTime = (filePath) => { const getFileModifiedTime = (filePath) => { try { const stats = fs.statSync(filePath); - return stats.mtime; + return DateTime.fromJSDate(stats.mtime); } catch (e) { return null; } @@ -60,9 +62,10 @@ const getFileModifiedTime = (filePath) => { const parseDate = (value) => { if (!value) return null; - if (value instanceof Date) return value; - const parsed = new Date(value); - return isNaN(parsed.getTime()) ? null : parsed; + if (DateTime.isDateTime(value)) return value; + if (value instanceof Date) return DateTime.fromJSDate(value); + const parsed = DateTime.fromISO(value); + return parsed.isValid ? parsed : null; } const getPostCreatedAt = (data) => { @@ -79,7 +82,7 @@ const getPostCreatedAt = (data) => { return fileDate; } - return data.page.date; + return DateTime.fromJSDate(data.page.date); } module.exports = { @@ -95,19 +98,9 @@ module.exports = { }, createdAt: getPostCreatedAt, updatedAt: (data) => { - const modifiedDate = parseDate(data.updatedAt) ?? + return parseDate(data.updatedAt) ?? getGitModifiedTime(data.page.inputPath) ?? getFileModifiedTime(data.page.inputPath); - const createdDate = getPostCreatedAt(data); - - if (modifiedDate) { - // Only return updatedAt if it's AFTER created date (by more than a day) - const dayInMs = 24 * 60 * 60 * 1000; - if (modifiedDate > createdDate && (modifiedDate - createdDate) > dayInMs) { - return modifiedDate; - } - } - return createdDate; }, permalink: (data) => { const title = data.title || getTitleFromFilename(data.page.inputPath); @@ -115,7 +108,7 @@ module.exports = { const createdDate = getPostCreatedAt(data); - const isoDate = createdDate.toISOString().split('T')[0]; + const isoDate = createdDate.toISODate(); return `/post/${slug}/${isoDate}/`; } }