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

Scala中RDD日期验证、时间戳转换及无效行过滤方案

处理RDD日期字符串转时间戳并过滤无效行

需求背景

现有RDD[(String, String)]类型数据,每个字符串元素为yyyy-MM-dd HH:mm:ss格式的日期时间戳。原通过SimpleDateFormat实现的epochTime函数仅做转换,未处理空值、空字符串或格式错误的情况,需要修改逻辑,过滤掉包含无效值的行,仅保留并转换有效行的时间戳。

原函数代码:

def epochTime (stringOfTime: String): Long = dateFormats.parse(stringOfTime).getTime

解决方案

1. 重构时间转换函数(支持异常与空值处理)

将函数返回值改为Option[Long],以此标记转换是否成功,同时处理空值、空串和格式错误:

import java.text.SimpleDateFormat
import java.util.Date

// SimpleDateFormat非线程安全,Spark分布式环境下用ThreadLocal隔离
private val dateFormat = new ThreadLocal[SimpleDateFormat] {
  override def initialValue(): SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
}

def epochTime(stringOfTime: String): Option[Long] = {
  Option(stringOfTime) // 处理null值
    .filter(_.trim.nonEmpty) // 过滤空串或全空格字符串
    .flatMap { timeStr =>
      try {
        // 解析成功则返回时间戳
        Some(dateFormat.get.parse(timeStr).getTime)
      } catch {
        // 捕获格式错误等异常,返回None标记无效
        case _: Exception => None
      }
    }
}

2. 处理RDD过滤有效行

通过flatMap遍历RDD,仅保留两个字段都能成功转换的行:

val originalRDD: RDD[(String, String)] = ... // 你的原始RDD实例

val validEpochRDD: RDD[(Long, Long)] = originalRDD
  .flatMap { case (time1, time2) =>
    // 仅当两个时间都转换成功时,返回元组
    for {
      epoch1 <- epochTime(time1)
      epoch2 <- epochTime(time2)
    } yield (epoch1, epoch2)
  }

3. 推荐:使用Java 8+时间API替代SimpleDateFormat

SimpleDateFormat已过时且线程不安全,Spark 2.0+环境下推荐用java.time包的API,无需ThreadLocal,更可靠:

import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException

// DateTimeFormatter是线程安全的,可全局复用
private val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")

def epochTime(stringOfTime: String): Option[Long] = {
  Option(stringOfTime)
    .filter(_.trim.nonEmpty)
    .flatMap { timeStr =>
      try {
        // 解析为LocalDateTime,转成UTC毫秒级时间戳(与原getTime结果一致)
        Some(LocalDateTime.parse(timeStr, formatter).toEpochSecond(java.time.ZoneOffset.UTC) * 1000)
      } catch {
        case _: DateTimeParseException => None
      }
    }
}

输入输出示例

输入

(2020-10-10 05:17:12,2015-04-10 09:18:20)
(2020-10-12 06:15:58,2015-04-10 09:17:42)
(2020-10-11 07:16:40,2015-04-10 09:17:49)

输出

(1602303432,1428653900)
(1602479758,1428653862)
(1602397000,1428653869)

内容的提问来源于stack exchange,提问作者ADK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:54:24