zoukankan      html  css  js  c++  java
  • Java获取时间与系统时间相差8小时终极解决方案

    https://www.cnblogs.com/exmyth/p/5320186.html

    https://www.cnblogs.com/oldtrafford/p/9680791.html

    一、在取日期以前设置一下时区

    //这两种写法都能获取到东八区

    TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
    TimeZone tz = TimeZone.getTimeZone("GMT+08:00");

    TimeZone.setDefault(tz);

    此种方法适用于单次快速获取系统本地时间

    二、设置java命令参数

    java -Duser.timezone=Asia/Jerusalem DateTest

    三、设置JVM的默认时区为东八区(北京时间)

    在下 面四个目录(beajdk142_11jrelibziEtc、beajdk142_11jrelibzi、beajrockit81sp6_142_10jrelibziEtc、beajrockit81sp6_142_10jrelibzi)下找到GMT文件bak备份 一下,然后复制一份GMT-8并重命名为GMT,复制完毕,重新运行一下java程序问题即可解决!

    世界时区和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

    1. 代码中设置
    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());
    
    1. 单次处理生效,建议使用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());
  • 相关阅读:
    Higher-Order Functions and Lambdas
    dispatch_sync:As an optimization, this function invokes the block on the current thread when possible
    为什么使用dispatch_sync
    如何安全使用dispatch_sync
    dispatch_sync
    Dispatch Queues and Thread Safety
    高阶函数-参数与返回值
    In Swift, typedef is called typealias:
    偏函数应用(Partial Application)和函数柯里化(Currying)
    Centos下添加用户到用户组
  • 原文地址:https://www.cnblogs.com/linus-tan/p/12652348.html
Copyright © 2011-2022 走看看