Java 日期时间
Java 日期时间
标签 : Java基础

Date
java.util.Date对象表示一个精确到毫秒的瞬间; 但由于Date从JDK1.0起就开始存在了,历史悠久,而且功能强大(既包含日期,也包含时间),所以他的大部分构造器/方法都已Deprecated,因此就不再推荐使用(如果贸然使用的话,可能会出现性能/安全方面的问题);下面我仅介绍它还剩下的为数不多的几个方法(这些方法的共同点是Date与毫秒值的转换):
构造器
Date(): 在底层调用System.currentTimeMillis()作为日期参数.Date(long date): 根据指定的long整数(从1970-1-1 00:00:00以来经过的毫秒数)来生成Date对象.
方法
boolean after(Date when): 测试this日期是否在指定日期when之后;boolean before(Date when): 测试this日期是否在指定日期when之前;long getTime(): 获取从1979-01-01 00:00:00 到Date对象之间经过的毫秒值;void setTime(long time): 设置时间,time含义上同.
/**
* Created by jifang on 15/12/30.
*/
public class DateTest {
@Test
public void test() {
Date dateBefore = new Date();
Date dateAfter = new Date(System.currentTimeMillis() + 1);
System.out.println("before: " + dateBefore.getTime());
System.out.println("after: " + dateAfter.getTime());
System.out.println(dateBefore.before(dateAfter));
System.out.println(dateAfter.after(dateBefore));
dateBefore.setTime(System.currentTimeMillis());
System.out.println(dateBefore.getTime());
System.out.println(dateBefore.before(dateAfter));
}
}
Calendar
由于Date存在缺陷,所以JDK又提供了java.util.Calendar来处理日期和时间.Calendar是一个抽象类,是所有日历类的模板,因此,我们可以继承Calendar来实现其他的历法(比如阴历);
Java中提供了一种Calendar的默认实现java.util.GregorianCalendar格里高利日历(其实JDK还默认提供了一款日本历法java.util.JapaneseImperialCalendar),也就是我们所说的公历. 使用Calendar.getInstance();获取的就是默认的GregorianCalendar,getInstance()方法的内部会调用cal = new GregorianCalendar(zone, aLocale);来生成一个格里高利日历实例.
- Calendar还可以和Date自由转换.
public class CalendarTest {
@Test
public void test() {
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
Calendar newCalendar = Calendar.getInstance();
newCalendar.setTime(date);
System.out.println(calendar.get(Calendar.DATE));
}
}
- Calendar类提供了大量访问/修改日期/时间的方法, 常用的方法如下:
| Method | Description |
|---|---|
void add(int field, int amount) |
Adds or subtracts the specified amount of time to the given calendar field, based on the calendar’s rules. |
int get(int field) |
Returns the value of the given calendar field. |
int getActualMaximum(int field) |
Returns the maximum value that the specified calendar field could have, given the time value of this Calendar. |
int getActualMinimum(int field) |
Returns the minimum value that the specified calendar field could have, given the time value of this Calendar. |
void roll(int field, int amount) |
Adds the specified (signed) amount to the specified calendar field without changing larger fields. |
void set(int field, int value) |
Sets the given calendar field to the given value. |
void set(int year, int month, int date) |
Sets the values for the calendar fields YEAR, MONTH, and DAY_OF_MONTH. |
void set(int year, int month, int date, int hourOfDay, int minute, int second) |
Sets the values for the fields YEAR, MONTH, DAY_OF_MONTH, HOUR, MINUTE, and SECOND. |
void setTimeInMillis(long millis) |
Sets this Calendar’s current time from the given long value. |
long getTimeInMillis() |
Returns this Calendar’s time value in milliseconds. |
上面的很多方法都需要一个int类型的field参数, field是Calendar类的类变量, 如:Calendar.DATE Calendar.MONTH Calendar.HOUR Calendar.DAY_OF_WEEK, 但需要指出的是Calendar.MONTH月份的起始值不是1, 而是0(一月:0, 二月:1 …), Calendar.DAY_OF_WEEK代表的星期, 起始值是周日(周日:1, 周一:2 …)(其他细节请参考JDK文档).
注意:
- 如果
Calendar没有设置相关的值, 就以当前系统时间来设置. add(int field, int amount)的功能非常强大, 如果需要增加某字段, 则让amount为正数, 如果要减少某字段的值, 让amount为负数. 且当超出他的允许范围时, 会发生进位.roll()的含义与用法和add()的类似,但是当被修改的字段超出它允许的范围时, 他不会进位.set(int field, int value)方法具有延迟修改的功能:他内部设置了一个成员变量,以指示日历字段field已经被修改,但是该Calendar所代表的时间不会立即修改, 他会直到下次调用get/getTime/getTimeInMillis/add/roll时才会重新计算日历时间.
public int get(int field)
{
complete();
return internalGet(field);
}
public long getTimeInMillis() {
if (!isTimeSet) {
updateTime();
}
return time;
}
测试
public class CalendarTest {
@Test
public void test() {
Calendar calendar = Calendar.getInstance();
calendar.set(2011, Calendar.JULY, 31);
calendar.set(Calendar.MONTH, Calendar.SEPTEMBER);
// 将下面注释放开, 再测试
// System.out.println(calendar.get(Calendar.MONTH) + 1 + "月" + calendar.get(Calendar.DATE) + "日");
calendar.set(Calendar.DATE, 5);
System.out.println(calendar.get(Calendar.MONTH) + 1 + "月" + calendar.get(Calendar.DATE) + "日");
}
}
日期格式化
完成字符串与日期对象的转化(format/parse)
DateFormat
java.text.DateFormat是一个抽象类, 他提供了如下几个方法获取DateFormat对象.
| 方法 | 描述 |
|---|---|
static DateFormat getDateInstance() |
Gets the date formatter with the default formatting style for the default locale. |
static DateFormat getDateTimeInstance() |
Gets the date/time formatter with the default formatting style for the default locale. |
static DateFormat getTimeInstance() |
Gets the time formatter with the default formatting style for the default locale. |
其实上面三个方法还可以指定日期/时间的样式, 如FULL/LONG/MEDIUM/SHOT, 通过这四个样式参数可以控制生成的格式化字符串. 但由于在我们的实际开发中很少直接用DateFormat类,因此就不对其做过多的介绍.而我们比较常用的是其子类SimpleDateFormat(其实上面几个getXxxInstance方法返回的也是SimpleDateFormat实例)
DateFormat dateFormat = DateFormat.getTimeInstance();
System.out.println(dateFormat.getClass().getName());
SimpleDateFormat
java.text.SimpleDateFormat可以非常灵活的格式化Date, 也可以用于解析各种格式的日期字符串.创建SimpleDateFormat对象时需要传入一个pattern字符串,这个pattern不是正则表达式,而是一个日期模板字符串.
/**
* Created by jifang on 15/12/30.
*/
public class FormatTest {
@Test
public void client() throws ParseException {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
// Date -> String
Date date = new Date(System.currentTimeMillis());
System.out.println(format.format(date));
// String -> Date
String timeString = "2015-12-30 08:53:21";
Date newDate = format.parse(timeString);
System.out.println(newDate);
}
}
在时间日期格式化时, 有下面几个方法是最常用的:
| 方法 | 描述 | 小结 |
|---|---|---|
String format(Date date) |
Formats a Date into a date/time string. | Date -> String |
Date parse(String source) |
Parses text from the beginning of the given string to produce a date. | String -> Date |
当然, pattern我们还可以根据我们的需求有其他的定制形式:
@Test
public void client() throws ParseException {
DateFormat format = new SimpleDateFormat("yy年MM月dd日 hh时mm分ss秒");
// Date -> String
Date date = new Date(System.currentTimeMillis());
System.out.println(format.format(date));
// String -> Date
String timeString = "15年12月30日 09时00分29秒";
Date newDate = format.parse(timeString);
System.out.println(newDate);
}
可以看出SimpleDateFormat把日期格式化成怎样的字符串以及能把怎样的字符串解析成Date, 完全取决于创建对象时指定的pattern参数,其他的pattern参数以及SimpleDateFormat的方法可以参考JDK文档.
数据库存储时间实战
由于时间存储会涉及到跨时区的问题(同一个UTC时间在各个时区显示的是不同的数值).因此,在我们向数据库中插入时间是需要小心谨慎,不能简单单单的使用数据库提供的TIMESTAMP或是DATETIME 类型,比较推荐的是选用一个整数类型(如BIGINT64位与Java的Long类型相同),来存储从`1970-01-01 00:00:00到时间点所经过的毫秒数(具体原因详见:如何正确地处理时间).
- 这样做的优点是:读取时间时(一个Long类型整数),只需要按照用户的时区格式化为字符串就能正确地显示出来.
- 当然这样做也存在缺陷,那就是当我们开发人员/DB直接查看数据库时,看到的只是一串数字,并不能清楚的知晓其对应的时间日期.
上面讲完了数据库该如何存储时间值,下面我们再聊一聊时间[存入/读出]数据库的转化问题:
- 从Date转换成Long 很简单:
Date date = new Date();
long time = date.getTime();
- 从Long转换成一个时间的String我们需要
SimpleDateFormat的一个方法:
// Formats an object to produce a string.| Object -> String
String format(Object obj);
// 当然pattern字符串可以指定为其他值
String time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(System.currentTimeMillis());
配置单例Formatter
由于在一个项目中时间格式化和解析的格式一般只有一种(我们应该不希望格式化之后的time到最后反而解析不出来),因此我们没有必要每次使用时都new出一个Formatter来,这样不光会造成性能下降还有可能造成时间形式不统一而出错.因此,我们可以在Sring的容器中装载一个Formatter Bean,使用时@Autowired就可以了:
<!-- 配置时间格式化器 -->
<bean id="dateFormatter" class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd HH:mm:ss"/>
</bean>
@Autowired
private DateFormat dateFormatter;
...
String time = dateFormatter.format(System.currentTimeMillis());
Java 日期时间的更多相关文章
- Java日期时间使用(转)
Java日期时间使用总结 转自:http://lavasoft.blog.51cto.com/62575/52975/ 一.Java中的日期概述 日期在Java中是一块非常复杂的内容,对于一个 ...
- Java日期时间处理
Java 日期时间处理 一.时间相关类 java.lang.System java.util.Date java.util.Calendar java.util.GregorianCalendar j ...
- Java日期时间,以及相互转换
Java日期时间,以及相互转化 package com.study.string; import java.text.ParseException; import java.text.SimpleDa ...
- Java 日期时间 Date类型,long类型,String类型表现形式的转换
Java 日期时间 Date类型,long类型,String类型表现形式的转换 1.java.util.Date类型转换成long类型 java.util.Date dt = new Date(); ...
- Java日期时间使用总结[转载]
Java日期时间使用总结 一.Java中的日期概述 日期在Java中是一块非常复杂的内容,对于一个日期在不同的语言国别环境中,日期的国际化,日期和时间之间的转换,日期的加减运算,日期的展示格式 ...
- Java-Runoob:Java 日期时间
ylbtech-Java-Runoob:Java 日期时间 1.返回顶部 1. Java 日期时间 java.util 包提供了 Date 类来封装当前的日期和时间. Date 类提供两个构造函数来实 ...
- Java日期时间实用工具类
Java日期时间实用工具类 1.Date (java.util.Date) Date(); 以当前时间构造一个Date对象 Date(long); 构造函数 ...
- Java 日期时间格式化
在此记录Java日期时间格式化转换符,方便以后有需要时查找. 1.日期格式化 2.时间格式化 3.格式化常见的日期时间组合
- Java 日期时间 Date类型,long类型,String类型表现形式的转换 (转)
Java 日期时间 Date类型,long类型,String类型表现形式的转换 1.java.util.Date类型转换成long类型java.util.Date dt = new Date();Sy ...
随机推荐
- 3139:[HNOI2013]比赛 - BZOJ
题目描述 Description 沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛.此次联赛共N只队伍参加,比赛规则如下: (1) 每两支球队之间踢一场比赛. (2) 若平局,两支 ...
- 【转载】hadoop的版本问题
免责声明: 本文转自网络文章,转载此文章仅为个人收藏,分享知识,如有侵权,请联系博主进行删除. 原文作者:阿笨猫 原文地址:http://www.cnblogs.com/xu ...
- IntelliJ IDEA的Maven项目在修改时报java.lang.OutOfMemoryError: PermGen space异常
什么也不说了---内存溢出,遇见太多回了,下面是解决方式: 1.在项目设置中新建Maven,然后设置VM: 2. 在pom.xml添加下面2个插件,一个是jrebel的,一个是jetty的 <b ...
- error C2061: syntax error : identifier '__RPC__out_xcount_part'
朋友遇到的 把dx, windows sdk ,vs2010照着成功人士的配置好 应该就可以了
- VC6.0环境安装STLport-5.2.1
今天安装STLport,网上搜资料安装好久,都不行,因为STLport 的版本不对,我这是STLport-5.2.1新版本. (注意:下面的步骤都在一个cmd里操作,很简单的原因:环境变量啊) 1.首 ...
- uva 10303
卡特兰数 但是个高精度 一开始用最普通的递推式 超时了 百度百科了一下 用另类递推式过了 ~~ 这个大数类是做数据结构课程设计的时候写的... #include <cstdio> #in ...
- css ul li 制作导航条
<html> <head> <style> .test ul{list-style:none;} .test li{float:left; width:100px; ...
- 国内最大的 Node.js 社区将 New Relic 的监控产品换成了 OneAPM
国内最知名的 CNode 社区把 New Relic 的监控产品换成了 OneAPM .难道 APM 的老大 New Relic 已经被 OneAPM 超越? 毋庸置疑,在全球应用性能管理 SaaS ...
- 【面试题002】java实现的单例模式,c++实现单例模式,实现禁止拷贝
[面试题002]java实现的单例模式,c++实现单例模式,实现禁止拷贝 一 c++实现单例模式 保证一个类,在一个程序当中只有一个对象,只有一个实例,这个对象要禁止拷贝,注意这里要区别于java. ...
- lintcode:1-10题
难度系数排序,容易题1-10题: Cosine Similarity new Fizz Buzz O(1)检测2的幂次 x的平方根 不同的路径 不同的路径 II 两个字符串是变位词 两个 ...