跳到主要内容

使用 Luxon 处理日期和时间#

Luxon 是一个 JavaScript 库,可简化日期和时间处理。有关 Luxon 的完整使用说明,请参阅 Luxon 官方文档

n8n 在节点间以字符串形式传递日期,因此需要进行解析。Luxon 可简化此过程。

Python 支持说明

Luxon 是 JavaScript 库。在代码节点中使用 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)
{{$now}} // n8n displays the ISO formatted timestamp // For example 2022-03-09T14:02:37.065+00:00 {{"Today's date is " + $now}} // n8n displays "Today's date is <unix timestamp>" // For example "Today's date is 1646834498755"$now // n8n displays <ISO formatted timestamp> // For example 2022-03-09T14:00:25.058+00:00 let rightNow = "Today's date is " + $now // n8n displays "Today's date is <unix timestamp>" // For example "Today's date is 1646834498755"_now # n8n displays <ISO formatted timestamp> # For example 2022-03-09T14:00:25.058+00:00 rightNow = "Today's date is " + str(_now) # n8n displays "Today's date is <unix timestamp>" # For example "Today's date is 1646834498755"

n8n 提供内置便捷函数以支持表达式中的日期数据转换。更多信息请参阅数据转换函数 | 日期

将 JavaScript 日期转换为 Luxon#

将原生 JavaScript 日期转换为 Luxon 日期的方法:

  • 在表达式中使用.toDateTime()方法,例如 {{ (new Date()).ToDateTime() }}
  • 在代码节点中使用 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)
{{DateTime.fromISO('2019-06-23T00:00:00.00')}}let luxonDateTime = DateTime.fromISO('2019-06-23T00:00:00.00')

Luxon的API文档包含更多关于fromISO的信息。

Luxon提供处理多种格式转换的函数,具体可参阅Luxon的解析技术格式指南。

若日期字符串未采用标准格式:#

使用Luxon的特殊解析功能。通过fromFormat()函数实现,需提供日期字符串和描述格式的标记符集合

例如:将n8n创立日期"2019年6月23日"的23-06-2019格式转换为Luxon对象:

表达式(JavaScript)代码节点(JavaScript)
{{DateTime.fromFormat("23-06-2019", "dd-MM-yyyy")}}let newFormat = DateTime.fromFormat("23-06-2019", "dd-MM-yyyy")

使用临时解析时,请注意 Luxon 关于解析限制的警告。若遇到异常结果,请查阅其调试指南

获取距今日n天的日期#

获取当前日期之前或之后指定天数的日期。

表达式(JavaScript)代码节点(JavaScript)

例如:需要将字段设置为始终显示当前日期前七天的日期。

在表达式编辑器中输入:

{{$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})

例如,若需要获取当前日期前七天的日期变量,请在代码编辑器中输入:

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})

更多详细信息与示例请参考:

创建人类可读日期#

获取当前日期前后N天的示例中,通过获取当前日期前七天的日期,返回格式为 [Object: "yyyy-mm-dd-T00:00:00.000+00:00"](表达式场景)或 yyyy-mm-dd-T00:00:00.000+00:00(代码节点场景)。为提升可读性,可使用Luxon的格式化函数。

例如:若需要将日期字段格式化为DD/MM/YYYY格式,使其在2019年6月23日返回 23/06/2019

以下表达式可获取当前日期前七天的日期,并将其转换为DD/MM/YYYY格式:

表达式(JavaScript)代码节点(JavaScript)
{{$today.minus({days: 7}).toLocaleString()}}let readableSevenDaysAgo = $today.minus({days: 7}).toLocaleString()

您可以更改格式。例如:

表达式(JavaScript)代码节点(JavaScript)
{{$today.minus({days: 7}).toLocaleString({month: 'long', day: 'numeric', year: 'numeric'})}}let readableSevenDaysAgo = $today.minus({days: 7}).toLocaleString({month: 'long', day: 'numeric', year: 'numeric'})

2019年6月23日调用该方法将返回"2019年6月16日"。

更多信息请参阅Luxon指南中的toLocaleString(人类可读字符串)章节。

计算两个日期之间的时间间隔#

要计算两个日期之间的时间间隔,请使用Luxon的diffs功能。该功能通过将一个日期减去另一个日期来返回持续时间。

例如,获取两个日期之间相隔的月数:

表达式(JavaScript)代码节点(JavaScript)
{{DateTime.fromISO('2019-06-23').diff(DateTime.fromISO('2019-05-23'), 'months').toObject()}}let monthsBetweenDates = DateTime.fromISO('2019-06-23').diff(DateTime.fromISO('2019-05-23'), 'months').toObject()

这将返回 [Object: {"months":1}]

更多信息请参阅 Luxon 的 时间差计算文档

完整示例:距离圣诞节还有多少天?#

本示例综合运用了多项 Luxon 功能,结合 JMESPath 查询语言并进行基础字符串处理。

应用场景:需要实现一个每日更新的圣诞节(12月25日)倒计时功能。该倒计时需具备跨年自适应能力,无需每年手动调整。

表达式(JavaScript)代码节点(JavaScript)
{{"There are " + $today.diff(DateTime.fromISO($today.year + '-12-25'), 'days').toObject().days.toString().substring(1) + " days to Christmas!"}}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!":另一个字符串常量,通过+与前一个字符串连接