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

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

🎯 核心概念:什么是 Luxon?

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

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

原生 JavaScript:


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

Luxon:


    
    
    
  // ✅ 清晰明确,指定格式
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

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


📚 常见应用场景详解

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

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

在表达式中:


    
    
    
  // 获取当前时刻(包含时间)
{{$now}}

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

{{$today}}

在 Code 节点中:


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

// 当前日期对象

const
 today = $today;
console
.log(today);

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

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

在表达式中:


    
    
    
  // 获取 7 天前的日期
{{$today.minus({days: 7})}}

// 获取 30 天后的日期

{{$today.plus({days: 30})}}

// 获取 3 个月前的日期

{{$today.minus({months: 3})}}

// 获取 1 年后的日期

{{$today.plus({years: 1})}}

在 Code 节点中:


    
    
    
  // 7 天前
let
 sevenDaysAgo = $today.minus({days: 7});

// 结合多个时间单位

let
 futureDate = $today.plus({
  years
: 1,
  months
: 2,
  days
: 15
});

// 输出给下一个节点

return
 [{json: {sevenDaysAgo, futureDate}}];

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

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

常用格式转换:


    
    
    
  // 表达式方式
{{$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();

格式化标记速查表

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

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

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

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


    
    
    
  // 表达式方式
// 假设输入数据中有一个 date 字段,值为 "2019-06-23"

{{DateTime.fromISO($json.date)}}

// Code 节点方式

const
 luxonDate = DateTime.fromISO("2019-06-23");

从自定义格式转换:


    
    
    
  // 假设日期格式为 "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️⃣:计算两个日期之间的差值

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

在表达式中:


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

// 计算距离圣诞节还有多少天

{{$today.diff(DateTime.fromISO($today.year + '-12-25'), 'days').toObject().days}}

在 Code 节点中:


    
    
    
  // 从 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 操作都会遵守这个时区设置。


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

// 如果需要特定时区,在 Code 节点中:

const
 tokioTime = $now.setZone('Asia/Tokyo');
const
 nyTime = $now.setZone('America/New_York');

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

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

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

工作流需求:

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

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


    
    
    
  {
  "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"
  }

}

工作流输出示例:

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


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

🚀 进阶技巧

✨ 技巧 1:链式调用


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

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

✨ 技巧 2:条件判断


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

// 在表达式中

{{$today > DateTime.fromISO($json.deadline) ? "已超期" : "未超期"}}

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


    
    
    
  // 在 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 错误使用了不存在的字段检查数据源是否真的有该字段

引用链接

[1] 官方文档: https://docs.n8n.io/code/cookbook/luxon/
[2] n8n系列教程: https://www.undsky.com/blog/?category=n8n%E6%95%99%E7%A8%8B#