一.引言
开发中遇到需要判断是否周末即 is_weekend 的逻辑需求,这里使用 LocalDateTime 解决问题并记录下该类的其他用法,方便后续查阅。
import java.time.format.DateTimeFormatter
二.LocalDateTime 获取与格式化
首先介绍如何生成 LocalDateTime 类。
1.获取当前时间 LocalDateTime
该方法开发环境中比较常见,一般是 Object 内加载一次获取当前相关的时间语义状态。
// 获取当前时间
val localDateTime = LocalDateTime.now()
2023-04-11T14:09:17.712
2.根据时间戳获取 LocalDateTime
多见于数据分析,将日志中的时间戳转化并统计相关指标。实际分析时将时间戳换成自己的时间戳即可。
val currentTimeStamp = System.currentTimeMillis() / 1000
val localDateTimeByTs = LocalDateTime.ofEpochSecond(currentTimeStamp, 0, ZoneOffset.ofHours(8))
2023-04-11T14:12:25
3.指定时间获取 LocalDateTime
LocalDateTime 提供方法可以直接指定年月日、小时分钟秒...
val localDateTimeByAssign = LocalDateTime.of(2023, 3, 5, 10, 20, 30)
下面指定 2023 年 3 月 5 日 10 点 20 分 30 秒:
2023-03-05T10:20:30
4.根据指定样式数据获取 LocalDateTime
val time = "2023-04-19 13:00:00"
val localDateTimeFromStr = LocalDateTime.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
println(localDateTimeFromStr)
常用于日志解析不同格式的时间数据使用。
2023-04-19T13:00
5.LocalDateTime 格式化
格式化多见于日志输出,因为 '2023-03-05T10:20:30' 这样的字符串并不适合我们任务解析与标识,大家可以自定义不同的格式化在 ofPattern 中。
val localDateTime = LocalDateTime.now()
val dateTimeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmm")
val dataTimeFormatV2 = DateTimeFormatter.ofPattern("yyyy-MM-dd")
println(dateTimeFormat.format(localDateTime))
println(dataTimeFormatV2.format(localDateTime))
202304111416
2023-04-11
三.LocalDateTime 读取时间细节
import java.time.temporal.{ChronoField, ChronoUnit}
// 获取当前时间
val localDateTime = LocalDateTime.now()
1.获取年-Year
val year = localDateTime.getYear
val year2 = localDateTime.get(ChronoField.YEAR)
2.获取月-Month
val month = localDateTime.getMonth
val month2 = localDateTime.get(ChronoField.MONTH_OF_YEAR)
这里推荐大家使用第二种,第一种 getMonth 返回的是 Month 类,打印结果为: "APRIL" 而不是 Int 的月份。
3.获取日-Day
val dayOfMonth = localDateTime.get(ChronoField.DAY_OF_MONTH)
val dayOfWeek = localDateTime.get(ChronoField.DAY_OF_WEEK)
DAY_OF_MONTH 是这个月的第几天即我们常说的今天几号
DAY_OF_WEEK 是当前周的第几天及我们常说的今天周几,其范围为 1-7,博主的需求其实用到了这一行就够了,is_weekend 判断 dayOfWeek 是不是 6-7 即可。
4.获取时-Hour
val hour = localDateTime.get(ChronoField.HOUR_OF_DAY)
5.获取分-Minute
val minute = localDateTime.get(ChronoField.MINUTE_OF_HOUR)
6.获取秒-Second
val second = localDateTime.get(ChronoField.SECOND_OF_MINUTE)
7.获取时间戳-TimeStamp
val localDateTime = LocalDateTime.now()
println(localDateTime.toEpochSecond(ZoneOffset.ofHours(8)))
1681195918
如果需要毫秒形式需要补 000
8.TimeUtil 工具类
def getTimeDetail(isNow: Boolean): mutable.HashMap[String, Int] = {
val timeMap = mutable.HashMap[String, Int]()
// 获取当前时间
val localDateTime = LocalDateTime.now()
val year = localDateTime.getYear
val year2 = localDateTime.get(ChronoField.YEAR)
val month = localDateTime.getMonth
val month2 = localDateTime.get(ChronoField.MONTH_OF_YEAR)
val dayOfMonth = localDateTime.get(ChronoField.DAY_OF_MONTH)
val dayOfWeek = localDateTime.get(ChronoField.DAY_OF_WEEK)
val isWeekend = if (dayOfWeek.equals(6) || dayOfWeek.equals(7)) 1 else 0
val hour = localDateTime.get(ChronoField.HOUR_OF_DAY)
val minute = localDateTime.get(ChronoField.MINUTE_OF_HOUR)
val second = localDateTime.get(ChronoField.SECOND_OF_MINUTE)
timeMap.put("year", year)
timeMap.put("month", month2)
timeMap.put("day", dayOfMonth)
timeMap.put("week", dayOfWeek)
timeMap.put("hour", hour)
timeMap.put("minute", minute)
timeMap.put("second", second)
timeMap.put("isWeekend", isWeekend)
println(s"年 $year $year2 月: $month 月: $month2 日期: $dayOfMonth 周: $dayOfWeek")
timeMap
}
直接调用该方法获取全部所需时间信息:
Map(second -> 6, hour -> 14, week -> 2, year -> 2023, minute -> 53, month -> 4, isWeekend -> 0, day -> 11)
四.LocalDateTime 修改
除了获取指定时间 LocaDateTime 外,有时候还需要对时间做适当修改。
1.加一年
val plusYearV1 = localDateTime.plusYears(1)
val plusYearV2 = localDateTime.plus(1, ChronoUnit.YEARS)
2024-04-11T14:59:40.311
2.加一月
// 加一月
val plusMonthV1 = localDateTime.plusMonths(1)
val plusMonthV2 = localDateTime.minus(1, ChronoUnit.MONTHS)
3.加一天
val plusDayV1 = localDateTime.plusDays(1)
val plusDayV2 = localDateTime.plus(1, ChronoUnit.DAYS)
4.通过 with
修改
4.1 指定年份
val withYearV1 = localDateTime.withYear(2021)
val withYearV2 = localDateTime.`with`(ChronoField.YEAR, 2020)
4.2 firstDayOfYear 今年第一天
println(localDateTime.`with`(firstDayOfYear))
2023-01-01T15:11:32.817
4.3 dayOfWeekInMonth 本月的第几个周几
返回本月的第一个周五:
println(localDateTime.`with`(dayOfWeekInMonth(1, DayOfWeek.FRIDAY)))
2023-04-07T15:16:02.061
返回本月的最后一个周一:
println(localDateTime.`with`(dayOfWeekInMonth(-1, DayOfWeek.MONDAY)))
2023-04-24T15:18:31.713
4.4 firstDayOfMonth 当月第一天
println(localDateTime.`with`(firstDayOfMonth()))
2023-04-01T15:20:29.200
4.5 firstDayOfNextMonth 下月第一天
println(localDateTime.`with`(firstDayOfNextMonth()))
2023-05-01T15:20:51.163
4.6 firstDayOfNextYear 明年第一天
println(localDateTime.`with`(firstDayOfNextYear()))
2024-01-01T15:21:31.954
4.7 firstInMonth 本月第一个周几
本月第一个周五
println(localDateTime.`with`(firstInMonth(DayOfWeek.FRIDAY)))
2023-04-07T15:22:26.534
4.8 lastDayOfYear 本年最后一天
println(localDateTime.`with`(lastDayOfYear))
2023-12-31T15:24:25.833
4.9 lastInMonth 本月最后一个周几
本月最后一个周一
println(localDateTime.`with`(lastInMonth(DayOfWeek.MONDAY)))
2023-04-24T15:25:26.660
4.10 next 下一个周几
下一个周一
println(localDateTime.`with`(next(DayOfWeek.MONDAY)))
2023-04-17T15:26:42.145
4.11 previous 上一个周几
上一个周五
println(localDateTime.`with`(previous(DayOfWeek.FRIDAY)))
2023-04-07T15:27:26.763
4.12 nextOrSame 下一个周几且是否当日
下一个周五,不是当日所以正常返回
println(localDateTime.`with`(nextOrSame(DayOfWeek.FRIDAY)))
2023-04-14T15:29:15.985
下一个周二,是当日所以返回当前日期即命中了 Same
println(localDateTime.`with`(nextOrSame(DayOfWeek.TUESDAY)))
2023-04-11T15:30:20.639
这里 nextOrSame 和 next 可以看作是大于等于和大于的区别。
4.13 previousOrSame 上一个周几且是否当日
上一个周五
println(localDateTime.`with`(previousOrSame(DayOfWeek.FRIDAY)))
2023-04-07T15:31:55.037
上一个周二
println(localDateTime.`with`(previousOrSame(DayOfWeek.TUESDAY)))
2023-04-11T15:31:30.415
和上面的 nextOrSame 同理,这里 previouesOrSame 和 previous 可以看作是小于等于和小于的区别。
五.LocalDateTime 与时间间隔 Duration
Duration 与 LocalDateTime 集合可以计算两个时间类之间的差距。
val from = LocalDateTime.of(2022, 1, 1, 0, 0, 0)
val to = LocalDateTime.of(2023, 1, 1, 0, 0, 0)
val duration = Duration.between(from, to)
1.差几天
val days = duration.toDays
2.差几小时
val hours = duration.toHours
3.差几分钟
val minutes = duration.toMinutes
4.差几秒
val seconds = duration.getSeconds
5.差几毫秒
val milliSeconds = duration.toMillis
6.差几纳秒
val nanoSeconds = duration.toNanos
7.DurationUtil 工具类
def timeDuration(): Unit = {
val from = LocalDateTime.of(2022, 1, 1, 0, 0, 0)
val to = LocalDateTime.of(2023, 1, 1, 0, 0, 0)
val duration = Duration.between(from, to)
// 间隔内的 总天数 小时数 分钟数 秒数 毫秒数 纳秒数
val days = duration.toDays
val hours = duration.toHours
val minutes = duration.toMinutes
val seconds = duration.getSeconds
val milliSeconds = duration.toMillis
val nanoSeconds = duration.toNanos
println(days, hours, minutes, seconds, milliSeconds, nanoSeconds)
}
直接调用方法获取全部 Duration:
(365,8760,525600,31536000,31536000000,31536000000000000)
六.总结
**• **Duration 可以便捷得到两个 LocalDateTime 之间的间隔信息
**• **LocalDateTime 可以获取年、月、日,下一个年、月、日等
**• **LocalTime 相比 LocalDateTime 无法获取更细粒度的秒信息
**• **TemporalAdjusters 内含多个时间函数静态方法,可以按需调用
**• **ChronoField 包含多类型时间字段,除上面介绍外,还有 AM、PM 类型时间获取
**• **ChronoUnit 主要为时间单位,例如 YEARS、MONTHS、DAYS 等等
**• **与 SimpleDataFormat 相比,DateTimeFormatter 是线程安全的
版权归原作者 BIT_666 所有, 如有侵权,请联系我们删除。