Java 使用tzupdater-2.2.0更新tzdata 2018f(2018年10月18日发布)时出错

Java 使用tzupdater-2.2.0更新tzdata 2018f(2018年10月18日发布)时出错,java,timezone,Java,Timezone,我正在尝试使用更新JVM的时区信息 因此,我正在运行下面的命令: > [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 2

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

因此,我正在运行下面的命令:

> [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
失败:java.lang.Exception:解析第1655行的文件'/tmp/tz.tmp_1/asia'时失败'Rule Japan 1948 1951-Sep Sat>=8 25:000S'
java.lang.Exception:解析第1655行上的文件“/tmp/tz.tmp_1/asia”时失败“Rule Japan 1948 1951-Sep Sat>=8 25:00 0”
位于tools.tzdb.tzdbzonerulesciler.parseFile(tzdbzonerulesciler.java:377)
位于tools.tzdb.tzdbzonerulesciler.compile(tzdbzonerulesciler.java:191)
位于tools.tzdb.tzdbzonerulesciler。(tzdbzonerulesciler.java:307)
在com.sun.tools.tzupdater.ExternalModule.compileToJSorbinary(ExternalModule.java:153)上
在com.sun.tools.tzupdater.TimezoneUpdater.run(TimezoneUpdater.java:230)上
位于com.sun.tools.tzupdater.TimezoneUpdater.main(TimezoneUpdater.java:634)
原因:tools.tzdb.DateTimeException:SecondOfDay值无效:90000
在tools.tzdb.ChronoField.checkValidValue中(ChronoField.java:173)
位于tools.tzdb.LocalTime.ofSecondOfDay(LocalTime.java:210)
位于tools.tzdb.tzdbzonerulesciler.parseMonthDayTime(tzdbzonerulesciler.java:475)
位于tools.tzdb.tzdbzonerulesciler.parseRuleLine(tzdbzonerulesciler.java:399)
位于tools.tzdb.tzdbzonerulesciler.parseFile(tzdbzonerulesciler.java:354)
... 还有5个
我将用作tzdata包的源

编辑-此外,我正在使用Java(TM)SE运行时环境(build 1.8.0_66-b17)和OpenJDK运行时环境(build 1.8.0_181-8u181-b13-1~deb9u1-b13),同时我在使用TZUpdater或

有人能帮我解决这个问题吗?如有任何意见,将不胜感激


非常感谢

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

现在有了一个-后防线的形式基本上更为保守,避免了爱尔兰消极的DST


我预计2018g会在某个合理的时间很快发布,包括该修复。假设tzupdater工具适当地使用了rearguard,我希望它能解决问题。如果你能等到那时,我会的。否则,请使用tzupdater上的
-l
标志指定不同的数据源,例如,对于2018e:

在这里有相同的问题,而问题似乎仅出现在最新版本上

使用

java -jar tzupdater.jar -l https://data.iana.org/time-zones/releases/tzdata2018d.tar.gz
(如果“2018d”对你来说足够)应该可以


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

如果您对日文版有问题,可以使用另一个巴西链接。
java-jar tzupdater.jar-l

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

使用以下命令:

sudo apt-get install oracle-java8-installer
sudo update-alternatives --config java 
然后选择数字*0(自动)

然后选择相同的*0

如果你已经有了tzupdater,那么只能看到它已经存在的版本

java -jar tzupdater.jar -V

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

请下载包,提取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!"
#/bin/bash
#tzupdater.jar的完整路径
TZUPDATER_JAR='/home/user/TZUPDATER.JAR'
OUTPUT_ALL=$(java-jar$TZUPDATER_jar-l2>&1>/dev/null)
echo“$OUTPUT_ALL”| grep-e”由以下原因引起:tools.tzdb.DateTimeException:SecondOfDay值无效:90000”>/dev/null
如果[$?-等式0]
然后

FIXME_FILE=$(echo“$OUTPUT_ALL”| grep-Po”(?如果需要使用版本2018f,但不使用亚洲时区,则可以从2018e使用它,从2018f使用其他文件

我已经在我的存储库中为希望避免进行这些手动更改的任何人创建了该文件

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

java -jar /app/tmp/ziupdater-1.0.1.2.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
如果你不想手动下载

在my repository中的示例中,它生成了一个Docker映像,但是您可以在不使用Docker的情况下使用它,Java直接安装在您的操作系统中

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

public static void main(String[] args) {        
    System.out.println("Date: " + new Date()); // prints correctly now
}
只需确保您没有使用某些第三方库(如Joda Time),这些库使用在自己的jar中硬编码的时区数据(或使用更新的时区数据从源生成jar,如中).

由于已使用后防护格式提供的修复程序发布,请使用后防护
tzdata
绑定-l选项

对于
tzdata2018g
命令如下所示:

java-jar tzupdater.jar-lhttps://web.cs.ucla.edu/~eggert/tz/release/2018g/tzdata2018g rearguard.tar.gz

Jon Skeet您知道是否有可能使用替代文件来更新tz?因为我使用的是巴西tz,我们只需要使用南美洲使用的部分更改进行更新brt@EAA当前位置参见克里斯蒂安的回答-我很乐意st已经解决了
-l
选项:)只需避开2018f,但要确保你有足够新的东西,而且应该是好的。@JonSkeet我仍然发现2019捆绑包存在问题。你知道这是否已经解决了吗?(请参阅我的帖子:)@伊恩克:我相信你现在仍然需要使用后防护格式。是的,问题与最新版本201有关
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
public static void main(String[] args) {        
    System.out.println("Date: " + new Date()); // prints correctly now
}