java处理时间(使用DateTimeFormatter和LocalDateTime)

前言

java在处理时间的时候有很多方式,早期的SimpleDateFormatDateCalendar,以及后来的DateTimeFormatterLocalDateTime等等,但是由于SimpleDateFormat存在线程不安全的问题,因此推荐使用DateTimeFormatterLocalDateTime来处理时间,在这里对一些常用的方法做一个整理。

时间样式标识

标识含义
Z时区,如:+0800
yyyy我们一般所指的年份
YYYYWeek year,当天所在的周属于的年份
MM
dd
HH24小时制的小时,如果只有H则不补0
hh12小时制的小时
mm分钟,如果只有m则不补0
ss秒,如果只有s则不补0

ZoneId时区

// 系统当前时区
ZoneId.systemDefault();
// 指定时区
ZoneId.of("Asia/Shanghai");
ZoneId.of("Europe/Zurich");
// 获取所有时区
ZoneId.getAvailableZoneIds();
// 获取指定时区
ZoneId.ofOffset("UTC", ZoneOffset.ofHours(8));
ZoneId.ofOffset("GMT", ZoneOffset.ofHours(8));
ZoneId.ofOffset("UTC", ZoneOffset.of("+0830"));

Instant时间点

// 获取某个时刻
Instant.now();
Instant.ofEpochSecond(1646739326);
Instant.ofEpochMilli(1646739326986L);
// 获取时间戳
// 秒级
long epochSecond = Instant.now().getEpochSecond();
// 毫秒级
long epochMilli = Instant.now().toEpochMilli();
long currentTimeMillis = System.currentTimeMillis();
// 转换为LocalDateTime
Instant.now().atOffset(ZoneOffset.ofHours(8)).toLocalDateTime();
// 转换为Date
Date.from(Instant.now());
// 从Date获取
Date date = new Date();
date.toInstant();

未找到Instant.now().toEpochMilli()System.currentTimeMillis()之间的明显差异,因此根据个人习惯来选择就好。

LocalDateTime

// 当前时间
LocalDateTime.now();
LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
// 声明一个时间
LocalDateTime.of(2022, 2, 28, 23, 50);
LocalDateTime.ofInstant(Instant.ofEpochSecond(1646739326), ZoneId.systemDefault());
LocalDateTime.ofEpochSecond(1646739326, 0, ZoneOffset.ofHours(8));
// 根据字符串获取时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime.parse("2022-05-23 14:35:56", formatter);
// 根据时间获取指定格式字符串
LocalDateTime tmpDateTime = LocalDateTime.now();
String timeStr = tmpDateTime.format(formatter);
// 获取年月日等
tmpDateTime.getYear();
tmpDateTime.getMonthValue();
tmpDateTime.getDayOfMonth();
tmpDateTime.getDayOfWeek();
tmpDateTime.getHour();
tmpDateTime.getMinute();
// 获取时间戳
        tmpDateTime.toEpochSecond(ZoneOffset.ofHours(8));
// 转换为LocalDate、LocalTime、Instant
LocalDate tmpDate = tmpDateTime.toLocalDate();
LocalTime tmpTime = tmpDateTime.toLocalTime();
Instant tmpInstant = tmpDateTime.toInstant(ZoneOffset.ofHours(8));
// 比较日期
tmpDateTime.isAfter(LocalDateTime.now());
tmpDateTime.isBefore(LocalDateTime.now());
tmpDateTime.isEqual(LocalDateTime.now());
// 获取两个日期间的时间跨度
long dayGap = ChronoUnit.DAYS.between(LocalDateTime.now(), tmpDateTime);
long hourGap = ChronoUnit.HOURS.between(LocalDateTime.now(), tmpDateTime);
// 根据日期生成新的LocalDateTime
tmpDateTime.withYear(1999);
tmpDateTime.withDayOfMonth(30);
tmpDateTime.withHour(14);
tmpDateTime.withMinute(50);
// 减
tmpDateTime.minusDays(100);
tmpDateTime.minusHours(4);
// 加
tmpDateTime.plusDays(180);
tmpDateTime.plusHours(5);
// 截取到某个粒度
tmpDateTime.truncatedTo(ChronoUnit.HOURS);
tmpDateTime.truncatedTo(ChronoUnit.DAYS);
// 如果想获取一周的第一个时刻,下面这个用法是错误的
// tmpDateTime.truncatedTo(ChronoUnit.WEEKS);
// 正确的做法(下面的几种方法都行):
tmpDateTime.minusDays(tmpDateTime.getDayOfWeek().getValue() - DayOfWeek.MONDAY.getValue()).truncatedTo(ChronoUnit.DAYS);
TemporalAdjuster firstOfWeek = TemporalAdjusters.ofDateAdjuster(localDate -> localDate.minusDays(localDate.getDayOfWeek().getValue() - DayOfWeek.MONDAY.getValue()));
tmpDateTime.with(firstOfWeek).truncatedTo(ChronoUnit.DAYS);
tmpDateTime.toLocalDate().with(firstOfWeek).atStartOfDay();
// 注意上面使用的with(TemporalAdjuster)方法只会调整日期,不会调整时间
// 2022-03-08 22:08:56 => 2022-03-01 22:08:56
tmpDateTime.with(TemporalAdjusters.firstDayOfMonth());

LocalDate和LocalTime

LocalDate和LocalTime的使用和上面的LocalDateTime大体相同,这里列出一些前面没有出现的方法

// 获取那一天的00:00
tmpDate.atStartOfDay();
LocalDateTime.of(tmpDate, LocalTime.MIN);
// 获取那一天的23:59
LocalDateTime.of(tmpDate, LocalTime.MAX);
// 转换为LocalDateTime
tmpDate.atTime(tmpTime);
tmpDate.atTime(10, 59);
// 是否是闰年
tmpDate.isLeapYear();
// 获取当月/当年有多长
tmpDate.lengthOfMonth();
tmpDate.lengthOfYear();


// 转换为LocalDateTime
tmpTime.atDate(tmpDate);

注意:

LocalDateTime tmpDateTime = LocalDateTime.parse("20220316", DateTimeFormatter.ofPattern("yyyyMMdd"));

如果只是转换日期格式,那么不要使用LocalDateTime,而是使用LocalDate,上述代码会抛出异常

Text '20220316' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {},ISO resolved to 2022-03-16 of type java.time.format.Parsed
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值