JDK8 之前日期时间API
首先我们需要知道时区的概念,同一时刻不同时区他们的表上的时间是不一样的。所以,我们在存取时间的时候,尽量存时间戳而不是时间字符串。特别是国际化的项目,一定是存时间戳(Epoch Time),而不能是时间字符串。
在java中,用长整型来存放时间戳(毫秒数);
标准库API
我们再来看一下Java标准库提供的API。Java标准库有两套处理日期和时间的API:
- 一套定义在
java.util
这个包里面,主要包括Date
、Calendar
和TimeZone
这几个类; - 一套新的API是在Java 8引入的,定义在
java.time
这个包里面,主要包括LocalDateTime
、ZonedDateTime
、ZoneId
等。
为什么会有新旧两套API呢?因为历史遗留原因,旧的API存在很多问题,所以引入了新的API。
那么我们能不能跳过旧的API直接用新的API呢?如果涉及到遗留代码就不行,因为很多遗留代码仍然使用旧的API,所以目前仍然需要对旧的API有一定了解,很多时候还需要在新旧两种对象之间进行转换。
获取当前时间戳
在java中获取当前时间戳的最简单方法就是System.currentTimeMillis()。
Date
java.util.Date表示特定的瞬间,精确到毫秒。
对于Date类,我们只需掌握两种构造器的使用,以及两个常用方法
下面,我们来看Date类的构造方法如何使用。该构造方法可以传入一个参数——时间戳。如果不传,则表示当前时间戳。
new Date(); // 没有参数,则表示当前时间戳
new Date(1609380374486L); // 传入一个毫秒时间戳
getTime()方法用来获取时间戳。通过该方法,也可以获取当前的时间戳。
Date d = new Date();
long t = d.getTime();
setTime()方法用来重新设置时间戳。
SimpleDateFormat
java.text.SimpleDateFormat
Date类是用来表示时间戳的,对于如何将Date格式化指定日期格式,以及从一个字符串日期格式解析出一个Date,就需要SimpleDateFormat。
我们需要掌握它的一个构造器的使用,以及两个方法的使用:
:该构造方法可以用参数pattern指定的格式创建一个对象public SimpleDateFormat(String pattern)
:格式化日期对象Datepublic String format(Date date)
:从给定字符串的开始解析文本,以生成一个日期对象。public Date parse(String source)
首先来看看构造器的使用,构造器里传入一个指定的格式,文档里展示的一些常用的格式如下表:
Date and Time Pattern | Result |
---|---|
"yyyy.MM.dd G 'at' HH:mm:ss z" |
2001.07.04 AD at 12:08:56 PDT |
"EEE, MMM d, ''yy" |
Wed, Jul 4, '01 |
"h:mm a" |
12:08 PM |
"hh 'o''clock' a, zzzz" |
12 o'clock PM, Pacific Daylight Time |
"K:mm a, z" |
0:08 PM, PDT |
"yyyyy.MMMMM.dd GGG hh:mm aaa" |
02001.July.04 AD 12:08 PM |
"EEE, d MMM yyyy HH:mm:ss Z" |
Wed, 4 Jul 2001 12:08:56 -0700 |
"yyMMddHHmmssZ" |
010704120856-0700 |
"yyyy-MM-dd'T'HH:mm:ss.SSSZ" |
2001-07-04T12:08:56.235-0700 |
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX" |
2001-07-04T12:08:56.235-07:00 |
"YYYY-'W'ww-u" |
2001-W27-3 |
一般来说,字母越长,输出越长。以M
为例,假设当前月份是9月:
M
:输出9
MM
:输出09
MMM
:输出Sep
MMMM
:输出September
我们开发中经常用到的格式总结如下:
Date and Time Pattern | Result |
---|---|
"yyyy-MM-dd HH:mm:ss" |
|
|
下面看两个例子,格式化Date以及从一个日期时间字符串解析出Date,获取时间戳。
案例一:
// 格式化日期
var sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
var date = new Date();
System.out.println(sdf.format(date));
// 2021-02-26 19:06:51
案例二:
// 解析Date
var dateStr = "2019-01-03 32:23:00";
var sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
var date = sdf.parse(dateStr);
System.out.println(date.getTime()); // 1546561380000
Calendar
java.util.Calendar
Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能。获取Calendar实例的方法:
- 使用Calendar.getInstance()方法
- 调用它的子类GregorianCalendar的构造器。
一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来取得想要的时间信息。比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY 、MINUTE、SECOND
注意:
- 获取月份时:一月是0,二月是1,以此类推,12月是11
- 获取星期时:周日是1,周二是2 , 。。。。周六是7
对于Calendar,我们需要掌握其5个方法:
-
public void get(int field)
-
public void set(int field,int value)
-
public void add(int field,int amount)
-
public final Date getTime()
-
public final void setTime(Date date)
get用法
// 获取当前时间:
Calendar c = Calendar.getInstance();
int y = c.get(Calendar.YEAR);
int m = 1 + c.get(Calendar.MONTH);
int d = c.get(Calendar.DATE);
int w = c.get(Calendar.DAY_OF_WEEK) - 1;
int hh = c.get(Calendar.HOUR_OF_DAY);
int mm = c.get(Calendar.MINUTE);
int ss = c.get(Calendar.SECOND);
int ms = c.get(Calendar.MILLISECOND);
System.out.println(y + "-" + m + "-" + d + " " + w + " " + hh + ":" + mm + ":" + ss + "." + ms);
set用法
set方法可以设置我们想要的日期时间
// 设置为2018-08-23
public class T10
{
public static void main (String[] args) throws Exception
{
// 设置为2018-08-23
var c = Calendar.getInstance();
c.set(Calendar.YEAR, 2018);
c.set(Calendar.MONTH, 7);
c.set(Calendar.DATE, 23);
printDate(c); // 2018-8-23 4 20:10:18.471
}
private static void printDate (Calendar c)
{
int y = c.get(Calendar.YEAR);
int m = 1 + c.get(Calendar.MONTH);
int d = c.get(Calendar.DATE);
int w = c.get(Calendar.DAY_OF_WEEK) - 1;
int hh = c.get(Calendar.HOUR_OF_DAY);
int mm = c.get(Calendar.MINUTE);
int ss = c.get(Calendar.SECOND);
int ms = c.get(Calendar.MILLISECOND);
System.out.println(y + "-" + m + "-" + d + " " + w + " " + hh + ":" + mm + ":" + ss + "." + ms);
}
}
add用法
add可以非常的方便获取一周前、三天后这样的时间。
// 设置为2018-08-23
var c = Calendar.getInstance();
// 加5天并减去2小时:
c.add(Calendar.DAY_OF_MONTH, 5);
c.add(Calendar.HOUR_OF_DAY, -2);
printDate(c); // 2021-3-3 3 18:18:2.600
getTime、setTime
这两个方法没什么好说的了,一个用于获取Date对象,一个用于从Date对象来设置时间。