N8N中文教程
代码开发/Cookbook

使用 Luxon 处理日期和时间#

Luxon 是一个 JavaScript 库,用于简化日期和时间的操作。有关如何使用 Luxon 的完整说明,请参考 Luxon 官方文档。 n8n 在节点之间传递日期时以字符串形式传输,因此你需要对其进行解析。Luxon 让这一过程更加简便。

Python 支持

Luxon 是一个 JavaScript 库。在代码节点(Code node)中使用 Python 时,n8n 提供的两个便捷 变量 可用,但其功能有限:

  • 你无法在这两个变量上执行 Luxon 操作。例如,Python 中没有与 $today.minus(...) 对应的等效方法。
  • 通用的 Luxon 功能(如 将日期字符串转换为 Luxon 对象)对 Python 用户不可用。

n8n 中的日期和时间行为#

请注意以下几点:

  • 在工作流中,n8n 会在节点之间将日期和时间转换为字符串。当你对来自其他节点的日期和时间进行算术运算时,请牢记这一点。
  • 使用原生 JavaScript,你可以通过 new Date('2019-06-23') 将字符串转换为日期。而在 Luxon 中,你必须显式使用指定格式的函数,例如 DateTime.fromISO('2019-06-23')DateTime.fromFormat("23-06-2019", "dd-MM-yyyy")

在 n8n 中设置时区#

Luxon 使用 n8n 的时区设置。该值可能为以下之一:

  • 默认值:America/New_York
  • 通过环境变量 GENERIC_TIMEZONE 为你的 n8n 实例设置的自定义时区。
  • 在工作流设置中为单个工作流配置的自定义时区。

常见任务#

本节提供了一些常见操作的示例。更多示例和详细指导,请参阅 Luxon 官方文档。

获取当前日期或时间#

使用 $now$today Luxon 对象 来获取当前时间或日期:

  • now:包含当前时间戳的 Luxon 对象。等同于 DateTime.now()
  • today:包含当前时间戳的 Luxon 对象,但已向下取整到当日零点。等同于 DateTime.now().set({ hour: 0, minute: 0, second: 0, millisecond: 0 })

请注意,当这些变量被转换为字符串时,可能会返回不同的时间格式: 表达式(JavaScript)代码节点(JavaScript)代码节点(Python)

1
2
3
4
5
6

| ``` {{$now}} // n8n 显示 ISO 格式的时间戳 // 例如:2022-03-09T14:02:37.065+00:00 {{"Today's date is "+$now}} // n8n 显示 "Today's date is " // 例如:"Today's date is 1646834498755"


---|---

1 2 3 4 5 6

| ```
$now
// n8n 显示 <ISO 格式的时间戳>
// 例如:2022-03-09T14:00:25.058+00:00
letrightNow="Today's date is "+$now
// n8n 显示 "Today's date is <unix timestamp>"
// 例如:"Today's date is 1646834498755"

---|---

1
2
3
4
5
6

| ``` _now

n8n 显示 <ISO 格式的时间戳>

例如:2022-03-09T14:00:25.058+00:00

rightNow = "Today's date is " + str(_now)

n8n 显示 "Today's date is "

例如:"Today's date is 1646834498755"


---|---
n8n 提供了内置的便捷函数,用于在表达式中对日期进行数据转换。更多信息请参见 数据转换函数 | 日期 (Data transformation functions | Dates)。
### 将 JavaScript 日期转换为 Luxon#
要将原生 JavaScript 日期转换为 Luxon 日期:
  * 在表达式中,使用 .toDateTime() 方法。例如:`{{ (new Date()).toDateTime() }}`。
  * 在代码节点(Code node)中,使用 `DateTime.fromJSDate()`。例如:`let luxondate = DateTime.fromJSDate(new Date())`。

### 将日期字符串转换为 Luxon#
你可以将日期字符串和其他日期格式转换为 Luxon 的 DateTime 对象。支持标准格式以及任意字符串的转换。

Luxon DateTime 与 JavaScript Date 的区别
在原生 JavaScript 中,你可以通过 `new Date('2019-06-23')` 将字符串转换为日期。而在 Luxon 中,你必须显式指定格式的函数,例如使用 `DateTime.fromISO('2019-06-23')` 或 `DateTime.fromFormat("23-06-2019", "dd-MM-yyyy")`。

#### 如果你的日期是受支持的标准技术格式:#
大多数情况下应使用 `fromISO()`。该方法可以从 ISO 8601 字符串创建一个 Luxon DateTime 对象。例如:
表达式(JavaScript)代码节点(JavaScript)

1

| ```
{{DateTime.fromISO('2019-06-23T00:00:00.00')}}

