Spark SQL不支持MySQL的FROM_UNIXTIME函数,仅提供小写的from_unixtime,返回STRING类型且仅接受秒级时间戳;推荐直接使用to_timestamp(秒级整数)获取TIMESTAMP类型,毫秒需先cast为long后除以1000,并注意会话时区影响。

FROM_UNIXTIME在Spark SQL里根本不存在
Spark SQL不支持FROM_UNIXTIME这个函数——它是MySQL的语法,直接照搬会报错:org.apache.spark.sql.catalyst.analysis.NoSuchFunctionException: No function found for 'from_unixtime'。别浪费时间查文档确认兼容性了,它就是没实现。
用from_unixtime(小写)替代,但注意参数和返回类型
Spark SQL提供的是from_unixtime(全小写),且行为和MySQL有关键差异:它默认返回STRING类型,不是TIMESTAMP;而且只接受秒级时间戳(不能自动识别毫秒)。常见踩坑点:
- 传入毫秒级时间戳(如
1717023600000)会导致结果错乱成公元年份(因为被当成了秒) - 不指定格式字符串时,返回的是
yyyy-MM-dd HH:mm:ss格式的字符串,无法直接参与时间运算 - 想得到
TIMESTAMP类型,必须套一层to_timestamp
正确用法示例:
SELECT to_timestamp(from_unixtime(1717023600)) AS ts;
或者一步到位(推荐):
SELECT to_timestamp(1717023600) AS ts;
to_timestamp直接支持秒级整数输入,且返回TIMESTAMP类型,更简洁、类型安全。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
毫秒时间戳要先除以1000再转
如果原始字段是毫秒(比如Kafka或日志里常见的1717023600123),必须先做整除处理:
SELECT to_timestamp(cast(col('ts_ms') / 1000 as long)) AS ts FROM tbl;
注意不能用floor(ts_ms / 1000)——Spark中对double除法结果取整可能引入浮点误差;强制cast(... as long)更可靠。另外,如果字段是字符串类型,得先cast(... as bigint)再除。
时区问题不能靠FROM_UNIXTIME解决
MySQL的FROM_UNIXTIME可传第二个参数指定时区(如'GMT+8'),Spark的from_unixtime和to_timestamp都不支持。它们始终按**会话时区**(spark.sql.session.timeZone)解析——默认是UTC。如果数据是东八区时间戳但想转成本地时间显示,得手动加偏移:
SELECT from_unixtime(1717023600) AS utc_str, from_unixtime(1717023600 + 8*3600) AS cst_str;
或者统一设置会话时区:SET spark.sql.session.timeZone = 'Asia/Shanghai';,之后所有to_timestamp都按该时区解释输入值。这点容易被忽略,导致时间差8小时还查不出原因。










