【问题标题】:Error updating tzdata 2018f (Released 2018-10-18) with tzupdater-2.2.0使用 tzupdater-2.2.0 更新 tzdata 2018f(2018-10-18 发布)时出错
【发布时间】:2019-03-26 16:01:43
【问题描述】:

我正在尝试使用 TZUpdater 2.2.0 更新 JVM 的时区信息。

> [root@local tzupdater-2.2.0]# java -jar tzupdater.jar -V
  tzupdater version 2.2.0-b01
  JRE tzdata version: tzdata2018d
  tzupdater tool would update with tzdata version: tzdata2018f

所以,我正在运行以下命令:

> [root@local tzupdater-2.2.0]# java -jar tzupdater.jar -l

但是,我收到以下错误消息:

Failed: java.lang.Exception: Failed while parsing file '/tmp/tz.tmp_1/asia' on line 1655 'Rule  Japan   1948    1951    -   Sep Sat>=8  25:000S'
java.lang.Exception: Failed while parsing file '/tmp/tz.tmp_1/asia' on line 1655 'Rule  Japan   1948    1951    -   Sep Sat>=8  25:00   0   S'
    at tools.tzdb.TzdbZoneRulesCompiler.parseFile(TzdbZoneRulesCompiler.java:377)
    at tools.tzdb.TzdbZoneRulesCompiler.compile(TzdbZoneRulesCompiler.java:191)
    at tools.tzdb.TzdbZoneRulesCompiler.<init>(TzdbZoneRulesCompiler.java:307)
    at com.sun.tools.tzupdater.ExternalModule.compileToJSRBinary(ExternalModule.java:153)
    at com.sun.tools.tzupdater.TimezoneUpdater.run(TimezoneUpdater.java:230)
    at com.sun.tools.tzupdater.TimezoneUpdater.main(TimezoneUpdater.java:634)
Caused by: tools.tzdb.DateTimeException: Invalid value for SecondOfDay value: 90000
    at tools.tzdb.ChronoField.checkValidValue(ChronoField.java:173)
    at tools.tzdb.LocalTime.ofSecondOfDay(LocalTime.java:210)
    at tools.tzdb.TzdbZoneRulesCompiler.parseMonthDayTime(TzdbZoneRulesCompiler.java:475)
    at tools.tzdb.TzdbZoneRulesCompiler.parseRuleLine(TzdbZoneRulesCompiler.java:399)
    at tools.tzdb.TzdbZoneRulesCompiler.parseFile(TzdbZoneRulesCompiler.java:354)
    ... 5 more

我使用https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz 作为 tzdata 包的来源。

已编辑 - 此外,我正在使用 Java(TM) SE 运行时环境(内部版本 1.8.0_66-b17)和 OpenJDK 运行时环境(内部版本 1.8.0_181-8u181-b13-1 ~deb9u1-b13),同时我使用 TZUpdater 或 ZIUpdater 报告了同样的问题

谁能帮我解决这个问题?任何意见将不胜感激。

非常感谢。

【问题讨论】:

  • 虽然您没有解决此问题,但您可以根据 GMT 手动更改您的时区,例如在 Java 选项中定义 -Duser.timezone=GMT[-03:00](而不是 -Duser.timezone=America/Sao_Paulo(或无),例如) .请记住,当 11 月 4 日到来时,您必须删除此更改(我假设您使用的是巴西时区,基于您在其他答案上的 cmets),否则您的应用程序将比应有的时间少 1 小时。
  • @LucasBasquerotto 我们正在使用这种姑息疗法。然而,使用此解决方案的系统是为了提高生产力并影响多个消费者。我们需要一个更强大、更自动化的解决方案。此时,我同时使用de IANA 参考版本。但是 JVM 忽略了旧版本和它使用来自 SO 的另一个时区来源。
  • 在我的情况下,由于您提到的问题,我使用了 IANA 2018f,除了使用 asia2018e。我也想要一个自动化的解决方案,并且只给出这个评论作为一个快速的即时解决方案。在我的例子中,IANA 2018e2018f 适用于 java 时间,但不适用于 JodaTime (joda.org/joda-time/tz_update.html)。 -Duser.timezone=GMT[-03:00] 的方法也适用于 JodaTime。我正在考虑从 JodaTime 迁移到 Java8 Time,这可能会得到解决,而不需要这种姑息解决方案。

标签: java timezone


【解决方案1】:

是的,1948-1951 年日本的规则在 2018 年以一种“有趣”的方式发生了变化:官方称日本的倒退发生在周六的 25:00,而不是周日的 01:00。这让 Java 时区更新程序以及我自己的 Noda Time 项目感到困惑。

