Java基础:日期与时间
程序员文章站
2022-05-18 17:21:15
...
文章目录
日期与时间
- 日期
如2020-06-17 - 时间(可包含日期)
如 12:10:10或2020-06-17 12:10:10
新纪元时间(Epoch Time)
epoch time
表示一个特定时间:1970-01-01 00:00:00 UTC
,从这一时刻开始计算所经过的秒数称为UNIX时间戳(Unix timestamp)。在Java中可使用System.currentTimeMillis()
获取时间戳。
Java时间API
老版本API
老版本时间API位于java.util
包中。
- Date 表示一个日期和时间对象。可以获取当前时间及对应的年月日时分秒等。
- Calendar 可获取和设置年月日时分秒,比Date多了时间运算。
- TimeZone 提供时区转换功能
更多信息参考:廖雪峰-Date和Calendar
时间格式化
Date date = new Date();
var sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(date));
更多格式化格式见:JDK文档: Class SimpleDateFormat
Java8中的新版本API
新的时间API位于java.time
包中,主要API包含:
类别 | API |
---|---|
本地日期时间 |
LocalDateTime ,LocalDate ,LocalTime
|
时刻 | Instant |
时间间隔 | Duration |
包含时区的时间 | ZonedDateTime |
时区 |
ZoneId ,ZoneOffset
|
时刻(Instant)
获取某一时刻时间戳
// 秒
instant.getEpochSecond()
// 毫秒
instant.toEpochMilli()
将时间戳转为特定时区时间
Instant ins = Instant.ofEpochSecond(1592385860);
System.out.println(ins); // UTC 时间
ZonedDateTime zonedDateTime = ins.atZone(ZoneId.systemDefault());
ZonedDateTime zonedDateTime2 = ins.atZone(ZoneId.of("America/New_York"));
创建一个时间对象
LocalDateTime ldt = LocalDateTime.now();
LocalDateTime ldt2 = LocalDateTime.of(2020, 6, 17, 12, 12, 12);
上述两个时间对象都将输出标准的ISO 8601的格式
Duration和Period
Duration
表示两个时刻之间的时间间隔,Period
表示两个日期之间的天数
LocalDateTime ldt = LocalDateTime.now();
LocalDateTime ldt2 = LocalDateTime.of(2020, 6, 17, 12, 12, 12);
Duration duration = Duration.between(ldt2, ldt);
System.out.println(duration);
Period period = Period.between(LocalDate.now().minusDays(1), LocalDate.now());
System.out.println(period);
输出内容类似:PT4H34M1.412S
,P1D
。
输出格式:以P...T...
的形式表示,P...T
之间表示日期间隔,T
后面表示时间间隔。
所以上述输出分别表示时间间隔为4小时34分钟1.412秒以及日期间隔为1天。
新版时间格式化(DateTimeFormatter)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dtf.format(LocalDateTime.now()));
新版API还提供了更强大的日期计算方法,参见廖雪峰-LocalDateTime
带时区的时间
ZonedDateTime beijingTime = ZonedDateTime.now(); // 默认时区
ZonedDateTime newYorkTime = ZonedDateTime.now(ZoneId.of("America/New_York")); // 指定时区
// or create by asZone
ZonedDateTime beijingTime2 = ldt.atZone(ZoneId.systemDefault());
ZonedDateTime newYorkTime2 = ldt.atZone(ZoneId.of("America/New_York"));
输出如下
2020-06-17T16:55:47.874+08:00[Asia/Shanghai]
2020-06-17T04:55:47.876-04:00[America/New_York]
也可使用withZoneSameInstant()
将时区转换为纽约时间:
ZonedDateTime newYorkTime3 = beijingTime.withZoneSameInstant(ZoneId.of("America/New_York"));
在数据库中存储日期和时间
我们可以在数据库中保存unix时间戳,然后根据用户选择的时区显示本地时间。
public static void main(String[] args) {
long unixTimestamp = 1592386268000L;
String bj = timestampToString(unixTimestamp, Locale.CHINA, "Asia/Shanghai");
String ny = timestampToString(unixTimestamp, Locale.US, "America/New_York");
System.out.println(bj);
System.out.println(ny);
}
static String timestampToString(long epochMilli, Locale locale, String zoneId) {
Instant ins = Instant.ofEpochMilli(epochMilli);
// DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return dtf.withLocale(locale).format(ZonedDateTime.ofInstant(ins, ZoneId.of(zoneId)));
}
输出如下
2020-06-17 17:31:08
2020-06-17 05:31:08
ISO 8601
ISO 8601规定的日期和时间分隔符是T
- 日期:yyyy-MM-dd
- 时间:HH:mm:ss
- 带毫秒的时间:HH:mm:ss.SSS
- 日期和时间:yyyy-MM-dd’T’HH:mm:ss
- 带毫秒的日期和时间:yyyy-MM-dd’T’HH:mm:ss.SSS
API文档
上一篇: Java时间日期类