Scala中如何将Timestamp类型值转换为Double类型值
问题原因
核心问题分为两点:
- 你定义的
RawData样例类中t字段声明为Double类型,但原始数据源的t是Timestamp类型,直接映射会触发类型不匹配报错 - 代码中
cal.setTimeInMillis(row.t.)语法不完整,且全局Calendar实例不是线程安全的,在分布式map运算中会出现数据错乱
解决步骤
步骤1:明确转换逻辑
Timestamp类型自带getTime()方法,可返回对应毫秒级时间戳的Long值,直接强制转为Double即可满足需求。如果需要秒级时间戳,除以1000再转换即可。
步骤2:修正代码实现
不要在算子外定义全局Calendar实例,改为在map算子内初始化,避免线程安全问题,修正后代码如下:
// 先定义中间样例类承接原始数据的Timestamp类型字段 case class TempRawData(sessionId: String, t: Timestamp, channel: Int, signalName: String, physicalValue: Double, messageId: Long, vehicleId: String) def raw(): Unit = { import rawData.sqlContext.implicits._ val datDMY = rawData .as[TempRawData] // 先转成中间类型的DataSet,避免类型映射错误 .map(row => { val cal = Calendar.getInstance() // Timestamp转Double的核心逻辑,毫秒级时间戳 val tDouble = row.t.getTime.toDouble cal.setTimeInMillis(row.t.getTime) RawDataExtended( row.sessionId, tDouble, // 传入转换完成的Double类型时间戳 row.channel, row.signalName, row.physicalValue, row.messageId, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DAY_OF_MONTH) ) }) }
补充场景
如果需要秒级精度的Double类型时间戳,转换逻辑修改为:
val tDouble = (row.t.getTime / 1000.0).toDouble
内容的提问来源于stack exchange,提问作者esercì ziator
相关产品推荐
相关产品推荐

