Java获取时间与系统时间相差8小时终极解决方案

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java获取时间与系统时间相差8⼩时终极解决⽅案
⼀、在取⽇期以前设置⼀下时区
//这两种写法都能获取到东⼋区
TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
TimeZone tz = TimeZone.getTimeZone("GMT+08:00");
TimeZone.setDefault(tz);
此种⽅法适⽤于单次快速获取系统本地时间
⼆、设置java命令参数
java -Duser.timezone=Asia/Jerusalem DateTest
三、设置JVM的默认时区为东⼋区(北京时间)
在下⾯四个⽬录(bea\jdk142_11\jre\lib\zi\Etc、bea\jdk142_11\jre\lib\zi、bea\jrockit81sp6_142_10\jre\lib\zi\Etc、
bea\jrockit81sp6_142_10\jre\lib\zi)下找到GMT⽂件bak备份⼀下,然后复制⼀份GMT-8并重命名为GMT,复制完毕,重新运⾏⼀下java程序问题即可解决!
0、引⾔
Druid中时区的问题⼀直困扰着我们,所以我专门去研究了⼀下世界时区和Java中的时区,对使⽤Druid很⽤帮助.
1、UTC时间&GMT时间
UTC时间是时间标准时间(Universal Time Coordinated),UTC是根据原⼦钟来计算时间,误差⾮常⼩。

UTC也是指零时区的时间,如果要表⽰其他时区的时间,这⾥要注意没有UTC+0800或者UTC+8这样的表⽰⽅式(⾄少Java⾥⾯没有,⼀般⽤于⼝头表⽰),只有Asia/Shanghai这样的表⽰⽅式,详细的时区列表参考这个⽂档时区列表,不要问我为什么没有北京时区。

GMT时间是根据地球的⾃转和公转来计算时间,⽼的时间计量标准,这⾥我们不过多讨论
2、表达时间⽅式
我们⼀般表⽰时间都会带格式以⽅便理解,例如时间表达式是'2018-09-12 08:00:00',因为我们在东⼋区,所以默认是:北京时间2018年9⽉12号8点整。

但是如果是⼀个美国⼈看到这个时间,就会认为是美国东部or西部时间的2018年9⽉12号8点整。

所以从这种表达⽅式很不准确,因为没有指明到底是哪个时区的时间
所以准确的表达时间必须带有时区,例如2018-09-12 08:00:00+0800,表达了Asia/Shanghai这个时区的时间2018年9⽉12号8点整。

这⾥要注意
+0800并不是表⽰加8⼩时的意思,只是表⽰这个时间'2018-09-12 08:00:00'是东⼋区Asia/Shanghai的时间,仅此⽽已。

3、UTC时间的时间戳
讲清楚了时间表达⽅式,再讲时间戳。

其实时间戳是没有时区概念的,或者说时间戳只能是0时区的。

时间戳是从1970-01-11 00:00:00+0000开始的(原因⼤家都知道),也就是在'1970-01-11 00:00:00+0000'这个时间点,时间戳是0。

再换句话说在'1970-01-11 08:00:00+0800'时间戳也是0。

这也是Java⾥时间组件的默认⽅式,不管⽤户输⼊的⼈类可识别的时间是什么格式,在内部统⼀存的是时间戳。

例如时间是'2018-09-01 08:00:00+0800',那么使⽤date.getTime()获取到时间戳是1535760000000;时间是'2018-09-01 00:00:00+0000',获取到时间戳也是1535760000000。

测试代码如下:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
System.out.println(sdf.parse("2018-09-01 08:00:00+0800").getTime());
System.out.println(sdf.parse("2018-09-01 00:00:00+0000").getTime());
可以观察到这2⾏代码的输出都是1535760000000,这就证明了上⾯的观点。

再啰嗦2点:
第⼀⾏代码DateFormat中Z表⽰时区,所以String类型格式时间带上+0800这种表达式,就能正确获取时间戳了。

SimpleDateFormat是线程不安全的,不要⽤
4、时区设置
为什么我们写以下代码的时候,程序能正确知道我们的时区呢?
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf2.parse("2018-09-01 08:00:00").getTime());
因为我们在mac上设置了时区
在Java中也可以设置时区
1)启动设置
java -Duser.timezone=Asia/Shanghai -jar xxx.jar
2. 代码中设置
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.parse("2018-09-01 08:00:00").getTime());
3. 单次处理⽣效,建议使⽤joda的时间包
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.9</version>
</dependency>
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withChronology(ISOChronology.getInstance(DateTimeZone.forID("Asia/Shanghai"))); System.out.println(dateTimeFormatter.parseDateTime("2018-09-01 08:00:00").getMillis());。

相关文档
最新文档