1 Instant
Instant 表示基于世界标准时间(UTC)的时间线上的某一个时间点,通常用作事件的时间戳。
Instant 取值为 基于世界标准时间 从 1970/01/01 00:00:00.000 到 某一个时间点 经历的时长(秒 + 纳秒),例如:
instantValue = 0s:表示 1970/01/01 00:00:00.000 (UTC) 或 1970/01/01 08:00:00.000 (UTC+8)
instantValue = 3600s:表示 1970/01/01 01:00:00.000 (UTC) 或 1970/01/01 09:00:00.000 (UTC+8)
// 获取当前时间点
Instant instant = Instant.now();
// 获取指定时间点(毫秒)
Instant instant = Instant.ofEpochMilli(long epochMilli);
// 获取指定时间点(秒)
Instant instant = Instant.ofEpochSecond(long epochSecond);
// 获取时间点值(毫秒)
long instantValue = instant.toEpochMilli();
注意:
当通过指定时间点的方式创建Instant对象时,参数值应该是基于世界标准时间的值。
2 ZoneId
ZoneId 表示时区,例如:北京时区为东八区,即 UTC+8 。
// 获取当前系统默认时区
ZoneId zoneId = ZoneId.systemDefault();
// 获取指定时区:东八区
ZoneId zoneId = ZoneId.of("+08:00");
3 LocalDateTime
LocalDateTime 表示一个不含时区信息的时间,其组成包含两个部分:LocalDate 和 LocalTime
LocalDate 仅包含日期部分(即 年 月 日)
LocalTime 仅包含时间部分(即 时 分 秒)
通过1、2两节内容可知,要表示一个时间,需要 Instant 和 ZoneId 两个信息,即 基于世界标准时间的时间点 和 要表示的时间的时区 信息,这样,才可以计算得到一个相应的时间信息,例如:
instantValue = 3600s:表示 1970/01/01 01:00:00.000 (UTC)
zoneId = UTC+8:表示 东八区
localDateTime = 1970/01/01 01:00:00.000(UTC) + 时区偏移量(+8小时) = 1970/01/01 09:00:00.000 (UTC+8)
// 获取当前时间点
Instant instant = Instant.now();
// 获取当前系统默认时区
ZoneId zoneId = ZoneId.systemDefault();
// 获取当前系统默认时区的本地时间
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
// 快捷方式:获取当前系统默认时区的本地时间
LocalDateTime nowLocalDateTime = LocalDateTime.now();
通过上述说明可知,LocalDateTime仅保存一个时间信息,在构造其对象时,提供的 Instant 和 ZoneId 信息,只是为了计算对应时区的一个时间信息,LocalDateTime 对象构造完成后,即表示一个时间,但并不保存时区信息。因此,也可以通过直接指定时间的方式构造 LocalDateTime 对象。
// 直接指定时间
LocalDateTime localDateTime = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
由于 LocalDateTime 对象不保存时区信息,因此,就无法从其中获取 Instant 信息。因为没有时区信息,无法确定 LocalDateTime 表示的是哪里的时间,因此,无法确定对应的世界标准时间的时间点。例如:
1970年01月01日 16:00:00
只有一个时间信息,没有时区信息,无法知道这个时间是北京时间,还是纽约时间。
在实际应用过程中,LocalDateTime 对象通常用于时间格式化(显示时间),而不用于不同时区的时间转换。
4 ZonedDateTime
LocalDateTime 表示一个无时区信息的时间,而 ZonedDateTime 表示一个包含时区信息的时间。
当为 LocalDateTime 附上时区信息时,即可转化为 ZonedDateTime 对象。
// 表示 localDateTime 为 UTC+8 时区的时间
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("+08:00"));
Instant 也是一个仅包含时间信息的对象,因此,为 Instant 附上时区信息时,同样,可转化为 ZonedDateTime 对象。
// 基于 UTC+8 时区,将 instant 转化为 ZonedDateTime 对象。
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("+08:00"));
// 等同于如下代码
ZonedDateTime zonedDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("+08:00")).atZone(ZoneId.of("+08:00"));
由于 ZonedDateTime 包含时区信息,因此,可以从其中获取 Instant 对象信息,例如:
1970年01月01日 16:00:00 UTC+8
明确是东八区的时间,则对应的世界标准时间为 1970年01月01日 08:00:00 ,其 instantValue = 28800秒。
// 时区
ZoneId zoneId = zonedDateTime.getZone();
// 时间点
Instant instant = zonedDateTime.toInstant();
// 世界标准时间的时间点值
long timestamp = zonedDateTime.toInstant().toEpochMilli();
5 关系图解
上图描述了 Instant、ZoneId、LocalDateTime 和 ZonedDateTime 之间的关系。
需要说明的是,Instant 和 ZoneId 结合得到 LocalDateTime 步骤中,ZoneId 仅用于确定时间偏移量,从而计算得到该时区对应的时间,并由 LocalDateTime 对象保存时间信息,而时区信息并没有在 LocalDateTime 对象保存。
常见的时间异常情况,大部分是由于时区问题没有处理正确导致。这种情况,在网络传递时间数据的时候,时常发生,其根本原因是两端基于不同的时区对时间进行处理,例如:
服务端:基于UTC,返回时间字符串信息,如 timestamp = 1970/01/01 08:00:00,对应北京时间为 1970/01/01 16:00:00。
客户端:基于本地时区,处理服务端返回的时间字符串信息,即 将 1970/01/01 08:00:00 当成北京时间,导致时间差8小时。
6 时间格式化
在 Java 8 之前,通常使用 SimpleDateFormat 对时间进行格式化,但 SimpleDateFormat 不是线程安全的类,即 在多线程环境下使用共享的 SimpleDateFormat 对象(例如 static 对象),则可能发生异常情况。
因此,为了保证线程安全,在每个线程中,需要创建一个 SimpleDateFormat 对象,保证不同线程之间不会共享一个 SimpleDateFormat 对象。或者,通过 ThreadLocal 方式,达到线程隔离效果。
在 Java 8 之后,JDK 提供了 DateTimeFormatter 类,用于提供时间格式化方法。
// 初始化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 获取 当前系统默认时区 的 本地时间
LocalDateTime nowDateTime = LocalDateTime.now();
// 格式化时间
String dateTimeString = formatter.format(nowDateTime);
// 解析 时间字符串 得到 LocalDateTime 对象
LocalDateTime dateTimeObj = LocalDateTime.from(formatter.parse(dateTimeString));
7 相关文章
《字符串格式化:Formatter类》
import
java
.text.ParseException;
import
java
.text.Simple
Date
Format
;
import
java
.util.Locale;
import
java
.util.regex.Pattern;
public class
Format
Trans
format
ion {
public static void main(String[] args) throws ParseExc
DateTime
Format
ter
dateTime
Format
ter =
DateTime
Format
ter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSS");
Local
DateTime
now = LocalDa
Date
Format
java
.text.
Date
Format
Date
Format
提供了很多类方法,以获得基于默认或给定语言环境和多种
格式化
风格的默认
日期
/
时间
Format
ter。
格式化
风格包括 FULL、LONG、MEDIUM 和 SHORT。方法描述中提供了使用这些风格的更多细节和示例。
Date
Format
可帮助进行
格式化
并解析任何语言环境的
日期
。对于月、星期,
public class Deal
Date
Format
Util {
public static String deal
Date
(String old
Date
Str) throws ParseException {
Date
Format
df = new Simple
Date
Format
("yyyy-MM-dd'T'HH:mm:ss");
Date
date
= df.parse(o...
1、获取今天的
日期
2、指定
日期
,进行相应操作3、生日检查或者账单日检查4、获取当前的
时间
5、
日期
前后比较6、处理不同时区的
时间
7、比较两个
日期
之前
时间
差8、
日期
时间
格式
解析、
格式化
9、
java
8
时间
类与
Date
类的相互转化在
Java
8 以前,
日期
和
时间
处理一直被广大
java
程序员抱怨太难用,首先是和中,都包含类,如果要进行
时间
格式化
,还需要类处理。同时中既包含了
日期
,又包含了
时间
,所以
java
8 新的
日期
和
时间
库,很好的解决了以前
日期
和
时间
类的很多弊端。并且也借鉴了第三方
日期
库很多的优点。在
最近在开发项目过程中,发现返回的数据中现实的
日期
与数据库中
日期
大概相差8小时,这是因为直接从数据库中查询出来的
时间
是格林威治
时间
,而不是北京(东八区)
时间
,所以我们需要做
日期
格式化
,将格林威治
时间
转为北京
时间
,代码如下:
@Json
Format
(
shape = Json
Format
.Shape.STRING,
pattern = "yyyy-MM-dd HH:mm:ss",...
在
Java
8之前,我们使用Simple
Date
Format
和
Date
Format
类来表示一种
格式
,这存在很多问题,例如它们笨重,易变且不是线程安全的,这意味着无法共享它们,并且每次都需要要将String转换为
Date
,必须创建一个新的
Date
Format
对象。 尽管将Simple
Date
Format
封装到线程局部变量中确实可以缓解,但这还不够。
JDK 8在新的
DateTime
Format
ter类中解决了该问题,该类可用于定义
日期
和
时间
格式
,例如“ yyyy-MM-dd HH:mm:SS”,用于指定
Java
8之前的版本,
格式化
日期
常使用Simple
Date
Format
,但这个类并不是线程安全的,通常要用作局部变量或者使用ThreadLocal包装。或者使用额外的joda
time
依赖来对
日期
进行操作。
但是到了
Java
8,这类烦恼都没有了,全新的
日期
api可以快速实现
日期
格式化
。
1.
日期
格式化
-
日期
类型的字符串转换成其他形式
* 不带时分秒的
日期
字符串转化
我们大家在初学
java
时,经常会做一些练习,这些练习往往会伴随着
日期
的相关数据,下面几种方法是
日期
数据的几种设置
public class demo2 {
public static void main(String[] args) {
//Calendar类是一个单例模式的类,他的构造方法私有且不可被实例化
//get
Inst
ance是类内部的一个静态方法,用来返回当前实例
Cal...
原标题:
Java
中的
日期
时间
格式化
1
Java
日期
时间
格式化
的概念我们在日常的开发过程中常常会碰到关于
日期
时间
的计算与存储问题,比如我们要把一个当前
时间
类型转换成字符串类型,我们会直接使用Util包下的
Date
数据类型(
java
.util.
Date
)来创建
时间
对象,例如:
Date
date
= new
Date
();但如果我们对其对象进行打印会发现
时间
的数据值如下:Fri Jul 24 16:02:...
java
.sql.
Date
日期
格式
为:年月日
java
.sql.
Time
日期
格式
为:时分秒
java
.sql.
Time
stamp
日期
格式
为:年月日时分秒纳秒(毫微秒)
从数据库中取出来的
日期
一般都用getTi...