0


Scala - 时间工具类 LocalDateTime 常用方法整理

一.引言

开发中遇到需要判断是否周末即 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 是线程安全的

标签: scala LocalDateTime

本文转载自: https://blog.csdn.net/BIT_666/article/details/130082525
版权归原作者 BIT_666 所有, 如有侵权,请联系我们删除。

“Scala - 时间工具类 LocalDateTime 常用方法整理”的评论:

还没有评论