---|---

1

| ```
let luxonDateTime = DateTime.fromISO('2019-06-23T00:00:00.00')

---|--- Luxon 的 API 文档提供了更多关于 fromISO 的信息。 Luxon 提供了处理多种格式转换的函数。详情请参考 Luxon 的 解析技术格式(Parsing technical formats) 指南。

如果你的日期是一个非标准格式的字符串:#

使用 Luxon 的 临时解析(Ad-hoc parsing)。为此,使用 fromFormat() 函数,并提供该字符串以及描述其格式的一组 令牌(tokens)。 例如,你有 n8n 的成立日期:2019 年 6 月 23 日,格式为 23-06-2019,你想将其转换为一个 Luxon 对象: 表达式(JavaScript)代码节点(JavaScript)

1

| ``` {{DateTime.fromFormat("23-06-2019","dd-MM-yyyy")}}


---|---

1

| ```
let newFormat = DateTime.fromFormat("23-06-2019", "dd-MM-yyyy")

---|--- 使用临时解析时,请注意 Luxon 关于 限制(Limitations) 的警告。如果出现意外结果,建议参考其 调试指南(Debugging)。

获取从今天起的 N 天前或 N 天后日期#

获取相对于今天的若干天前或若干天后的日期。 表达式(JavaScript)代码节点(JavaScript) 例如,你想设置一个字段始终显示当前日期七天前的日期。 在表达式编辑器中输入:

1

| ``` {{$today.minus({days:7})}}


---|---
在 2019 年 6 月 23 日执行时,返回 `[Object: "2019-06-16T00:00:00.000+00:00"]`。
此示例为了方便使用了 n8n 的自定义变量 `$today`,它等价于 `DateTime.now().set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).minus({days: 7})`。
再比如,你想创建一个变量,包含当前日期七天前的日期。
在代码编辑器中输入:

1

| ```
let sevenDaysAgo = $today.minus({days:7})

---|---
在 2019 年 6 月 23 日,返回 `[Object: "2019-06-16T00:00:00.000+00:00"]`。
此示例为方便起见使用了 n8n 的自定义变量 `$today`。其等价于 `DateTime.now().set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).minus({days: 7})`。
如需更详细的信息和示例,请参考:
  * Luxon 的 数学运算指南
  * 其 API 文档中的 DateTime plus 和 DateTime minus


### 创建人类可读的日期#
在 获取今天之前的 n 天 示例中,获取当前日期前七天的日期,并以 `[Object: "yyyy-mm-dd-T00:00:00.000+00:00"]`(用于表达式)或 `yyyy-mm-dd-T00:00:00.000+00:00`(在 Code 节点中)格式返回。为了提高可读性,你可以使用 Luxon 的格式化功能。
例如,你希望包含日期的字段以 DD/MM/YYYY 格式显示,这样在 2019 年 6 月 23 日时,返回 `23/06/2019`。
以下表达式获取今天之前七天的日期,并将其转换为 DD/MM/YYYY 格式。
表达式 (JavaScript)Code 节点 (JavaScript)

1

| ```
{{$today.minus({days:7}).toLocaleString()}}

---|---

1

| ``` let readableSevenDaysAgo = $today.minus({days:7}).toLocaleString()


---|---
你可以更改格式。例如:
表达式 (JavaScript)Code 节点 (JavaScript)

1

| ```
{{$today.minus({days:7}).toLocaleString({month:'long', day:'numeric', year:'numeric'})}}

---|--- 在 2019 年 6 月 23 日,此表达式返回 "16 June 2019"。

1

| ``` let readableSevenDaysAgo = $today.minus({days:7}).toLocaleString({month:'long', day:'numeric', year:'numeric'})


---|---
在 2019 年 6 月 23 日,此代码返回 "16 June 2019"。
更多信息请参阅 Luxon 关于 toLocaleString(面向人类的字符串) 的指南。
### 获取两个日期之间的时间间隔#
要获取两个日期之间的时间间隔,请使用 Luxon 的 diff 功能。它会从一个日期减去另一个日期,并返回一个持续时间(duration)。
例如,获取两个日期之间的月份数:
表达式 (JavaScript)Code 节点 (JavaScript)

1

| ```
{{DateTime.fromISO('2019-06-23').diff(DateTime.fromISO('2019-05-23'), 'months').toObject()}}

