将时区字符串(即 US/Eastern)转换为偏移量
Converting timezone string, i.e. US/Eastern, to offset
我正在寻找一种纯 Ruby 的方法,该方法采用诸如“US/Eastern”之类的时区字符串,并将其与时间戳的字符串表示形式一起使用,以转换为带时区的时间戳.
到目前为止我发现的是 strptime
,它支持像“EST”这样的短时区名称或像“-0500”这样的时区偏移量,但不支持完整的时区字符串。
我需要能够 运行 这作为 Logstash ruby 过滤器的一部分。我有一些 JSON 包含没有时区的时间戳,如下所示:
{
"event": {
"created": "2021-02-15_11-26-29",
},
"Accounts": [
{
"Name": "operator",
"Caption": "SERVER\operator",
"Domain": "SERVER",
"PasswordChangeable": "False",
"PasswordRequired": "True",
"PasswordExpires": "False",
"Disabled": "False",
"Lockout": "False",
"LocalAccount": "True",
"FullName": "operator",
"Status": "OK",
"LastLogon": "07/08/2020 2:14:13 PM"
},
...
]
}
对于 event.created 字段,我可以只使用 date
过滤器:
date {
match => [ "[event][created]", "yyyy-MM-dd_HH-mm-ss" ]
timezone => "${TIMEZONE}"
target => "[event][created]"
}
其中 ${TIMEZONE}
是保存完整时区名称的环境变量,即“US/Eastern”。但是对于 Acounts.LastLogin 字段我不能使用 date
过滤器,因为它驻留在一个可变长度的列表中,所以我不得不求助于 ruby 过滤器。我能得出的最接近的结果是:
ruby {
code => 'event.get("[Accounts]").each_index {|x|
tz = "-0500"
last_logon_str = event.get("[Accounts][#{x}][LastLogon]")
last_logon = DateTime.strptime(last_logon_str + " " + tz, "%m/%d/%Y %I:%M:%S %p %z")
event.set("[users][#{x}][last_logon]", last_logon.strftime("%Y-%m-%dT%H:%M:%S%z"))
}'
}
但是当然这是使用硬编码的时区偏移量而不是包含全名的变量。
我在 https://ruby-doc.org/core-2.6/Time.html 查看的 Time
对象的文档指出可以使用 timezone
:
创建 Time
对象
Or a timezone object:
tz = timezone("Europe/Athens") # Eastern European Time, UTC+2
Time.new(2002, 10, 31, 2, 2, 2, tz) #=> 2002-10-31 02:02:02 +0200
然后我可以使用它来提取偏移量,但我无法在任何地方找到对 timezone
的引用。
处理此问题的最佳方法是什么?
时区是 TZInfo class 的一部分。你需要要求它。以下代码
ruby {
code => '
require "tzinfo"
tz = TZInfo::Timezone.get(ENV["TIMEZONE"])
event.set("offset", tz.observed_utc_offset())
'
}
当 $TIMEZONE 为“US/Eastern”时 "offset" => -18000,
。
我正在寻找一种纯 Ruby 的方法,该方法采用诸如“US/Eastern”之类的时区字符串,并将其与时间戳的字符串表示形式一起使用,以转换为带时区的时间戳.
到目前为止我发现的是 strptime
,它支持像“EST”这样的短时区名称或像“-0500”这样的时区偏移量,但不支持完整的时区字符串。
我需要能够 运行 这作为 Logstash ruby 过滤器的一部分。我有一些 JSON 包含没有时区的时间戳,如下所示:
{
"event": {
"created": "2021-02-15_11-26-29",
},
"Accounts": [
{
"Name": "operator",
"Caption": "SERVER\operator",
"Domain": "SERVER",
"PasswordChangeable": "False",
"PasswordRequired": "True",
"PasswordExpires": "False",
"Disabled": "False",
"Lockout": "False",
"LocalAccount": "True",
"FullName": "operator",
"Status": "OK",
"LastLogon": "07/08/2020 2:14:13 PM"
},
...
]
}
对于 event.created 字段,我可以只使用 date
过滤器:
date {
match => [ "[event][created]", "yyyy-MM-dd_HH-mm-ss" ]
timezone => "${TIMEZONE}"
target => "[event][created]"
}
其中 ${TIMEZONE}
是保存完整时区名称的环境变量,即“US/Eastern”。但是对于 Acounts.LastLogin 字段我不能使用 date
过滤器,因为它驻留在一个可变长度的列表中,所以我不得不求助于 ruby 过滤器。我能得出的最接近的结果是:
ruby {
code => 'event.get("[Accounts]").each_index {|x|
tz = "-0500"
last_logon_str = event.get("[Accounts][#{x}][LastLogon]")
last_logon = DateTime.strptime(last_logon_str + " " + tz, "%m/%d/%Y %I:%M:%S %p %z")
event.set("[users][#{x}][last_logon]", last_logon.strftime("%Y-%m-%dT%H:%M:%S%z"))
}'
}
但是当然这是使用硬编码的时区偏移量而不是包含全名的变量。
我在 https://ruby-doc.org/core-2.6/Time.html 查看的 Time
对象的文档指出可以使用 timezone
:
Time
对象
Or a timezone object:
tz = timezone("Europe/Athens") # Eastern European Time, UTC+2 Time.new(2002, 10, 31, 2, 2, 2, tz) #=> 2002-10-31 02:02:02 +0200
然后我可以使用它来提取偏移量,但我无法在任何地方找到对 timezone
的引用。
处理此问题的最佳方法是什么?
时区是 TZInfo class 的一部分。你需要要求它。以下代码
ruby {
code => '
require "tzinfo"
tz = TZInfo::Timezone.get(ENV["TIMEZONE"])
event.set("offset", tz.observed_utc_offset())
'
}
当 $TIMEZONE 为“US/Eastern”时 "offset" => -18000,
。