Java 学习笔记 - 时间日期常用案列
- 获取当前时间
- 创建一个指定时间
- Date
- Calendar
- LocalDateTime
- ZonedDateTime
- OffsetDateTime
- 转换
- Instant
- ZonedDateTime
- LocalDateTime
- OffsetDateTime
- Date
- 时间戳(毫秒数)
- 格式化
- 以前:DateFormat
- Java8: DateTimeFormatter
- 0. 自带的格式
- 1. 自定义格式
- 2. 自定义格式(支持默认值)
- 3. 其它
- 时间计算
- 加减时间
- 计算间隔
- 时区
- 添加时区信息
- 时区间转换
- ZoneOffset
- ZoneId
- 工具类 hutool
- 参考资料
获取当前时间
以前
Date date = new Date();
Date date = new Date(System.currentTimeMillis());
Java8
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
Instant now = Instant.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();
带时区的日期时间
ZonedDateTime zonedDateTimeDefault = ZonedDateTime.ofInstant(now, ZoneId.systemDefault());// 系统默认时区
ZonedDateTime zonedDateTimeE8 = ZonedDateTime.now().withZoneSameInstant(ZoneId.of("Asia/Shanghai")); // 指定东8区
创建一个指定时间
Date
Date 创建指定日期的方式已经 @Deprecated,仅供参观
Date date = new Date(2022-1900, 0, 5, 12, 30, 59);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
System.out.println(dateFormat.format(date)); // 2022-01-05 12:30:59:000
Calendar
Calendar
还有一大堆常量用于指定时间单位:年、月、日、时、分、秒、毫秒 等。。
Calendar instance = Calendar.getInstance();
// 月从 0 开始
instance.set(2022, 6, 5, 12, 30, 59);
// 补充一下毫秒
instance.set(Calendar.MILLISECOND, 369);
// 取得 日期对象
Date time = instance.getTime();
// 定义格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
// 输出格式化的日期字符串
System.out.println(sdf.format(time)); // 2022-07-05 12:30:59:369
LocalDateTime
LocalDateTime dateTime = LocalDateTime.of(2022, 6, 5, 12, 30, 59, 999999999);
String format = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(format);// 2022-06-05T12:30:59.999999999
ZonedDateTime
ZonedDateTime dateTime = ZonedDateTime.of(2022, 6, 5, 12, 30, 59, 999999999, ZoneId.of("Asia/Shanghai"));
String format = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(format); // 2022-06-05T12:30:59.999999999
ZonedDateTime.of
内部是封装了 LocalDateTime.of
public static ZonedDateTime of(
int year, int month, int dayOfMonth,
int hour, int minute, int second, int nanoOfSecond, ZoneId zone) {
LocalDateTime dt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
return ofLocal(dt, zone, null);
}
OffsetDateTime
OffsetDateTime dateTime = OffsetDateTime.of(2022, 6, 5, 12, 30, 59, 999999999, ZoneOffset.of("+8"));
String format = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(format); // 2022-06-05T12:30:59.999999999
OffsetDateTime.of
内部是封装了 LocalDateTime.of
public static OffsetDateTime of(
int year, int month, int dayOfMonth,
int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset) {
LocalDateTime dt = LocalDateTime.of(year, month, dayOfMonth, hour, minute, second, nanoOfSecond);
return new OffsetDateTime(dt, offset);
}
转换
Instant
直接: LocalDateTime
, ZonedDateTime
, Date
, Timestamp
Instant instant = Instant.now();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai"));
ZonedDateTime zonedDateTime1 = instant.atZone(ZoneId.systemDefault());
ZonedDateTime zonedDateTime2 = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
Date date = Date.from(instant);
Timestamp timestamp = Timestamp.from(instant);
ZonedDateTime
直接:LocalDate
, LocalTime
, LocalDateTime
, Instant
间接:Date
ZonedDateTime zonedDateTime = ZonedDateTime.now();
LocalDate localDate = zonedDateTime.toLocalDate();
LocalTime localTime = zonedDateTime.toLocalTime();
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
Instant instant = zonedDateTime.toInstant();
Date date = Date.from(zonedDateTime.toInstant());
LocalDateTime
直接:LocalDate
, LocalTime
, ZonedDateTime
, OffsetDateTime
, Instant
间接:Date
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
OffsetDateTime dateTime = new OffsetDateTime(localDateTime, ZoneOffset.of("+8"));
Instant instant = localDateTime.toInstant(ZoneOffset.of("+8"));
Date date = Date.from(instant);
OffsetDateTime
直接:LocalDate
, LocalTime
, LocalDateTime
, ZonedDateTime
, Instant
, long
OffsetDateTime offsetDateTime1 = Instant.now().atOffset(ZoneOffset.of("+8"));
OffsetDateTime offsetDateTime2 = OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.of("+8"));
OffsetDateTime offsetDateTime = OffsetDateTime.now();
LocalDate localDate = offsetDateTime.toLocalDate();
LocalTime localTime = offsetDateTime.toLocalTime();
LocalDateTime localDateTime = offsetDateTime.toLocalDateTime();
ZonedDateTime zonedDateTime = offsetDateTime.toZonedDateTime();
Instant instant = offsetDateTime.toInstant();
long timestamp = offsetDateTime.toEpochSecond();
Date
直接:Instant
间接:LocalDate
, LocalTime
, LocalDateTime
Date date = new Date();
Instant instant = Instant.ofEpochMilli(date.getTime());
Instant instant1 = date.toInstant();
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
LocalDate localDate = zonedDateTime.toLocalDate();
LocalTime localTime = zonedDateTime.toLocalTime();
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
LocalDateTime localDateTime1 = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Shanghai"));
LocalTime localTime1 = localDateTime1.toLocalTime();
LocalDate localDate1 = localDateTime1.toLocalDate();
时间戳(毫秒数)
- 直接获取当前时间戳
// 13 位
long timestamp = System.currentTimeMillis();
long timestamp1 = Instant.now().toEpochMilli();
long timestamp2 = new Date().getTime();
long timestamp4 = Clock.systemDefaultZone().millis();
// 10 位
long ts1= LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
long ts2= ZonedDateTime.now().toEpochSecond();
long ts3= OffsetDateTime.now().toEpochSecond();
- LocalDate
->
LocalDateTime->
Instant->
long
LocalDate localDateNow = LocalDate.now();
LocalDateTime now = localDateNow.atStartOfDay();
long time = now.toInstant(ZoneOffset.of("+8")).toEpochMilli();
- LocalDate
->
LocalDateTime->
Timestamp->
long
LocalDate localDate = LocalDate.now();
LocalDateTime now = localDate.atStartOfDay();
long time = Timestamp.valueOf(now).getTime();
- long
->
Instant->
Timestamp->
LocalDateTime
long now = 1654068798634L;
Instant instant = Instant.ofEpochMilli(now);
Timestamp timestamp = Timestamp.from(instant);
LocalDateTime ldt = timestamp.toLocalDateTime();
System.out.println(ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss.SSS")));
格式化
以前:DateFormat
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
System.out.println(dateFormat.format(date)); // 2022-06-02 12:53:35
Calendar cal = Calendar.getInstance();
System.out.println(dateFormat.format(cal.getTime())); // 2022-06-02 12:53:35
Java8: DateTimeFormatter
0. 自带的格式
格式不少,但感觉没几个用的上。 Predefined Formatters
String isoLocalDate = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(isoLocalDate); // 2022-06-02
String isoLocalTime = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME);
System.out.println(isoLocalTime); // 13:09:34.282
String isoLocalDateTime = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(isoLocalDateTime); // 2022-06-02T13:09:34.283
1. 自定义格式
DateTimeFormatter
默认还定义了一些常用的日期格式。满足不了需求我们再自定义。
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println(LocalDateTime.now(ZoneOffset.of("+8")).format(dtf));
2. 自定义格式(支持默认值)
- 只有【月、日】,其它设置默认值。
DateTimeFormatter df= new DateTimeFormatterBuilder()
.appendPattern("MMdd")
.parseDefaulting(ChronoField.YEAR_OF_ERA, 2046)
.parseDefaulting(ChronoField.HOUR_OF_DAY, 23)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 59)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 59)
.parseDefaulting(ChronoField.MILLI_OF_SECOND, 999) // 如果字符串中有毫秒,则会冲突。
.toFormatter();
System.out.println(LocalDateTime.parse("0524", df).toString());
// 2046-05-24T23:59:59.999
- 只有毫秒,没有秒。将秒默认为
0
DateTimeFormatter df = new DateTimeFormatterBuilder()
.appendPattern("yyMMddHHmm[ss].SSS")
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
System.out.println(LocalDateTime.parse("2205241234.567", df).toString());
// 2022-05-24T12:34:00.567
- 综合展示
DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder()
.appendPattern("yyMMdd[[HH][mm][ss][.SSS]]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
System.out.println(LocalDateTime.parse("220524", DATE_FORMAT).toString());
// 2022-05-24T00:00
System.out.println(LocalDateTime.parse("220524.567", DATE_FORMAT).toString());
// 2022-05-24T00:00:00.567
System.out.println(LocalDateTime.parse("22052412.567", DATE_FORMAT).toString());
// 2022-05-24T12:00:00.567
System.out.println(LocalDateTime.parse("2205241234.567", DATE_FORMAT).toString());
// 2022-05-24T12:34:00.567
System.out.println(LocalDateTime.parse("2205241234", DATE_FORMAT).toString());
// 2022-05-24T12:34
3. 其它
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
String format = LocalDate.now().format(dateTimeFormatter);
String format1 = LocalTime.now().format(dateTimeFormatter);
String format2 = LocalDateTime.now().format(dateTimeFormatter);
String format3 = ZonedDateTime.now().format(dateTimeFormatter);
时间计算
加减时间
支持直接加减指定单位,返回结果。
计算间隔
LocalDateTime now = LocalDateTime.now();
LocalDateTime target = now.plusDays(1);
long betweenDays = ChronoUnit.DAYS.between(now, target);
System.out.println(betweenDays); // 1
long betweenHours = ChronoUnit.HOURS.between(now, target);
System.out.println(betweenHours); // 24
时区
添加时区信息
LocalDateTime shanghai = LocalDateTime.now();
System.out.println(shanghai); // 2022-11-16T11:18:37.518
// 给日期时间直接加上时区信息
ZonedDateTime newYork = shanghai.atZone(ZoneId.of("America/New_York"));
System.out.println(newYork); // 2022-11-16T11:18:37.518-05:00[America/New_York]
时区间转换
ZoneOffset
// 指定东八区
ZoneOffset 东八区 = ZoneOffset.of("+8");
// 获取系统默认时区
ZoneOffset 默认时区 = OffsetDateTime.now().getOffset();
System.out.println(默认时区.equals(东八区)); // true
// 默认当前时间(使用系统默认时区)
LocalDateTime 北京 = LocalDateTime.now();
System.out.println(北京);
long l = 北京.toEpochSecond(东八区); // 获取逝去的秒数至 1970-01-01T00:00:00Z
// 转西五区时间
LocalDateTime 纽约 = LocalDateTime.ofEpochSecond(l, 0, ZoneOffset.of("-5"));
System.out.println(纽约);
ZoneId
// 获取时间,按系统默认时区(可能服务器不在国内)
LocalDateTime localDateTime = LocalDateTime.now();
// 将 localDateTime 转带时区格式:东八区上海时间
ZoneId shanghaiZoneId = ZoneId.of("Asia/Shanghai");
ZonedDateTime 上海 = ZonedDateTime.of(localDateTime, shanghaiZoneId);
// 将 shanghai 转为西五区纽约时间
ZoneId newYorkZoneId = ZoneId.of("America/New_York");
ZonedDateTime 纽约 = 上海.withZoneSameInstant(newYorkZoneId);
System.out.println("默认时区: " + localDateTime);
System.out.println("东八区(上海): " + 上海.toLocalDateTime());
System.out.println("西五区(纽约): " + 纽约.toLocalDateTime());
// 日期时间,无时区信息
String dt = "2022-11-16T12:31:45";
LocalDateTime ldt = LocalDateTime.parse(dt, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
System.out.println(ldt);
// 指定为上海时间
ZonedDateTime 上海 = ldt.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(上海);
System.out.println(上海.toLocalDateTime());
// 转换为纽约时间
ZonedDateTime 纽约 = 上海.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(纽约);
System.out.println(纽约.toLocalDateTime());
工具类 hutool
DateTime now = DateUtil.date();
System.out.println(now); // 当地时间
DateTime dateTime = DateUtil.convertTimeZone(now, ZoneId.of("America/New_York"));
System.out.println(dateTime); // 纽约时间