---|---
这将返回 `[Object: {"months":1}]`。

1

| ```
let monthsBetweenDates = DateTime.fromISO('2019-06-23').diff(DateTime.fromISO('2019-05-23'), 'months').toObject()

---|--- 这将返回 {"months":1}。 更多信息请参考 Luxon 的 Diffs(差值计算)。

更长的例子:距离圣诞节还有多少天?#

这个例子结合了多个 Luxon 功能,使用了 JMESPath,并进行了一些基础的字符串操作。 场景如下:你想要一个倒计时,指向每年的 12 月 25 日。每天它都会告诉你距离圣诞节还有多少天。你不想每年都手动更新年份——它需要能够无缝适用于每一年。 表达式(JavaScript)代码节点(JavaScript)

1

| ``` {{"There are "+$today.diff(DateTime.fromISO($today.year+'-12-25'),'days').toObject().days.toString().substring(1)+" days to Christmas!"}}



---|---
该表达式输出 `"There are <天数> days to Christmas!"`。例如,在 3 月 9 日运行时,输出为 "There are 291 days to Christmas!"。

以下是该表达式的详细解释:
  * `{{`:表示表达式的开始。
  * `"There are "`:一段普通字符串。
  * `+`:用于连接两个字符串。
  * `$today.diff()`:类似于 获取两个日期之间的时间间隔 中的例子,但这里使用了 n8n 自定义的 `$today` 变量。
  * `DateTime.fromISO($today.year + '-12-25'), 'days'`:这部分通过 `$today.year` 获取当前年份,将其与固定的月份和日期组合成 ISO 格式的字符串,然后将整个字符串转换为 Luxon 的 DateTime 数据结构。同时指定你希望以“天”为单位计算时间间隔。
  * `toObject()` 将 `diff()` 的结果转换为更易使用的对象格式。此时表达式的结果是 `[Object: {"days":-<天数>}]`。例如,在 3 月 9 日时,结果为 `[Object: {"days":-291}]`。
  * `.days` 使用 JMESPath 语法从对象中提取出“天数”字段的值。关于在 n8n 中使用 JMESPath 的更多信息,请参阅我们的 JMESPath 文档。此时得到的是一个负数,表示距离目标日期还剩多少天。
  * `.toString().substring(1)` 将数字转换为字符串,并移除开头的负号 `-`。
  * `+ " days to Christmas!"`:另一段字符串,用 `+` 连接到前面的结果上。
  * `}}`:表示表达式的结束。

1

| ```
let daysToChristmas = "There are " + $today.diff(DateTime.fromISO($today.year + '-12-25'), 'days').toObject().days.toString().substring(1) + " days to Christmas!";

---|---
这将输出 `"距离圣诞节还有 <天数> 天!"`。例如,在 3 月 9 日,它会输出 "距离圣诞节还有 291 天!"。
代码功能的详细说明:
  * `"There are "`:一个字符串。
  * `+`:用于连接两个字符串。
  * `$today.diff()`:类似于 获取两个日期之间的时间 中的例子,但使用了 n8n 自定义的 `$today` 变量。
  * `DateTime.fromISO($today.year + '-12-25'), 'days'`:这一部分使用 `$today.year` 获取当前年份,将其与月份和日期组合成 ISO 格式的字符串,然后将整个 ISO 字符串转换为 Luxon 的 DateTime 数据结构。同时告诉 Luxon 你希望以“天”为单位计算时间间隔。
  * `toObject()` 将 diff() 的结果转换为更易使用的对象。此时表达式返回 `[Object: {"days":-<天数>}]`。例如,在 3 月 9 日时,返回 `[Object: {"days":-291}]`。
  * `.days` 使用 JMESPath 语法从对象中提取出天数。有关在 n8n 中使用 JMESPath 的更多信息,请参考我们的 JMESpath 文档。这会得到一个表示距离圣诞节天数的负数。
  * `.toString().substring(1)` 将该数字转换为字符串并移除前面的 `-` 符号。
  * `+ " days to Christmas!"`:另一个字符串,使用 `+` 将其与前面的字符串连接起来。