将时区字符串即美国/东部转换为偏移量

问题描述

我正在寻找纯 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()) ' }