Java中日期时间API小结
Java中为处理日期和时间提供了大量的API,确实有把一件简单的事情搞复杂的嫌疑,各种类:Date Time Timestamp Calendar...
,但是如果能够看到时间处理的本质就可以轻松hold住这堆东西了。
常用的类
表示类
java.util.Date
:能够准确记录到毫秒级别的时间表示类,但是其中的各种get set(修改时间或者获取时间中某一个特殊参数)都已经被废弃。java.sql.Date
:为数据库提供的日期类,继承自util
包中的Date
,但是这个类只能够操作日期,不能读取或者修改时间。sql和util中Date内部进行存储的long,都可以保存到毫秒级别java.sql.Time
:为数据库提供的时间类,和Date
相反,它只能获取和操作时间相关的信息。java.sql.Timestamp
:时间戳,继承util.Date
,它不仅能够完美支持util.Date
的功能,而且可以支持到纳秒级别(10^-9 s)。
工具类
Calendar
:主要用来操作一个Date
类型,提供了一系列接口来获取或修改其中的信息。TimeZone
:用来配合Calendar
操作Date
,主要是考虑时区的问题,值得注意的是,在Date
中存储的信息是一个绝对标准时间(稍后说明),而如果需要进行时区的转化,那么只需要配合此类即可。SimpleDateFormat
:常用的格式化Date
的工具,主要是进行String
和日期之间的互换。
基本概念
时间的来源
注意,这里并不是讨论一个哲学的问题,在大部分的编程语言中,我们都是采用从1970-01-01 00:00:00.000 开始至今的毫秒差作为表示时间的数值,这个时间是绝对公立的,它和时区没有任何关系。在Java中任何时间的表示类的底层存储的毫秒数都是一个这样的标准时间。
在java中获取当前时间接口是System.currentTimeMillis()
。
值得一提的是Java还提供了一个更加精确的时间:System.nanoTime()
,获取一个时间精确到纳秒,但是它并不是一个当前的精确时间,而是JVM提供的一个时间,它的主要用途是来精确衡量两个时间段之间的时间,如计算一段代码的执行时间:
long startTime = System.nanoTime();
// ... the code being measured ...
long estimatedTime = System.nanoTime() - startTime;
可以比较两个接口返回的内容:
System.currentTimeMillis()
:1429108246639
System.nanoTime()
:1429108246640(ms)089000------->多了6位
UTC和GMT
这两个标准唯一不同之处在于UTC是基于GMT进行微调之后的一个时间,本文不去深究这两者的差别,在此认为这两者是一个东西。
初中地理教过我们,地球是24个时区,东部和西部各12个,时区的基准点是伦敦(基准UTC),往东,会领先UTC,往西,会落后UTC。
如北京属于东八区,那么我们的时间会领先基准,也就是我们在早上9点时,伦敦是早上1点。如果我们在不同时区接发邮件的时候,可以发现这个问题。
这个时间是我收到一份来自华盛顿的邮件的时间:
2014年1月23日(星期四) 晚上7:29 (UTC-05:00 华盛顿、多伦多、古巴、智利时间)
这里我们可以在邮件时间后面发现UTC-05:00
,说明这里是落后UTC基准5个小时。注意,前面的时间是发件人的本地时间,如果转化成北京所在时区的时间应该是加上13h,那我收到这封邮件的本地时间是:2014-01-24 星期五早上8:29。
再谈TimeStamp
前面说了,TimeStamp能够精确到纳秒,那它是怎么做到的呢?由于TimeStamp继承自Date
,它把整数秒存储在超类中,而在子类中专门用一个long类型存储零的秒数:nanos
需要注意,除非你显示去调用TimeStamp的这个构造器:
public Timestamp(int year, int month, int date, int hour, int minute, int second, int nano)
显示去指定nano的值,否则这个构造器的参数
public Timestamp(long time)
的单位实际上是毫秒。
API的使用
最后再来说说日期时间的操作接口,过程基本如下图:
SimpleDateFormat <------> Date <---------> Calendar
Date负责存储一个绝对时间,并对两边提供操作接口。Calendar负责对Date中特定信息,比如这个时间是改年的第几个星期,此外,还可以通过set,add,roll接口来进行日期时间的增减。SimpleDateFormat主要作为一些格式化的输入输出。
SimpleDateFormat
SimpleDateFormat
的构造器接受一个String pattern,其中的pattern是预定义的:
G 年代标志符
y 年
M 月
d 日
h 时 在上午或下午 (1~12)
H 时 在一天中 (0~23)
m 分
s 秒
S 毫秒
E 星期
D 一年中的第几天
F 一月中第几个星期几
w 一年中第几个星期
W 一月中第几个星期
a 上午 / 下午 标记符
k 时 在一天中 (1~24)
K 时 在上午或下午 (0~11)
z 时区
例子1:
SimpleDateFormat DATETIME_FORMATER_WITHWEEK = new SimpleDateFormat(
"yyyy-MM-dd E HH:mm");
java.util.Date date = new java.util.Date();
System.out.println(DATETIME_FORMATER_WITHWEEK.format(date));
//output: 2015-04-15 星期三 23:59
//当然,反过来,我也可以使用这个format将output的字符串转化成Date
Calendar
Calendar中主要需要了解的各种操作域,感觉这也是Java在做这个API时的一个败笔,灵活有余,可控性不足,初学者如果乱用域,将会产生各种bug。至于每一个域对应的时间分量,请自行google。
一些常用的filed:
- YEAR:年
- MONTH:月(从0 开始,0 表示1月....11表示12月)
- DAY_OF_MONTH :几号(等同DATE)
- DAY_OF_WEEK:星期几
- DAY_OF_YEAR:年里面的天
- DATE:几号(等同DAY_OF_MONTH)
一个filed通常来说对应了日期时间中的某一个分量,在操作这个分类有些操作会向高位进位,而有的操作则不会【bug高发区域】。
例子2:
SimpleDateFormat DATETIME_FORMATER_WITHWEEK = new SimpleDateFormat(
"yyyy-MM-dd E");
Calendar calendarT = Calendar.getInstance(Locale.CHINA);
System.out.println(DATETIME_FORMATER_WITHWEEK.format(calendarT.getTime()));
calendarT.set(Calendar.MONTH,12);// 月份进位
System.out.println(DATETIME_FORMATER_WITHWEEK.format(calendarT.getTime()));
//output: 2015-04-16 星期四
2016-01-16 星期六
例子3:
SimpleDateFormat DATETIME_FORMATER_WITHWEEK = new SimpleDateFormat(
"yyyy-MM-dd E");
Calendar calendarT = Calendar.getInstance(Locale.CHINA);
System.out.println("原始 :"+DATETIME_FORMATER_WITHWEEK.format(calendarT.getTime()));
calendarT.set(Calendar.DAY_OF_MONTH,1);// 当月第一天
System.out.println("当月第一天:"+DATETIME_FORMATER_WITHWEEK.format(calendarT.getTime()));
//roll不会进位
calendarT.roll(Calendar.DATE,-1);
System.out.println("roll -1:"+DATETIME_FORMATER_WITHWEEK.format(calendarT.getTime()));
calendarT.set(Calendar.DAY_OF_MONTH,1);// 当月第一天
calendarT.add(Calendar.DATE,-1);
//add产生进位
System.out.println("add -1:"+DATETIME_FORMATER_WITHWEEK.format(calendarT.getTime()));
//output:原始 :2015-04-16 星期四
当月第一天:2015-04-01 星期三
roll -1:2015-04-30 星期四
add -1:2015-03-31 星期二
最后还是需要说明一点,获取当前时间指的是当前本地时间对应的UTC时间,和时区没有关系!有点绕,没关系看代码:
例子4:
Calendar calendar1 = Calendar.getInstance(Locale.CHINA);
Calendar calendar2 = Calendar.getInstance(Locale.GERMAN);
System.out.println(calendar1.getTimeInMillis());
System.out.println(calendar2.getTimeInMillis());
//output:
1429115150117
1429115150117
最后贴一个日期处理开源库:joda-time
Java中日期时间API小结的更多相关文章
- Java 8 新特性-菜鸟教程 (8) -Java 8 日期时间 API
Java 8 日期时间 API Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理. 在旧版的 Java 中,日期时间 API 存在诸多问题,其中有: ...
- Java 8 日期时间 API
转自:https://www.runoob.com/java/java8-datetime-api.html Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与 ...
- Java 8 日期时间API
Java 8一个新增的重要特性就是引入了新的时间和日期API,它们被包含在java.time包中.借助新的时间和日期API可以以更简洁的方法处理时间和日期; 在介绍本篇文章内容之前,我们先来讨论Jav ...
- Java 8 日期时间API使用介绍
如何正确处理时间 现实生活的世界里,时间是不断向前的,如果向前追溯时间的起点,可能是宇宙出生时,又或是是宇宙出现之前, 但肯定是我们目前无法找到的,我们不知道现在距离时间原点的精确距离.所以我们要表示 ...
- [转载]Java 8 日期&时间 API
Java 8 日期和时间 声明 本文转自http://www.journaldev.com/2800/java-8-date-localdate-localdatetime-instant,以mark ...
- Java 中 日期 时间 加减
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //方法1(推荐,功能强大灵活多变) Ca ...
- 【转】JAVA 8 日期/时间(Date Time)API指南
前言 本来想写下Java 8的日期/时间API,发现已经有篇不错的文章了,那就直接转载吧~ PS:主要内容没变,做了部分修改. 原文链接: journaldev 翻译: ImportNew.com - ...
- 《Java 8实战》读书笔记系列——第三部分:高效Java 8编程(四):使用新的日期时间API
https://www.lilu.org.cn/https://www.lilu.org.cn/ 第十二章:新的日期时间API 在Java 8之前,我们常用的日期时间API是java.util.Dat ...
- JDK8中的时间API
在Java 1.0中,对日期和时间的支持只能依赖java.util.Date类.正如类名所表达的,这个类无法表示日期,只能以毫秒的精度表示时间.更糟糕的是它的易用性,由于某些原因未知的设计决策,这个类 ...
随机推荐
- Linux学习一些在Terminal可以用到的快捷键及Shell常用的通配符
Ctrl+c 终断程序 Ctrl+d 键盘输入结束或退出终端 Ctrl+s 暂定当前程序,暂停后按下任意键恢复运行 Ctrl+z 将当前程序放到后台运行,恢复到前台为命令fg Ctrl+a 将光标移至 ...
- 华硕笔记本怎么设置u盘启动(两种方法)
华硕笔记本怎么设置u盘启动(两种方法) 华硕笔记本怎么设置u盘启动.我想用U盘安装系统但是 我不知道如何设置U盘启动,那么该如何设置呢?下面和大家分享一下我的经验,希望能够帮到大家.如果你的系统是预装 ...
- (转)ligerUI 使用教程之Tip介绍与使用
概述: ligertip是ligerUI系列插件中的tooltip类插件,作用是弹一个浮动层,起提示作用 阅读本文要求具备jQuery的基本知识,不然文中的javascript代码不易理解 截 ...
- arcmap从excel坐标数据生成点shp文件
概述 今天试图在ArcMap中将excel数据转成点文件,在"Display XY Data"的时候,无法选择X,Y字段,很是纳闷,原来Excel中列的格式是文本,导致无法选择.有 ...
- spring-security 登陆认证之初次探究
首先,希望还对 spring-security框架完全不懂的新手 下载下Git源码. 引入到项目中.这个短文就是边看源码边聊的.也会启动下项目验证自己的推想. 一.登陆认证的登陆配置项 <for ...
- [Leetcode][019] Remove Nth Node From End of List (Java)
题目在这里: https://leetcode.com/problems/remove-nth-node-from-end-of-list/ [标签] Linked List; Two Pointer ...
- CentOS(Linux) - SVN使用笔记(二) - 创建SVN仓库及下载仓库到本地
1.安装: 参考文章 CentOS(Linux) - SVN使用笔记(一) - 安装SVN过程及开启和关闭svn服务指令 2.创建仓库 #创建项目目录 mkdir /usr/svn#进入目录cd / ...
- The use of function Merge (update、insert、delete)
1.The use of function merge(update.insert.delete) Example: #1.Initialize the data create table #test ...
- jquery多级联动(ajax查数据库)
/id 代表下级下拉框ID,cityCode代表的是父级菜单代码,所有级菜单在同一张表,后台在加载是把菜单已经加入到Map缓存中.... //id 代表下级下拉框ID,cityCode代表的是父级菜单 ...
- Anisotropic gauss filter
最近一直在做版面分析,其中文本行检测方面,许多文章涉及到了Anigauss也就是各向异性高斯滤波. 顾名思义,简单的理解就是参数不同的二维高斯滤波. 在文章Fast Anisotropic Gauss ...