java 日期

来源:互联网 发布:路由器访客网络是什么 编辑:程序博客网 时间:2024/05/20 18:41
学习一下java的基础知识吧,比如java这些日期相关的类,不看不知道,这水还挺深的~

转载请注明出处!!!!

统一标准
我们都知道,java的时间戳,是以1970年1月1日为原点开始计时的。java有个系统函数,System.currentTimeMillis()就是获取当前与1970-01-01 00:00:00UTC(请注意这个UTC) 的时间差,以毫秒为单位。Date类的无参构造函数,就是使用了这个方法:
     privatetransientlongfastTime;
    publicDate() {
       this(System.currentTimeMillis());
    }

   publicDate(longdate) {
       fastTime= date;
    }

那么,问题来了,为什么要这么做?
这样做可以用一个长整型(long)数字表示一个日期,比较两个时间的大小,在时间上做加减法,都很方便,是不是很厉害!
比如Date类的before方法:
   publicbooleanbefore(Datewhen) {
       returngetMillisOf(this) < getMillisOf(when);
    }
为什么是1970年呢?!
简单的说,从什么时候开始,一定要有个标准,这是大家(计算机)都认可的标准,所以就是它喽。
这个问题的详细解释,知乎:https://www.zhihu.com/question/21503281


时区
下面看一段有意思的代码
    Datedate= new Date(0);
    System.out.println(date);
    System.out.println(date.getHours());
 输出的结果:     
Thu Jan 01 08:00:00 CST 1970
8
是不是很神奇?!
没错,就是因为时区,CST( China Standard Time UT+8:00 ),因为我的系统默认时区是东八区,比标准时间快了8个小时。还记得文章开始时候加粗的红字么,UTC,协调世界时间。java中的时间都是以这个为基准的,其实很多其他语言和操作系统也是如此,有了统一的标准才好计算嘛。
其实时区的问题很麻烦,我眼中的0点和你眼中的0点可能是不一样的。那怎么办呢,统一用UTC喽,也就是统一用一个long型的数字表示喽。这里不会有歧义。
这里有篇文章说的非常好,大概意思,就是数据库里直接用一个数字表示时间,就没有所谓的时区的问题了。
http://www.liaoxuefeng.com/article/0014132675721847f569c3514034f099477472c73b5dee2000

那如何使用指定的时区呢?
Date这个类,你翻遍API,也找不到设置时区的方法,因为它使用的是默认时区,你要通过修改默认的时区才能指定Date类的时区。
    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    Datedate= new Date(0);
    System.out.println(date);
    System.out.println(date.getHours());
这样输出的就是UTC时间了      
Thu Jan 01 00:00:00 UTC 1970
0
可以看到,Date类在处理时区方面,不大好用,它本身并不带有时区这个数据!那我我传递给你的Date对象,到底是用什么时区呢?!所以,还是long型数据好,就是使用UTC时区的,没什么歧义。即使我们的时区不同,但是这个long型数据是一致的,想要什么时区,自己转换去~

为什么还要指定时区呢?
梳理一下,为什么我们需要时区。因为一个长整形的数字,一点都不直观。你想知道这个长整型的数字到底是哪年,哪月,哪日,几点。还是要有时区的概念的,具体如何处理下一小节我再梳理。


Date还剩的不多的方法
Date这个类,很多方法,都已经被不赞成(deprecated)使用了。官方说法是因为不利于国际化(是因为时区问题么!?)。那基本上已经没什么方法了。
构造函数两个,表示时间的长整型数字的设置和读取两个,时间比较两个,没啦,其他的都被deprecated啦!!!
  • Date(): 默认的无参构造函数,调用System.currentTimeMillis()作为日期参数.
  • Date(long date): 根据指定的long整数来生成Date对象.
  • boolean after(Date when): 比较是否在when之后
  • boolean before(Date when): 比较是否在when之前
  • long getTime(): 获取fastTime
  • void setTime(long time): 设置fastTime
其实,1.8又增加了两个函数,与Instant互相转换的两个方法,啥作用,等熟悉了1.8新的时间API之后再说。


其他
1.时区调整问题
http://stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result
http://blog.jobbole.com/1178/
这个问题应该已经没有了,把这里的代码在我现在的环境下跑是没什么问题的。
2.闰秒的问题
http://blog.jobbole.com/22714/



0 0