问题描述
我正在寻找纯 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}
是保存完整时区名称的环境变量,即“美国/东部”。但是对于 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
对象查看的文档指出可以使用 Time
创建 timezone
对象:
或时区对象:
tz = timezone("Europe/athens") # Eastern European Time,UTC+2
Time.new(2002,10,31,2,tz) #=> 2002-10-31 02:02:02 +0200
然后我可以用它来提取偏移量,但我在任何地方都找不到对 timezone
的引用。
处理这个问题的最佳方法是什么?
解决方法
时区是 TZInfo 类的一部分。你需要要求它。以下代码
{
allFile {
edges {
node {
extension
dir
modifiedTime
}
}
}
}
当 $TIMEZONE 为“美国/东部”时,我会收到 ruby {
code => '
require "tzinfo"
tz = TZInfo::Timezone.get(ENV["TIMEZONE"])
event.set("offset",tz.observed_utc_offset())
'
}
。