在看这篇博文之前,请先看我之前的博文。
TimeZone
import java.util.TimeZone;TimeZone表示一个时区(相对UTC)的偏移量,并且可以推算出夏令时,始于JDK1.1。 简而言之,用来表示各个时区。
常用时区
- Asia/Shanghai
- Asia/Urumqi
- Hongkong
- Europe/London
- America/Los_Angeles
- Japan
1 | TimeZone aDefault = TimeZone.getDefault(); //获取当前程序运行环境的默认TimeZone |
ps: TimeZone.getTimeZone("Asia/Shanghai")中参数也可直接填写”UTC+XX00”或”UTC-XX00”。
Locale
import java.util.Locale;Locale类用来标识一个特定的地理位置,或政治、文化地区。
当进行一些”地区敏感”的操作时,需要用到该类。例如展示日期,不同地区展示日期的格式是不同的。
常见Locale
Locale有以下三种表示方式:
- 语言:例如
zh,表示所有官方语言为中文的国家或地区。 - 语言+国家:例如
zh_CN,约定只用于表示中国。 - 语言+国家+变体:例如
zh_CN_Kwangtung,表示中国广东。变体也可理解为版本,中国的不同版本即中国的不同地区。
第三种表示方式不常用,一般都使用第二种方式。
常用语言地区
zh= 中文地区en= 英语地区ja= 日语地区ko= 韩语地区
常用国家/地区
- zh_CN = 中国
- zh_HK = 中国香港
- zh_TW = 中国台湾
- en_US = 美国
- en_GB = 英国
- ja_JP = 日本
- ko_KR = 韩国
使用
Locale类里已经声明两类常用的Locale常量:语言和国家,直接使用即可。
语言
1 | Locale chinese = Locale.CHINESE; //中文 |
国家
1 | Locale china = Locale.CHINA; //中国 |
自定义,可使用以下三个构造方法new一个Locale类
1 | public Locale(String language); //语言 |
其他使用
1 | Locale aDefault = Locale.getDefault(); //获取当前程序运行环境的默认Locale |
Date
import java.util.Date;拥有毫秒级精确度的、用来表示一个特定时刻的Java类,始于JDK1.0。
Date类目前只有两个推荐使用的构造方法,其余已被弃用。
- 使用无参构造函数
new一个Date类,表示当前时刻。内部实现:new Date(System.currentTimeMillis())(非源码,仅用于表意);
1 | Date date = new Date(); |
- 使用
Unix时间戳new一个Date类,10位、13位时间戳皆可;
1 | Date date = new Date(1583547742); |
Question:如何初始化一个指定时刻的Date类?| 如何更改Date对象的年、月、日等?
Answer:初始化指定时刻的构造方法和Date类的setMonth()、setDate()、setHour()等方法已被弃用,改用Calendar类。
转换
使用SimpleDateFormat类可将Date转化为指定ISO格式字符串、或解析符合ISO格式的字符串为Date类。
Date转String
1 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //new SimpleDateFormat()时指定ISO格式 |
Date转指定时区String
1 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //new SimpleDateFormat()时指定ISO格式 |
String转Date,注意此时字符串中日期格式要与SimpleDateFormat指定的格式相符;
1 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //new SimpleDateFormat()时指定ISO格式 |
Date转时间戳,注意此时的timeStamp为13位;
1 | Date date = new Date(); |
Calendar
import java.util.Calendar;Calendar类提供了一些方法用于转换特定的时刻和Calendar字段(如YEAR、MONTH、DAY_OF_MONTH等)。Calendar类还提供了一些操作Calendar字段的方法,例如”getFirstDayOfWeek()”。- 简而言之,
Calendar是专门用来操作年月日时分秒的类。 Calendar始于JDK1.1。
实例化
当前时间
Calendar中的两个构造方法均为protected,因此只能使用静态方法getInstance()来创建Calendar对象。
1 | Calendar calendar = Calendar.getInstance(); //初始化一个表示当前时刻的Calendar对象 |
getInstance()共有四个重载方法,用来初始化不同时区、不同地区的Calendar对象。
1 | public static Calendar getInstance(); //默认时区、默认地区 |
注意:getInstance()方法最终会将时间设为System.currentTimeMillis()。
指定时间
在调用getInstance()创建Calendar对象之后,再调用下述set方法可将Calendar置为指定时间。
1 | public final void setTime(Date date); //根据Date类来设定 |
转换
Calendar转Date
1 | Calendar calendar = Calendar.getInstance(); |
Date转Calendar
1 | Calendar calendar = Calendar.getInstance(); |
Calendar转String
先将Calendar转为Date类,再使用SimpleDateFormat类将Date转String。
使用
Calendar常用的几个方法。
get()
获取指定字段的值,返回值为int。
1 | public int get(int field); |
上述结果为:year = 2020,month = 2,day = 10,dayOfWeek = 3
getDisplayName()
获取指定字段的值,返回值为String。
1 | public String getDisplayName(int field, int style, Locale locale); //根据style和locale展示某个field的值 |
上述结果为:shortMon = Dec,narrowMon = D,longMon = December
注意:
- 一般只使用
Calendar.SHORT、Calendar.LONG两种style。Calendar.NARROW_FORMAT只显示首字母,存在重复无法识别的情况。 get()获取到的是数字值,getDisplayName()获取到的是String值。Year、Day这类数据只有int一种表示方法,因此使用getDisplayName()会返回null。
getDisplayNames()
获取某个字段的所有展示值,返回值为Map<String, Integer>。
1 | public String getDisplayNames(int field, int style, Locale locale); //根据style和locale展示某个字段的所有展示 |
上述结果为:
chinaNames = {星期二=3, 星期六=7, 星期三=4, 星期四=5, 星期五=6, 星期日=1, 星期一=2}
usNames = {Monday=2, Thursday=5, Friday=6, Sunday=1, Wednesday=4, Tuesday=3, Saturday=7}add()
1 | abstract public void add(int field, int amount); //增、减某个字段的值,amount正为增,负为减 |
注意:若当前为3月,amount为-5,add()之后月份为9月;日期类似,也可倒退到1之前。
比较
1 | public boolean before(Object when); //是否早于 |
获取时间戳
1 | // 精确到毫秒 |
LocalDateTime 优先使用该库
为什么使用
LocalDateTime是Java8推出的Date类的升级版,若条件允许,推荐使用LocalDateTime。Date体系混乱且复杂,存在两个java.util.Date、java.sql.Date类,还需配套的Calendar、TimeZone、Locale类等。Date若不格式化,打印出的日期可读性差,而SimpleDateFormat格式化Date的操作是线程不安全的。LocalDateTime简单,学习简单、使用简单。
引用
import java.time.LocalDateTime;实例化
构造方法访问权限为private,不可用。使用静态方法now()来实例化。
1 | LocalDateTime now = LocalDateTime.now(); //实例化一个表示当前时间的LocalDateTime类 |
或者使用静态方法of()直接指定年月日时分秒来实例化。
1 | LocalDateTime time1 = LocalDateTime.of(2020, 3, 10, 18, 22, 34, 633); //指定 年月日、时分秒、纳秒 |
注意:
- 月的范围是
1到12,也可用枚举类java.time.Month来代替。 - 日的范围是
1到31,时的范围是0到23,分、秒的范围是0到59。 - 若使用
of()时超出上述范围,编译会报错。
转换
LocalDateTime转String
利用toString()方法进行转换,其默认格式为:yyyy-MM-ddTHH:mm:ss.SSS
1 | LocalDateTime now = LocalDateTime.now(); |
或者使用LocalDateTime的format()方法转换为自定义格式的String。通过DateTimeFormatter来指定需要的String格式。
1 | LocalDateTime now = LocalDateTime.now(); |
注:ISO 8601标准格式转换DateTimeFormatter.ofPattern(“yyyy-MM-dd’T’HH:mm:ss’Z’”)
DateTimeFormatter有15种内置格式(以下为部分):
DateTimeFormatter.BASIC_ISO_DATE 20200310
DateTimeFormatter.ISO_LOCAL_DATE_TIME 2020-03-10T18:30:34
DateTimeFormatter.ISO_LOCAL_DATE 2020-03-10
DateTimeFormatter.ISO_DATE_TIME 2020-03-10T18:30:34
DateTimeFormatter.ISO_ORDINAL_DATE 2020-070LocalDateTime转指定时区的String
1 | LocalDateTime now = LocalDateTime.now(ZoneId.of("UTC")); //实例化时指定时区 |
或者
1 | LocalDateTime now = LocalDateTime.now(); |
String转LocalDateTime
使用LocalDateTime.parse()进行解析,String中的时间格式必须与DateTimeFormatter的pattern匹配。
1 | String time = "2020-03-10 11:11:11"; |
Date转LocalDateTime
时间戳是所有系统通用的表示时间的方式,因此通过时间戳来转换Date和LocalDateTime。
具体使用LocalDateTime.ofInstant()进行转换(Java中将时间戳抽象为Instant类)。
1 | Date date = new Date(); |
注:因为时间戳不带有任何地区信息,所以ofInstant()方法需要借助ZoneId类。
LocalDateTime转Date
借助Instant类使用Date.from()方法来转换。
1 | LocalDateTime now = LocalDateTime.now(); |
注:ZoneOffset.of(“+8”)中 +8 代表中国时区,其他时区可+/- N。
LocalDateTime转Unix
1 | long utc = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC); //转表示UTC的unix |
使用
LocalDateTime常用的几类方法。
获取某个字段值
1 | LocalDateTime now = LocalDateTime.now(); |
加减
- 加减操作有三类方法,分别以
plus、minus、with开头; - 三类方法入参都可正可负,意味着每类方法都可以单独实现加、减两个功能,但是根据约定
plus用来加,minus用来减; minus实际调用了plus方法,而plus方法最终又调用了with方法;
1 | LocalDateTime now = LocalDateTime.now(); |
注意:三类方法并不改变自己身的值,而是返回一个修改过值得副本。
比较
1 | LocalDateTime now = LocalDateTime.now(); |
计算
利用java.time.Duration类来计算两个LocalDateTime之间的时间差。
1 | LocalDateTime now = LocalDateTime.now(); |