现在有commit to avoid 25:00 in the "rearguard" format - 后卫格式基本上更保守,避免像爱尔兰的负 DST 之类的事情。

我预计 2018g 版本很快就会发布,包含该修复程序。假设 tzupdater 工具适当地使用后卫,我希望它能解决问题。如果你能等到那个时候,我会这样做。否则,使用 tzupdater 上的 -l 标志来指定不同的数据源,例如2018e:https://data.iana.org/time-zones/releases/tzdata2018e.tar.gz

【讨论】:

  • Jon Skeet 你知道是否有可能使用替代文件来更新 tz ?因为我使用的是巴西 tz,我们只需要使用南美洲 brt 中使用的部分更改进行更新
  • @EAA:请参阅 Cristian 的回答 - 我刚刚制定了 -l 选项 :) 只是避免 2018f,但要确保你有足够新的东西,应该没问题。
  • @JonSkeet 我仍然看到 2019 捆绑包存在问题。你知道这是否曾经修复过吗? (见我的帖子:stackoverflow.com/questions/56908541/…
  • @iank:我相信你现在仍然需要使用后卫格式。
【解决方案2】:

如果您需要使用 2018f 版本而不是亚洲时区,您可以从 2018e 开始使用它,从 2018f 开始使用其他文件。

我已在我的存储库 https://github.com/lucasbasquerotto/my-projects/tree/master/tz 中创建了文件 tzdata2018f-01.tar.gz,供任何想要避免进行这些手动更改的人使用。

有一个使用 OpenJDK 创建 docker 镜像时使用 ziupdater 的示例,但是如果您使用 Oracle JDK,您应该能够使用几乎相同的代码来使用 tzupdater 更改

java -jar /app/tmp/ziupdater-1.0.1.2.jar -l file:///app/tmp/tzdata2018f-01.tar.gz

java -jar /app/tmp/tzupdater.jar -l file:///app/tmp/tzdata2018f-01.tar.gz

甚至

java -jar tzupdater.jar -l https://github.com/lucasbasquerotto/my-projects/raw/master/tz/tzdata2018f-01.tar.gz

如果您不想手动下载。

在我的存储库中的示例中,它会生成一个 Docker 映像,但您可以在没有 docker 的情况下使用它,直接在您的操作系统中安装 Java。

我在本地机器(使用 Oracle JDK)上执行了上面的最后一个示例,并且成功更正了时区:

public static void main(String[] args) {        
    System.out.println("Date: " + new Date()); // prints correctly now
}

只需确保您没有使用使用硬编码在自己的 jar 中的时区数据的第三方库(如 Joda Time)(或使用更新的时区数据从源生成 jar,如 https://www.joda.org/joda-time/tz_update.html) .

【讨论】:

    【解决方案3】:

    由于tzdata2018g 已经发布,并附带以后卫格式提供的修复程序,请使用带有-l 选项的后卫tzdata 捆绑包。

    对于tzdata2018g,命令将如下所示:
    java -jar tzupdater.jar -l https://web.cs.ucla.edu/~eggert/tz/release/2018g/tzdata2018g-rearguard.tar.gz

    【讨论】:

    【解决方案4】:

    这里有同样的问题,问题似乎只是在最新版本上。

    使用

    java -jar tzupdater.jar -l https://data.iana.org/time-zones/releases/tzdata2018d.tar.gz
    

    (如果“2018d”对您来说足够了)应该可以正常工作。

    出于某种原因,在那之后,升级到最新的 tzdata 也可以正常工作(只有一个警告)。

    【讨论】:

    • 是的,问题与最新版本 2018f(2018-10-18 发布)有关。 iana.org/time-zones
    • @EAA:您需要哪些确切更改? github.com/eggert/tz/blob/master/NEWS 说明每个版本的内容。
    • @e2a 我从你的 cmets 看到你只需要 brt 更新。这些已经固定在版本“d”上。只需按照建议使用它,它就会修复巴西夏令时的变化。
    • @CristianTM 是的,版本“d”已被使用。它解决了我的问题。
    【解决方案5】:

    我遇到了同样的错误,然后我修复了从IANA下载的文件,使用以下shell脚本,将文件中的麻烦行替换为以前版本的“asia”文件,如@所述lucas-basquerotto 在他的帖子below。我已经测试过了,效果很好!

    请下载 TZUpdater 包,解压缩 tzupdater.jar 并使用下载的 jar 文件的完整文件路径更新变量 TZUPDATER_JAR,以便成功运行脚本。

    #!/bin/bash
    
    #FULL PATH TO tzupdater.jar
    TZUPDATER_JAR='/home/user/tzupdater.jar'
    
    OUTPUT_ALL=$(java -jar $TZUPDATER_JAR -l 2>&1 >/dev/null)
    echo "$OUTPUT_ALL" | grep -e "Caused by: tools.tzdb.DateTimeException: Invalid value for SecondOfDay value: 90000" > /dev/null
    if [ $? -eq 0 ]
    then
            FIXME_FILE=$(echo "$OUTPUT_ALL" | grep -Po "(?<=java.lang.Exception: Failed while parsing file ').+(?=' on line 1655 'Rul)")
            echo "file $FIXME_FILE contains a syntax error"
    
            ERROR_LINE=$(sed -n '1656,1656p' $FIXME_FILE )
            echo "Line 1655 \"$ERROR_LINE\" contains an error"
            FIXED_LINE=${ERROR_LINE/Sat>=8/Sun>=9}
            FIXED_LINE=${FIXED_LINE/25:00/0:00}
            echo "Line 1655 fixed: \"$FIXED_LINE\" ( rule \"Sat>=8 25:00\" replaced by \"Sun>=9 0:00\" as it was used to be on previous version )"
            sed -i "s/$ERROR_LINE/$FIXED_LINE/" $FIXME_FILE
            TEMP_DIR_NAME=$(dirname $FIXME_FILE)
            cd $TEMP_DIR_NAME
            mkdir tzdata
            mv tzdata.tar.gz tzdata/
            cd tzdata/
            echo "untar original tzdata.tar.gz"
            tar -xf tzdata.tar.gz
            rm tzdata.tar.gz
    
            FIXME_FILENAME=$(basename $FIXME_FILE)
            echo "replacing original $FIXME_FILENAME file"
            rm $FIXME_FILENAME
            cp ../$FIXME_FILENAME $FIXME_FILENAME
            echo "building a new tar ball with the fixing"
            tar -czf ../tzdata-updated.tar.gz *
            echo "installing the updated tar file (requires elevation sudo)"
            sudo java -jar $TZUPDATER_JAR -l "file:///$TEMP_DIR_NAME/tzdata-updated.tar.gz"
            if [ $? -ne 0 ]
            then
                    echo "something went wrong!"
                    exit 2
            fi
    fi
    echo "installation successful!"
    

    将此脚本保存在名称 update_jdk_tzdata.sh 下并授予其执行权限:chmod +x update_jdk_tzdata.sh 并执行它./update_jdk_tzdata.sh(它需要 sudo 才能更新 JRE 文件)

    【讨论】:

    • 请注意,这通过更改数据“修复”了问题。 25:00 完全是故意的,只是目前 Java 没有正确处理(甚至解决)它。
    • 我已经更新了脚本,只将报错的那一行还原到之前的版本
    【解决方案6】:

    更新您的 Java 8 版本; tzupdater 工具仅适用于 Java 8 更新 181。

    【讨论】:

    • 不是jvm版本。这是与 iana 版本相关的问题。
    • 这不是真的。来自tzupdater-readme:“TZUpdater 工具在所有支持的平台上支持所有当前支持的 Oracle JDK 和 JRE 版本。”
    • Tzupdater 用于在不更新 JRE 的情况下更新 tzdata。所以更新 JRE 不是答案。
    【解决方案7】:

    使用这些命令:

    sudo apt-get install oracle-java8-installer
    sudo update-alternatives --config java 
    

    并选择数字 *0(自动)

    sudo update-alternatives --config javac
    

    并选择相同的 *0。

    如果您已经拥有 tzupdater,则只能查看已经是 2018 的版本

    java -jar tzupdater.jar -V
    

    【讨论】:

    • 这绝对有效吗?我不会期望它,除非 tzupdater 真的,真的是最近 更新以处理 25:00 的转换时间。如果您自己运行并成功将数据更新到 2018f,那么值得在您的答案中明确说明这一点,因为这会令人惊讶。
    • 这没有回答问题。 tzupdater 用于更新 tzdata 而不更新 jvm/jre。
    【解决方案8】:

    如果您在使用日文版时遇到问题,可以使用另一个巴西链接。 java -jar tzupdater.jar -l https://data.iana.org/time-zones/releases/tzdata2018e.tar.gz

    【讨论】:

    • 问题是新的 DST 将计划在 11 月 4 日开始,而使用此版本 (2018e) 的计划将在 11 月 3 日开始。所以它不能用于巴西 DST。
    • 如果到 11 月 4 日的法令是在 2017 年 12 月完成的,为什么会安排在 11 月 3 日? pcdsh01.on.br/DecHV.htmle版本来自2018-05-03 23:55
    猜你喜欢
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    • 2019-03-05
    • 2021-10-29
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多