如何自动识别Unix时间戳与yyyy-MM-dd HH:mm:ss.S格式并提取年月?
我来帮你搞定这个自动识别日期格式并提取年月的需求,用Scala实现的话可以这么做:
整体思路
我们可以通过模式匹配区分两种输入格式:
- 如果是数字(或纯数字字符串),判定为Unix时间戳,转成日期后提取年月
- 如果是符合
yyyy-MM-dd HH:mm:ss.S格式的字符串,直接解析后提取年月 - 同时处理异常情况,返回默认值或安全的可选类型(根据你的业务需求选择)
完整实现代码
import java.time.{Instant, LocalDateTime, ZoneId} import java.time.format.DateTimeFormatter object DateUtils { // 定义目标日期格式 private val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S") // 时区可根据业务调整,比如UTC或系统默认时区 private val defaultZone = ZoneId.systemDefault() // 提取年份 def getYear(datetimeInput: Any): Int = { getYearAndMonth(datetimeInput)._1 } // 提取月份 def getMonth(datetimeInput: Any): Int = { getYearAndMonth(datetimeInput)._2 } // 核心逻辑:统一处理两种格式,返回(年, 月) private def getYearAndMonth(datetimeInput: Any): (Int, Int) = { datetimeInput match { // 处理Long类型的Unix时间戳(秒级) case timestamp: Long => val localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), defaultZone) (localDateTime.getYear, localDateTime.getMonthValue) // 处理字符串形式的Unix时间戳 case timestampStr: String if timestampStr.forall(_.isDigit) => try { val timestamp = timestampStr.toLong val localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), defaultZone) (localDateTime.getYear, localDateTime.getMonthValue) } catch { case _: NumberFormatException => handleInvalidInput() } // 处理yyyy-MM-dd HH:mm:ss.S格式的字符串 case dateStr: String => try { val localDateTime = LocalDateTime.parse(dateStr, dateFormatter) (localDateTime.getYear, localDateTime.getMonthValue) } catch { case _: Exception => handleInvalidInput() } // 其他无效输入 case _ => handleInvalidInput() } } // 无效输入的默认返回值,可根据业务调整 private def handleInvalidInput(): (Int, Int) = (2017, 1) }
代码说明
- 时区处理:如果你的Unix时间戳是基于UTC的,可以把
defaultZone改成ZoneId.of("UTC") - 毫秒级时间戳:如果你的时间戳是毫秒级(比如13位数字),把
Instant.ofEpochSecond改成Instant.ofEpochMilli即可 - 安全可选类型:如果不想用默认值,也可以把返回值改成
Option[(Int, Int)],避免无效输入带来的隐性错误,示例如下:private def getYearAndMonth(datetimeInput: Any): Option[(Int, Int)] = { datetimeInput match { case timestamp: Long => val localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), defaultZone) Some((localDateTime.getYear, localDateTime.getMonthValue)) case timestampStr: String if timestampStr.forall(_.isDigit) => try { val timestamp = timestampStr.toLong val localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), defaultZone) Some((localDateTime.getYear, localDateTime.getMonthValue)) } catch { case _: NumberFormatException => None } case dateStr: String => try { val localDateTime = LocalDateTime.parse(dateStr, dateFormatter) Some((localDateTime.getYear, localDateTime.getMonthValue)) } catch { case _: Exception => None } case _ => None } } // 对应提取函数改成返回Option def getYear(datetimeInput: Any): Option[Int] = getYearAndMonth(datetimeInput).map(_._1)
使用示例
// 测试Unix时间戳(秒级) println(DateUtils.getYear(1520877600)) // 输出2018 println(DateUtils.getMonth(1520877600)) // 输出4 // 测试yyyy-MM-dd HH:mm:ss.S格式 println(DateUtils.getYear("2018-04-23 11:12:00.0")) // 输出2018 println(DateUtils.getMonth("2018-04-23 11:12:00.0")) // 输出4 // 测试无效输入 println(DateUtils.getYear("invalid-date")) // 输出默认值2017 println(DateUtils.getMonth("invalid-date")) // 输出默认值1
内容的提问来源于stack exchange,提问作者ScalaBoy
相关产品推荐
相关产品推荐

