epoch time
表示一个特定时间:1970-01-01 00:00:00 UTC
,从这一时刻开始计算所经过的秒数称为UNIX时间戳(Unix timestamp)。在Java中可使用System.currentTimeMillis()
获取时间戳。
老版本时间API位于java.util
包中。
时间格式化
Date date = new Date();
var sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(date));
更多格式化格式见:JDK文档: Class SimpleDateFormat
新的时间API位于java.time
包中,主要API包含:
类别 | API |
---|---|
本地日期时间 | LocalDateTime ,LocalDate ,LocalTime |
时刻 | Instant |
时间间隔 | Duration |
包含时区的时间 | ZonedDateTime |
时区 | ZoneId ,ZoneOffset |
获取某一时刻时间戳
// 秒
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
表示两个日期之间的天数
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 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规定的日期和时间分隔符是T
中文
English