You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自动识别Unix时间戳与yyyy-MM-dd HH:mm:ss.S格式并提取年月?

我来帮你搞定这个自动识别日期格式并提取年月的需求,用Scala实现的话可以这么做:

整体思路

我们可以通过模式匹配区分两种输入格式:

  1. 如果是数字(或纯数字字符串),判定为Unix时间戳,转成日期后提取年月
  2. 如果是符合yyyy-MM-dd HH:mm:ss.S格式的字符串,直接解析后提取年月
  3. 同时处理异常情况,返回默认值或安全的可选类型(根据你的业务需求选择)
完整实现代码
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)
}
代码说明
  1. 时区处理:如果你的Unix时间戳是基于UTC的,可以把defaultZone改成ZoneId.of("UTC")
  2. 毫秒级时间戳:如果你的时间戳是毫秒级(比如13位数字),把Instant.ofEpochSecond改成Instant.ofEpochMilli即可
  3. 安全可选类型:如果不想用默认值,也可以把返回值改成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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:33:05