【n8n教程】:Luxon日期时间处理,打造智能时间自动化工作流

【n8n教程】:Luxon日期时间处理,打造智能时间自动化工作流

在自动化工作流中,日期和时间数据处理是最常见的需求之一。无论是计算两个日期之间的天数、格式化日期显示,还是处理不同时区的时间,n8n 的 Luxon 库都能完美解决。本教程将带你从零开始,学会在 n8n 中高效使用 Luxon,让日期时间处理变得简单易懂。

点击获取最新AI资讯、n8n工作流、开发经验分享

🎯 核心概念:什么是 Luxon?

Luxon 是一个功能强大的 JavaScript 日期时间库,专门为了解决原生 JavaScript Date 对象的复杂性而创建。它提供了更加直观和易用的 API,让你能够轻松处理:

  • ✅ 日期的解析和格式化
  • ✅ 时区转换
  • ✅ 日期计算(加减天数、月份等)
  • ✅ 两个日期之间的时间差计算
  • ✅ 人类可读的日期格式输出

为什么选择 Luxon 而不是原生 JavaScript?

原生 JavaScript:

javascript 复制代码
// ❌ 不够直观,需要记住很多 API 细节
new Date('2019-06-23')  // 容易出错,可能产生错误的时区

Luxon:

javascript 复制代码
// ✅ 清晰明确,指定格式
DateTime.fromISO('2019-06-23')
DateTime.fromFormat("23-06-2019", "dd-MM-yyyy")

🔧 n8n 中的 Luxon 快速开始

两个黄金变量

n8n 为你提供了两个内置的时间变量,无需额外导入:

变量 说明 示例输出
$now 当前时刻(精确到秒) 2025-12-05T11:21:00.000+00:00
$today 当前日期(时间部分为 00:00:00) 2025-12-05T00:00:00.000+00:00

