我有一个Java实例,它似乎使用了一个完全不正确的时区。它使用的是美国/加拉加斯时区,而不是使用Windows正在使用的澳大利亚/悉尼时区。
我首先通过系统时钟检查了Windows时间,然后检查了HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/
和ControlSet001
,ControlSet002
。所有都设在悉尼时区。
有人知道这是Java中的错误,还是指其他地方设置的时间?
Java版本是1.6.0_06
答案 0 :(得分:12)
确保在启动应用程序时设置JVM的时区:
-Duser.timezone="Australia/Sydney"
答案 1 :(得分:6)
检查以下链接的信息:
http://techtavern.wordpress.com/2010/04/15/java-and-incorrect-timezone-on-windows-xp/
它表明,JVM中存在一个错误,导致从Windows注册表中读取不正确的默认时区。还没有错误修复。
答案 2 :(得分:5)
答案 3 :(得分:2)
尝试使用您的应用获取默认时区,或手动设置时区(注释行)。
我的小例子:
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Locale locale = Locale.getDefault();
TimeZone localTimeZone = TimeZone.getDefault();
//TimeZone localTimeZone = TimeZone.getTimeZone("Australia/Sydney");
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale);
dateFormat.setTimeZone(localTimeZone);
Date rightNow = new Date();
System.out.println(locale.toString() + ": " + dateFormat.format(rightNow));
}
}
答案 4 :(得分:2)
我最近遇到了同样的问题,显然这是由于Windows在注册表中代表其时区设置以及Java无法正确解释它的模糊性造成的。
可以在this article中找到更多详细信息,其中还介绍了受影响计算机的“治愈方法”:
- 手动更改日期/时间,然后再更改回原始正确时间。
- 更改时区,然后返回原始时区。
- 请求从时间服务器自动更新时间。
答案 5 :(得分:1)
有这样的问题的历史来来往往,没有合理的解决方案。点击此处:Java incorrect time zone bug on Windows
编辑:回答Tom和francis:简而言之,Java运行时很难正确地找到计算机上当前时区的工作。
关于时区的Windows注册表信息不可靠,对于依赖于msvcrt.dll和各种msvcrxx.dll的本机Windows API也是如此。还有Managed(.NET)API需要安装某个版本的.NET Framework,这与Java的可移植性相矛盾。
因此,Java运行时的开发人员很难在Windows上使用当前时区,这可能会持续到微软有一些合作的理由。
如果您希望Java应用程序在任何时区正常工作,请让用户通过GUI更正时区。
答案 6 :(得分:0)
我有同样的错误,当我将我的时区设置为马来半岛标准时间时,JVM给了我委内瑞拉时间时区。
以下修复程序适用于我:
在注册表编辑器中,将您的时区编辑到另一个时区(我试图添加另一个文本,如“新加坡时间”。您可以在此处找到注册表:
HKEY_LOCAL_MACHINE /系统/ CurrentControlSet /控制/ TimeZoneInformation
然后,我使用“控制面板”,“日期和时间”设置将其重置回我想要的时区。 当我回到注册表编辑器时,我可以看到它被恢复为马来半岛标准时间。我的JVM现在正确读取它......
答案 7 :(得分:0)
Java程序员切勿依赖JVM当前的默认时区。
Continent/Region
的格式指定proper time zone name,例如Africa/Casablanca
。以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用2-4个字母的缩写,例如CST
,EST
或IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的( !)。例如,如果您将IST
用作爱尔兰标准时间,则可能会获得令人惊讶的印度标准时间。
ZoneId z = ZoneId.of( "America/Montreal" ) ; // Or "Pacific/Auckland", "Africa/Tunis", etc.
从不依赖JVM当前的默认时区。该默认值可以更改。
TimeZone.setDefault
的任何应用程序的任何线程中的任何代码来设置JVM当前的默认时区。 (顺便说一下,TimeZone
和ZoneId
已使ZoneOffset
被过时了,除了那个setter方法,除非在最极端的情况下才应该调用它。)因此,由于所有这些原因,JVM的当前默认时区完全不在程序员的掌握范围内,更糟糕的是,它可以在运行时动态更改。因此,使用当前默认值是不可靠的。
仅出于最偶然的目的使用JVM当前的默认时区。对于任何重要的事情,您只需与用户确认目标区域。这是一个经常被程序员抵制的不便的事实,但是仍然如此。
提示:Locale
的同上。 JVM的当前默认语言环境可能与主机OS的语言环境匹配,也可能不匹配,可以随时更改,因此不可靠。始终与用户确认所需的{/ {1}}。
java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
,SimpleDateFormat
和java.util.TimeZone
。
目前位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要Locale
类。
在哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如Interval
,YearWeek
,YearQuarter
和more。
答案 8 :(得分:0)
如果时区似乎已完全消失,至少就我而言,在旧系统上使用Java 5而言,请确保%JAVA_HOME%\ jre \ lib \ zi文件夹中存在正确的文件。例如,对我而言,我无法让Europe / Athens终身为我服务。原来文件%JAVA_HOME%\ jre \ lib \ zi \ Europe \ Athens丢失了(那些指向各大洲的目录在我使用的JDK中是完全空的..)-与新下载的JDK 1.5进行了比较Oracle的.0_22。
答案 9 :(得分:0)
我解决了将其添加到我的数据库 URL 中的错误:
?useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC