gpt4 book ai didi

ruby - Alpine Linux 上的 Rails ActiveSupport 时间和时区错误

转载 作者:行者123 更新时间:2023-12-03 14:19:52 24 4
gpt4 key购买 nike

我不知道我是不是在做蠢事,所以请耐心等待。
tl;博士 Rails ActiveSupport 时间和时区在 Alpine Linux 上似乎有错误。当它应该使用冬季时间时,它使用我的时区的 DST 变体(夏令时)。
重现步骤:

  • 在 Docker Alpine Linux Ruby 镜像中启动一个 shell:

  • $ docker run -it --rm ruby:2.7.1-alpine sh
    以下所有步骤都发生在正在运行的 docker 容器内。
  • 安装时区数据:

  • $ apk add --no-cache --update tzdata
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
    (1/1) Installing tzdata (2020c-r0)
    Executing busybox-1.31.1-r9.trigger
    OK: 23 MiB in 37 packages
  • 打印标准 ruby​​ 当前时间:

  • $ ruby -e 'puts Time.now.inspect'
    2020-10-28 20:34:24.4817918 +0000
    看起来不错。时间以 UTC 打印。
  • 除了UTC,标准ruby Time类只能处理本地时间。这取决于本地系统时区,它可以使用操作系统配置机制进行配置,或者可以简单地通过 TZ 传递给 Ruby。环境变量。让我们尝试使用我的时区“欧洲/柏林”:

  • $ TZ="Europe/Berlin" ruby -e 'puts Time.now.inspect'
    2020-10-28 21:39:22.7037648 +0100
    看起来不错。柏林时区在冬季(标准)是 UTC+01,在夏季(DST)是 UTC+02。在撰写本文时,我们有冬天,所以 +0100很好。
  • 现在让我们转到 ActiveSupport:

  • $ gem install activesupport
    Fetching tzinfo-1.2.7.gem
    Fetching i18n-1.8.5.gem
    Fetching activesupport-6.0.3.4.gem
    # #### many more lines of output ####
    Successfully installed activesupport-6.0.3.4
    6 gems installed
  • 与标准 ruby​​ 相比,ActiveSupport 支持所有可能的时区,而不仅仅是两个。获取当前时间是Time.current ,所以让我们试试这个:

  • $ ruby -e 'require "active_support/all"; puts Time.current.inspect'
    2020-10-28 20:43:51.1098842 +0000
    这看起来与步骤 3 的输出没有什么不同。原因是 Time.current仅与 Time.now 的行为不同配置时区时。
  • 我们可以使用 Time.zone=(timezone_identifier) 为 ActiveSupport 配置时区或与 Time.use_zone(timezone_identifier) { "inside this block the timezone is used" } .让我们尝试第一个变体:

  • $ ruby -e 'require "active_support/all"; Time.zone = "UTC"; puts Time.current.inspect'
    Wed, 28 Oct 2020 20:50:55 UTC +00:00
    我们仍然使用 UTC,但输出看起来与以前不同。由此我们知道我们得到了一个 ActiveSupport::TimeWithZone目的。这很好。
  • 现在我想要相同的时区:

  • $ ruby -e 'require "active_support/all"; Time.zone = "Europe/Berlin"; puts Time.current.inspect'
    Wed, 28 Oct 2020 22:52:21 CEST +02:00
    乍一看,这看起来不错,但请仔细将其与步骤 4 的输出进行比较。在“欧洲/柏林”时区中,我们目前有冬季时间 UTC+01,也称为“CET”(中欧时间)。但是这次在输出中时间戳被标记为“CEST”(中欧夏令时),即 UTC+02。
    这是错误的。
    错误在哪里?它在 Alpine Linux 中吗?它是标准的 Ruby 吗?但是第 4 步中的输出是正确的。还是 ActiveSupport 中的错误或其与时区数据的连接?难道我做错了什么?

    最佳答案

    原来这是一个影响 tzinfo 的问题。 gem(版本 < 1.2.8/< 2.0.3) - 它是 incompatible with timezone-data 2020b (以后?),以及 Alpine ship with 2020c 的最新版本.文件格式从“fat”更改为“slim”,与 tzinfo 不兼容。 gem 呢。
    更新解决方案 (2020-11-09)
    对“slim”格式 zoneinfo 文件的支持现已添加到 tzinfo发布中的 gem :

  • v1.2.8
  • v2.0.3

  • 原始 Ruby 解决方案
    您可以使用 tzinfo-data gem 而不是依赖于系统 tzinfo:
    gem install activesupport tzinfo-data
    ruby -e 'require "active_support/all"; Time.zone = "Europe/Berlin"; puts TZInfo::DataSource.get; puts Time.current.inspect'

    # Ruby DataSource
    # Thu, 29 Oct 2020 16:25:08 CET +01:00
    原始的阿尔卑斯解决方案
    您可以以 'fat' 格式( adapted from comment )重建时区数据包:
    FROM ruby:2.7.2-alpine

    # Install tzdata because we need the zic binary
    RUN apk add --no-cache tzdata

    # Fix incompatibility with slim tzdata from 2020b onwards
    RUN wget https://data.iana.org/time-zones/tzdb/tzdata.zi -O /usr/share/zoneinfo/tzdata.zi && \
    /usr/sbin/zic -b fat /usr/share/zoneinfo/tzdata.zi

    然后测试 Europe/Berlin中的时间:
    gem install activesupport
    ruby -e 'require "active_support/all"; Time.zone = "Europe/Berlin"; puts TZInfo::DataSource.get; puts Time.current.inspect'

    # Zoneinfo DataSource: /usr/share/zoneinfo
    # Thu, 29 Oct 2020 16:29:19 CET +01:00

    关于ruby - Alpine Linux 上的 Rails ActiveSupport 时间和时区错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64581249/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com