跳至内容

使用Luxon处理日期和时间#

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

n8n在节点之间传递日期时使用字符串格式,因此您需要对其进行解析。Luxon让这一过程变得更简单。

Python支持

Luxon是一个JavaScript库。当在代码节点中使用Python时,n8n创建的两个便捷变量可用,但它们的功能有限:

  • 你无法对这些变量执行Luxon操作。例如,Python中没有与$today.minus(...)等效的操作。
  • 通用的Luxon功能,例如Convert date string to Luxon,对Python用户不可用。

变量#

n8n 使用 Luxon 提供两个自定义变量:

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

请注意,这些变量在被转换为字符串时可能返回不同的时间格式。这与Luxon的DateTime.now()行为相同。

1
2
3
4
5
6
{{$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"
1
2
3
4
5
6
$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"
1
2
3
4
5
6
_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提供内置的便捷函数来支持表达式中的日期数据转换。更多信息请参考Data transformation functions | Dates

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
  • 为您的n8n实例设置自定义时区,通过GENERIC_TIMEZONE环境变量配置。
  • 在单个工作流设置中配置的自定义时区。

常见任务#

本节提供了一些常见操作的示例。更多示例及详细指南可在Luxon官方文档中查阅。

将日期字符串转换为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。例如:

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的解析技术格式指南。

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

使用Luxon的Ad-hoc解析。为此,请使用fromFormat()函数,提供字符串和一组描述格式的tokens

例如,您有n8n的创立日期,2019年6月23日,格式为23-06-2019。您想将其转换为Luxon对象:

1
{{DateTime.fromFormat("23-06-2019", "dd-MM-yyyy")}}
1
let newFormat = DateTime.fromFormat("23-06-2019", "dd-MM-yyyy")

使用临时解析时,请注意Luxon关于限制的警告。如果遇到意外结果,请尝试查阅他们的调试指南。

获取从今天起的n天#

获取今天之前或之后的若干天数。

例如,您希望将某个字段设置为始终显示当前日期前七天的日期。

在表达式编辑器中输入:

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

如需更详细的信息和示例,请参阅:

创建人类可读的日期#

获取从今天起的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格式。

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

您可以更改格式。例如:

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

2019年6月23日,这将返回"2019年6月16日"。

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

2019年6月23日,这将返回"2019年6月16日"。

更多信息请参考Luxon关于toLocaleString (面向人类的字符串)的指南。

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

要计算两个日期之间的时间差,可以使用Luxon的diffs功能。它会将一个日期减去另一个日期并返回一个持续时间段。

例如,计算两个日期之间的月份数:

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日还有多少天。每天它都应该告诉你距离圣诞节还剩多少天。你不想每年都手动更新它——它需要每年都能自动运行。

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日,它会输出"距离圣诞节还有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!": 另一个字符串,使用+与前一个字符串连接。
  • }}: 表示表达式的结束。
1
let daysToChristmas = "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日,它会输出"距离圣诞节还有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!": 另一个字符串,使用+与前一个字符串连接。
优云智算