如何正确设置JVM TimeZone


141

我正在尝试运行Java程序,但是它采用默认的GMT时区而不是OS定义的时区。我的JDK版本是1.5,操作系统是Windows Server Enterprise(2007)

Windows指定了中央时区,但是当我运行以下程序时,它给了我GMT时间。

import java.util.Calendar;

public class DateTest
{
    public static void main(String[] args)
    {
        Calendar now = Calendar.getInstance();
        System.out.println(now.getTimeZone());
        System.out.println(now.getTime());
    }
}

这是输出

sun.util.calendar.ZoneInfo[id="GMT",
offset=0,
dstSavings=0,
useDaylight=false,
transitions=0,
lastRule=null]
Mon Mar 22 13:46:45 GMT 2010

请注意,我不想从应用程序中设置时区。我希望JVM使用的时区应该是操作系统中指定的时区。(对于具有JDK 1.4版和Microsoft Server 2003的其他服务器,我没有发现此问题)。

任何想法将不胜感激。


1
嗯,这很奇怪。看起来像是JVM / OS错误或一些奇怪的错误配置。
Michael Borgwardt 2010年

您如何DateTest上课?
马特b

@matt b:我正在从Windows命令提示符下编译并调用DateTest。但这只是一个Test类。最初的问题是针对IBM cognos服务器的某些ETL流程。
库沙尔·波迪亚

1
只是想排除通过可能带有-Duser.timezone值的任何shell / batch脚本启动它的问题
matt b

Answers:


220

您可以将此参数传递给JVM

-Duser.timezone

例如

-Duser.timezone=Europe/Sofia

这应该可以解决问题。设置环境变量TZ在Linux上也可以解决问题。


我们不得不使用JDK DST时区更新工具-1.3.25(tzupdater),然后按照您的建议更改JVM参数,终于解决了这个问题。顺便说一句,时区信息由Windows存储在某个注册表中。我使用的更新程序还更新了注册表值。
库沙尔·波迪亚

1
我正在尝试使用此参数启动JVM,但似乎没有任何变化...如果要在UTC上启动,应将什么用作参数!?
rafa.ferreira

在我的应用程序中,我正在更改一些位置并获取这些位置的时区。使用时区,我正在进一步处理。但是,当应用程序首次启动时,我会获得正确的值。当我更改时区并将新时区设置为默认时区时,我没有获得正确的值。问题是什么?如何准确更改时区。我正在使用TimeZone.setDefault(TimeZone.getTimeZone(“ my_time_zone”)))更改时区。
2012年

2
TZ的时区​​列表在这里:en.wikipedia.org/wiki/List_of_tz_database_time_zones。使用时区名称比偏移量更好,因为它可以处理夏令时。
布赖恩

65

您还可以使用以下代码在代码中设置默认时区。

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

给你的

 TimeZone.setDefault(TimeZone.getTimeZone("Europe/Sofia"));

1
“请注意,我不想从应用程序中设置时区。”
AbVog

22

上面接受的答案:

-Duser.timezone="Europe/Sofia" 

完全不适合我。只有在参数周围没有引号时,我才能够成功更改时区:

-Duser.timezone=Europe/Sofia

2
我同意。我已经编辑了原始答案以删除引号。
GaZ 2015年

1
这取决于使用的外壳。
vadipp

10

在Windows 7和JDK6上,我必须添加-Duser.timezone="Europe/Sofia"到“我的电脑=>属性=>高级系统设置=>环境变量”下的JAVA_TOOL_OPTIONS系统变量。

如果您已经设置了其他属性,JAVA_TOOL_OPTIONS只需添加一个空格,然后插入属性字符串即可。


5

其他答案中涵盖了我不认为的两个选项:

避免需要

无论您做什么来设置JVM默认时区,都很难确保没有其他人对它进行不同的设置。可以随时进行设置,而无需程序其他部分或运行在同一JVM中的其他程序的通知。因此,在您的时间操作中,应明确说明所需的时区,并且您将始终知道与JVM设置无关的结果。例:

    System.out.println(ZonedDateTime.now(ZoneId.of("Asia/Dushanbe")));

输出示例:

2018-10-11T14:59:16.742020 + 05:00 [亚洲/杜尚别]

System.setProperty

对于许多目的,以下不是首选的方法,并且肯定会被滥用。对于“扔掉”程序,我有时会发现它很实用。您还可以在Java中设置系统属性:

    System.setProperty("user.timezone", "Australia/Tasmania");
    System.out.println(ZonedDateTime.now());

刚刚打印:

2018-10-11T21:03:12.218959 + 11:00 [澳大利亚/塔斯马尼亚]

如果要验证传递的字符串,请使用:

        System.setProperty("user.timezone", ZoneId.of("Australia/Tasmania").getId());

4

如果您使用的是Maven

mvn -Dexec.args="-Duser.timezone=Europe/Sofia ....."

mvn spring-boot:run -Drun.jvmArguments="-Duser.timezone=UTC"适用于Spring Boot v1。
Chloe

0

在win7中,如果要在JRE中将正确的时区设置为参数,则必须编辑deployment.properties路径中存储的文件,c:\users\%username%\appdata\locallow\sun\java\deployment并添加字符串deployment.javaws.jre.1.args=-Duser.timezone\=my_time_zone


我试了一下,它不起作用(从intellij内部执行jvm)
kumetix
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.