重点:这两个变量可以在:

  • 📝 表达式编辑器 中使用(使用 {``{}} 包裹)
  • 💻 Code 节点 中使用(直接使用 $now$today

📚 常见应用场景详解

场景 1️⃣:获取当前日期和时间

需求:在工作流中获取当前时刻

在表达式中:

javascript 复制代码
// 获取当前时刻(包含时间)
{{$now}}

// 获取当前日期(不包含时间,午夜)
{{$today}}

在 Code 节点中:

javascript 复制代码
// 当前时刻对象
const now = $now;
console.log(now);  // 输出 Luxon DateTime 对象

// 当前日期对象
const today = $today;
console.log(today);

场景 2️⃣:日期向前或向后推移

需求:获取 7 天前的日期,或 30 天后的日期

在表达式中:

javascript 复制代码
// 获取 7 天前的日期
{{$today.minus({days: 7})}}

// 获取 30 天后的日期
{{$today.plus({days: 30})}}

// 获取 3 个月前的日期
{{$today.minus({months: 3})}}

// 获取 1 年后的日期
{{$today.plus({years: 1})}}

在 Code 节点中:

javascript 复制代码
// 7 天前
let sevenDaysAgo = $today.minus({days: 7});

// 结合多个时间单位
let futureDate = $today.plus({
  years: 1,
  months: 2,
  days: 15
});

// 输出给下一个节点
return [{json: {sevenDaysAgo, futureDate}}];

场景 3️⃣:日期格式化(重点!)

需求:将日期转换为易读的格式

常用格式转换:

javascript 复制代码
// 表达式方式
{{$today.toLocaleString()}}                    // 23/06/2019(地区格式)
{{$today.toFormat("dd/MM/yyyy")}}             // 23/06/2019
{{$today.toFormat("MMMM dd, yyyy")}}          // June 23, 2019
{{$today.toFormat("yyyy-MM-dd HH:mm:ss")}}    // 2019-06-23 14:30:45

// Code 节点方式
let dateString = $today.toFormat("dd/MM/yyyy");
let humanReadable = $today.toLocaleString();

格式化标记速查表

标记 说明 示例
yyyy 4 位年份 2025
MM 2 位月份 01, 12
dd 2 位日期 05, 25
HH 24 小时制小时 00, 23
mm 分钟 00, 59
ss 秒钟 00, 59
MMMM 月份全名 January, December
MMM 月份缩写 Jan, Dec
EEEE 星期全名 Monday, Sunday
EEE 星期缩写 Mon, Sun

场景 4️⃣:字符串转换为 Luxon 日期

需求:处理来自其他节点的日期字符串

从标准格式转换(ISO 8601):

javascript 复制代码
// 表达式方式
// 假设输入数据中有一个 date 字段,值为 "2019-06-23"
{{DateTime.fromISO($json.date)}}

// Code 节点方式
const luxonDate = DateTime.fromISO("2019-06-23");

从自定义格式转换:

javascript 复制代码
// 假设日期格式为 "23-06-2019"
// 表达式方式
{{DateTime.fromFormat($json.date, "dd-MM-yyyy")}}

// Code 节点方式
const luxonDate = DateTime.fromFormat("23-06-2019", "dd-MM-yyyy");
const luxonDate2 = DateTime.fromFormat($json.dateField, "dd/MM/yyyy");

⚠️ 重要 :注意格式标记的大小写,YYYYyyyy 的含义不同!


场景 5️⃣:计算两个日期之间的差值

需求:计算订单创建到现在已经过了多少天

在表达式中:

javascript 复制代码
// 计算从某个日期到今天经过了多少天
{{$today.diff(DateTime.fromISO($json.orderDate), 'days').toObject().days}}

// 计算距离圣诞节还有多少天
{{$today.diff(DateTime.fromISO($today.year + '-12-25'), 'days').toObject().days}}

在 Code 节点中:

javascript 复制代码
// 从 order_date 到现在的天数差
const orderDate = DateTime.fromISO($json.order_date);
const daysDiff = $today.diff(orderDate, 'days').toObject();
console.log(`距离订单创建已经 ${daysDiff.days} 天`);

// 同时获取多个时间单位
const duration = $today.diff(orderDate, ['years', 'months', 'days']).toObject();
console.log(`${duration.years} 年 ${duration.months} 个月 ${duration.days} 天`);

return [{json: {daysPassed: daysDiff.days, duration}}];

场景 6️⃣:时区处理

n8n 中的时区规则

n8n 默认使用的时区是 美国纽约时区 (America/New York),但你可以在工作流设置中修改。所有 Luxon 操作都会遵守这个时区设置。

javascript 复制代码
// 在表达式中查看当前时区
{{$today}}  // 会基于实例或工作流的时区设置

// 如果需要特定时区,在 Code 节点中:
const tokioTime = $now.setZone('Asia/Tokyo');
const nyTime = $now.setZone('America/New_York');

console.log(tokioTime.toLocaleString());  // 东京时间,易读格式
console.log(nyTime.toLocaleString());     // 纽约时间,易读格式

💡 综合案例:自动生成周报

现在让我们组合使用所有学到的知识,创建一个实用的工作流:自动生成周报

工作流需求:

  1. ✅ 获取上周的开始日期和结束日期
  2. ✅ 生成周报时间范围的文字描述
  3. ✅ 计算距离本周末还有多少天
  4. ✅ 生成易读的周报标题

工作流 JSON(可直接导入 n8n):

json 复制代码
{
  "nodes": [
    {
      "parameters": {},
      "id": "abc123start",
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [250, 300]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "code": "// 计算上周的日期范围\nconst today = $today;\n\n// 上周的第一天(上周一)\nconst lastMonday = today.minus({days: today.weekday}).minus({days: 6});\n\n// 上周的最后一天(上周日)\nconst lastSunday = lastMonday.plus({days: 6});\n\n// 周报的标题\nconst reportTitle = `周报 (${lastMonday.toFormat('MM/dd')} - ${lastSunday.toFormat('MM/dd')})`;\n\n// 距离本周末的天数\nconst daysToWeekend = today.diff(\n  today.endOf('week'), \n  'days'\n).toObject().days;\n\n// 返回结果\nreturn [{\n  json: {\n    weekStart: lastMonday.toFormat('yyyy-MM-dd'),\n    weekEnd: lastSunday.toFormat('yyyy-MM-dd'),\n    reportTitle: reportTitle,\n    daysToWeekend: Math.abs(daysToWeekend),\n    formattedRange: `${lastMonday.toFormat('MMMM dd')} 至 ${lastSunday.toFormat('MMMM dd, yyyy')}`,\n    generatedAt: $now.toFormat('yyyy-MM-dd HH:mm:ss')\n  }\n}];"
      },
      "id": "def456code",
      "name": "生成周报日期",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "position": [450, 300]
    },
    {
      "parameters": {
        "jsonData": "={\"weeklyReport\": $('生成周报日期').first().json}"
      },
      "id": "ghi789output",
      "name": "输出结果",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [650, 300]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "生成周报日期",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "生成周报日期": {
      "main": [
        [
          {
            "node": "输出结果",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "timezone": "Asia/Shanghai"
  }
}

工作流输出示例:

当你运行这个工作流时,会得到类似这样的输出:

json 复制代码
{
  "weekStart": "2025-11-24",
  "weekEnd": "2025-11-30",
  "reportTitle": "周报 (11/24 - 11/30)",
  "daysToWeekend": 4,
  "formattedRange": "November 24 至 November 30, 2025",
  "generatedAt": "2025-12-05 11:21:30"
}

🎓 学习总结

快速参考表

需求 表达式示例 Code 节点示例
当前日期 {``{$today}} const date = $today;
7天前 {``{$today.minus({days: 7})}} $today.minus({days: 7})
格式化 {``{$today.toFormat("dd/MM/yyyy")}} $today.toFormat("dd/MM/yyyy")
字符串转日期 {``{DateTime.fromISO($json.date)}} DateTime.fromISO("2025-12-05")
计算差值 {``{$today.diff(date, 'days')}} $today.diff(date, ['days'])

3个黄金法则

  1. 🎯 始终使用 Luxon 函数进行格式转换 - 不要用原生 JavaScript Date 对象
  2. 🎯 记住格式标记区分大小写 - yyyyYYYY 不一样
  3. 🎯 在表达式中用 {``{}} 包裹,Code 节点中直接使用 - 两种方式都支持

🚀 进阶技巧

✨ 技巧 1:链式调用

javascript 复制代码
// 一行代码完成多个操作
const result = $today
  .minus({days: 7})                    // 7天前
  .endOf('week')                       // 周末
  .toFormat('MMMM dd, yyyy');          // 格式化

// 结果:如果今天是 12月5日,则输出 November 30, 2025

✨ 技巧 2:条件判断

javascript 复制代码
// 判断是否超期
const dueDate = DateTime.fromISO($json.dueDate);
const isOverdue = $today > dueDate;

// 在表达式中
{{$today > DateTime.fromISO($json.deadline) ? "已超期" : "未超期"}}

✨ 技巧 3:循环处理多个日期

javascript 复制代码
// 在 Code 节点中处理数组
const dates = $json.datesList;
const formattedDates = dates.map(date => 
  DateTime.fromISO(date).toFormat('yyyy-MM-dd')
);

return [{json: {formatted: formattedDates}}];

⚠️ 常见错误及解决方案

错误 原因 解决方案
Cannot read property 'minus' 传入了字符串而非 Luxon 对象 使用 DateTime.fromISO() 转换
日期格式不对 格式标记错误 检查大小写,参考标记速查表
时区不对 没有设置工作流时区 在工作流设置中修改时区
undefined 错误 使用了不存在的字段 检查数据源是否真的有该字段

相关推荐
Surmon2 小时前
基于 Cloudflare 生态的 AI Agent 实现
前端·人工智能·架构
冷小鱼7 小时前
pgvector 向量数据库完全指南:PostgreSQL 生态的 AI 增强
数据库·人工智能·postgresql
陈天伟教授7 小时前
人工智能应用- 天文学家的助手:08. 星系定位与分类
前端·javascript·数据库·人工智能·机器学习
啵啵鱼爱吃小猫咪7 小时前
机械臂阻抗控制github项目-mujoco仿真
开发语言·人工智能·python·机器人
放下华子我只抽RuiKe57 小时前
算法的试金石:模型训练、评估与调优的艺术
人工智能·深度学习·算法·机器学习·自然语言处理·数据挖掘·线性回归
songyuc8 小时前
【PyTorch】感觉`CrossEntropyLoss`和`BCELoss`很类似,为什么它们接收labels的shape常常不一样呢?
人工智能·pytorch·python
renhongxia18 小时前
如何对海洋系统进行知识图谱构建?
人工智能·学习·语言模型·自然语言处理·自动化·知识图谱
浑水摸鱼仙君8 小时前
SpringSecurity和Flux同时使用报未认证问题
java·ai·flux·springsecurity·springai