news 2026/10/22 1:13:26

spark日期时间处理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
spark日期时间处理

注意事项:

  • 函数性能,选择高性能方式或函数;
  • 客户端显示问题,客户端时区影响时间类型数据的展示;

一、相关参考

官网参考链接:Spark SQL, Built-in Functions

时间日期格式符号: https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html

标准日期格式符号: yyyy-MM-dd HH:mm:ss、yyyy-M-ddTHH:mm:ss

二、时区影响

  1. 时间相关的函数,大多会受时区的影响;
  2. 不特殊指定时区,会默认使用服务器的时区;
  3. spark中处理时间时,最好指定session级时区,并且最好指定为0时区,便于进行时区偏移;
set spark.sql.session.timeZone=GMT+8; -- 指定到东八区 set spark.sql.session.timeZone=UTC; -- 指定到零时区


三、时间函数

1. 受时区影响


1. current_date获取当前日期

select current_date() as cur_date;

2018-04-09

2. current_timestamp/now()获取当前时间

select current_timestamp() as cur_time;

2018-04-09 15:20:49.247

3. unix_timestamp/to_unix_timestamp从当前时区转换到unix时间

这两个函数从官方文档看是相同的;

从指定格式的时间转换到Unix时间

unix_timestamp([timeExp[, fmt]])

Returns the UNIX timestamp of current or specified time.

Arguments:

  • timeExp - A date/timestamp or string. If not provided, this defaults to current time.
  • fmt - Date/time format pattern to follow. Ignored iftimeExpis not a string. Default value is "yyyy-MM-dd HH:mm:ss". See Datetime Patterns for valid date and time format patterns.

Examples:

> SELECT unix_timestamp(); 1476884637 > SELECT unix_timestamp('2016-04-08', 'yyyy-MM-dd'); 1460041200

to_unix_timestamp(timeExp[, fmt])

Returns the UNIX timestamp of the given time.

Arguments:

  • timeExp - A date/timestamp or string which is returned as a UNIX timestamp.
  • fmt - Date/time format pattern to follow. Ignored iftimeExpis not a string. Default value is "yyyy-MM-dd HH:mm:ss". See Datetime Patterns for valid date and time format patterns.

Examples:

> SELECT to_unix_timestamp('2016-04-08', 'yyyy-MM-dd'); 1460098800

4. from_unixtime从unix时间转换到当前时区的时间戳

注意:第一个参数是10位的时间戳

from_unixtime(unix_time[, fmt])

Returnsunix_timein the specifiedfmt.

Arguments:

  • unix_time - UNIX Timestamp to be converted to the provided format.
  • fmt - Date/time format pattern to follow. See Datetime Patterns for valid date and time format patterns. The 'yyyy-MM-dd HH:mm:ss' pattern is used if omitted.

Examples:

> SELECT from_unixtime(0, 'yyyy-MM-dd HH:mm:ss'); 1970-01-01 00:00:00 > SELECT from_unixtime(0); 1970-01-01 00:00:00

5. cast从unix时间强转到时间戳(转到设定的时区)

select cast(1614815429 as timestamp);

2021-03-04 07:50:29

6. date_format日期格式转换

第一个参数必须是标准格式的时间

date_format(timestamp, fmt)

Convertstimestampto a value of string in the format specified by the date formatfmt.

Arguments:

  • timestamp - A date/timestamp or string to be converted to the given format.
  • fmt - Date/time format pattern to follow. See Datetime Patterns for valid date and time format patterns.

Examples:

> SELECT date_format('2016-04-08', 'y'); 2016

1) 不受时区影响

SELECT date_format('2016-04-08 18', 'yyyy-MM-dd');

2016-04-09

2) 这种特定时间戳格式受时区影响

select date_format('2021-06-24T22:04:50+00:00', 'yyyy-MM-dd');

2021-06-25

2. 不受时区影响

1. 返回当前时间的unix时间戳
SELECT unix_timestamp();
1614237507

2. to_utc_timestamp时间戳从指定的时区转换到0时区

to_utc_timestamp(timestamp, timezone)

Given a timestamp like '2017-07-14 02:40:00.0', interprets it as a time in the given time zone, and renders that time as a timestamp in UTC. For example, 'GMT+1' would yield '2017-07-14 01:40:00.0'.

Examples:

> SELECT to_utc_timestamp('2016-08-31', 'Asia/Seoul'); 2016-08-30 15:00:00

3. from_utc_timestamp从0时区转换到指定时区

from_utc_timestamp(timestamp, timezone)

Given a timestamp like '2017-07-14 02:40:00.0', interprets it as a time in UTC, and renders that time as a timestamp in the given time zone. For example, 'GMT+1' would yield '2017-07-14 03:40:00.0'.

Examples:

> SELECT from_utc_timestamp('2017-07-14 02:40:00.0', 'GMT+1'); 2017-07-14 03:40:00

4. to_date时间从指定格式转换到标准格式日期yyyy-MM-dd

to_date(date_str[, fmt])

Parses thedate_strexpression with thefmtexpression to a date. Returns null with invalid input. By default, it follows casting rules to a date if thefmtis omitted.

Arguments:

  • date_str - A string to be parsed to date.
  • fmt - Date format pattern to follow. See Datetime Patterns for valid date and time format patterns.

Examples:

-- 默认按标准格式转换 > SELECT to_date('2009-07-30 04:17:52'); 2009-07-30 -- 指定格式转换 > select to_date('20161231', 'yyyyMMdd'); 2016-12-31 -- 指定可选格式,[]代表可选项 > select to_date('2024-12-02', 'yyyy-MM[-dd]') as dt_f; 2024-12-02 > select to_date('2024-12', 'yyyy-MM[-dd]') as dt_f; 2024-12-01

5. 日期的加减(最终转成日期格式)
SELECT date_add('2016-07-30 22:12:30', 1);
2016-07-31

6. to_timestamp从指定时间格式转换到标准格式

to_timestamp(timestamp_str[, fmt])

Parses thetimestamp_strexpression with thefmtexpression to a timestamp. Returns null with invalid input. By default, it follows casting rules to a timestamp if thefmtis omitted. The result data type is consistent with the value of configurationspark.sql.timestampType.

Arguments:

  • timestamp_str - A string to be parsed to timestamp.
  • fmt - Timestamp format pattern to follow. See Datetime Patterns for valid date and time format patterns.

Examples:

> select to_timestamp('2023/5/14 2:11:00', 'yyyy/M/d h:mm:ss'); 2023-05-14 02:11:00 > select to_timestamp('20200726', 'yyyyMMdd'); 2020-07-26 00:00:00


3. 客户端显示影响

前端显示date、time类型的时候,有可能收时区的影响,为了避免不必要的麻烦可存成字符串;

select typeof( from_utc_timestamp(cast(cast(1697992306453 as bigint)/1000 as timestamp), 'GMT+00:00') ) as time_ori -- timestamp类型, 客户端展示时可能转到本地时区 ,typeof( date_format(from_utc_timestamp(cast(cast(1697992306453 as bigint)/1000 as timestamp),'GMT+00:00'), 'yyyy-mm-dd hh:mm:ss') ) as time_utc -- 字符串类型, 不受时区影响 ; time_ori time_utc timestamp string

四、获取时间差

1. 获取某个时段数据

限定时间最好要闭合, 否则回溯历史数据会出问题.

-- 1. sql 函数推算(日期必须是标准格式:yyyy-MM-dd) select * from tbl_name where dt >= date_format(date_sub('2020-07-26', 2),'yyyyMMdd') and dt <= date_format('2020-07-26','yyyyMMdd') ; -- 2. 调度直接传入 select * from tbl_name where dt >= '20200726' and dt <= '20200727' ;

2. 获取时间差

-- 指定时间格式,获取两个时间相差的秒数 select unix_timestamp('2023/5/14 9:09:05', 'yyyy/M/d h:mm:ss') - unix_timestamp('2023/5/14 9:09:00', 'yyyy/M/d h:mm:ss') as diff_seconds; -- 指定时间格式, 获取相差天数(左参数-右参数) SELECT DATEDIFF(TO_DATE('20250705', 'yyyyMMdd'), TO_DATE('20250703', 'yyyyMMdd')) AS diff_days; diff_days 2

五、格式或时区转换

指定时区:set spark.sql.session.timeZone=UTC;

不受时区影响函数:to_timestamp、

时区影响函数:from_unixtime、from_utc_timestamp

-- 1 从指定时间格式转换到标准格式 select to_timestamp('2023/5/14 2:11:00', 'yyyy/M/d h:mm:ss'); 2023-05-14 02:11:00 select to_timestamp('20200726', 'yyyyMMdd'); 2020-07-26 00:00:00 -- 2 从标准格式时间(yyyy-MM-dd 和 yyyy-MM-dd HH:mm:ss.SSSS)转到指定格式时间 select date_format('2016-04-08', 'yyyyMMdd'); 20160408 -- 3 yyyyMMdd--->yyyy-MM-dd 时间格式转换 select to_date('20161231', 'yyyyMMdd'); 2016-12-31 select concat_ws('-',substr('20200726',1,4),substr('20200726',5,2),substr('20200726',7,2)); 2020-07-26 select date_format(to_timestamp('20200726', 'yyyyMMdd'), 'yyyy-MM-dd'); 2020-07-26 -- 4 从unix时间戳(10位)转换到当前时区时间戳, 再从当前时区转换到指定时区 -- session时区是0时区,转换到东八区 > set spark.sql.session.timeZone=UTC; > select from_utc_timestamp(from_unixtime(0),'GMT+8') as dt; 1970-01-01 08:00:00

日期格式符 - 格式符的数量影响显示格式,具体要什么样式可以实际测试;

Datetime patterns - Spark 3.5.1 Documentation

-- 季度的格式符号 > select date_format(date '2024-05-01', "q") as time; 2 > select date_format(date '2024-05-01', "qq") as time; 02 > select date_format(date '2024-05-01', "Q") as time; 2 > select date_format(date '2024-05-01', "QQ") as time; 02 > select date_format(date '2024-05-01', "QQQ") as time; Q2 > select date_format(date '2024-05-01', "QQQQ") as time; 2nd quarter -- 月份的格式符号 > select date_format(date '1970-01-01', "M"); 1 > select date_format(date '1970-09-01', "MM"); 09 > select date_format(date '1970-01-01', "MMM"); Jan > select date_format(date '1970-01-01', "MMMM"); January

不同语言的转换

'२०२४-१०-१९ ०५:१६:०५' 转换到 '2024-10-19 05:16:05'

import org.apache.hadoop.hive.ql.exec.UDF import java.text.SimpleDateFormat import java.util.TimeZone /** * 日期时间转换时区 */ class date_trans_tz extends UDF { /** * 指定要转换的时区和格式 * * @param ori_date 原日期 * @param ori_tz 原时区 * @param tgt_tz 目标时区 * @param format 日期格式 */ def evaluate(ori_date: String, ori_tz: String, tgt_tz: String, format: String): String = { try { // 日期样式 val sdf = new SimpleDateFormat(format) // 原时区解析日期 sdf.setTimeZone(TimeZone.getTimeZone(ori_tz)) val dateStr = sdf.parse(ori_date) // 更改时区 sdf.setTimeZone(TimeZone.getTimeZone(tgt_tz)) sdf.format(dateStr.getTime) } catch { case e: Exception => "" } } /** * 指定要转换的时区 * * @param ori_date 原日期 * @param ori_tz 原时区 */ def evaluate(ori_date: String, ori_tz: String, tgt_tz: String): String = { val format = "yyyy-MM-dd HH:mm:ss" try { // 日期样式 val sdf = new SimpleDateFormat(format) // 原时区解析日期 sdf.setTimeZone(TimeZone.getTimeZone(ori_tz)) val dateStr = sdf.parse(ori_date) // 更改时区 sdf.setTimeZone(TimeZone.getTimeZone(tgt_tz)) sdf.format(dateStr.getTime) } catch { case e: Exception => "" } } /** * 默认转换到0时区 * * @param ori_date 原日期 * @param ori_tz 原时区 */ def evaluate(ori_date: String, ori_tz: String): String = { val tgt_tz = "GMT+00:00" val format = "yyyy-MM-dd HH:mm:ss" try { // 日期样式 val sdf = new SimpleDateFormat(format) // 原时区解析日期 sdf.setTimeZone(TimeZone.getTimeZone(ori_tz)) val dateStr = sdf.parse(ori_date) // 更改时区 sdf.setTimeZone(TimeZone.getTimeZone(tgt_tz)) sdf.format(dateStr.getTime) } catch { case e: Exception => "" } } }

六、获取特定日期

1. 静态日期处理

-- 1 获取周一日期 SELECT DATE_FORMAT(DATE_TRUNC('WEEK', '2020-09-15'),'yyyy-MM-dd'); 2020-09-14 -- 2 获取季初日期 SELECT DATE_FORMAT(DATE_TRUNC('QUARTER', '2020-09-15'),'yyyy-MM-dd'); 2020-07-01 -- 3 获取年初日期 SELECT TRUNC('2020-09-15', 'YEAR'); 2020-01-01 SELECT DATE_FORMAT(DATE_TRUNC('YEAR', '2020-09-15'),'yyyy-MM-dd'); 2020-01-01 -- 4 获取月初日期 SELECT TRUNC('2020-09-15', 'MM'); 2020-09-01 SELECT DATE_FORMAT(DATE_TRUNC('MM', '2020-09-15'),'yyyy-MM-dd'); 2020-09-01 SELECT CONCAT(SUBSTRING('2020-09-15',1,8),'01'); 2020-09-01 -- 5 获取月末日期 -- last_day(date) - Returns the last day of the month which the date belongs to. SELECT LAST_DAY('2009-01-12'); 2009-01-31

2. 动态日期处理

-- 获取昨天日期 SELECT DATE_FORMAT(DATE_ADD(CURRENT_DATE(), -1),'yyyMMdd'); -- 获取本周一/上周一日期 SELECT DATE_FORMAT(DATE_ADD(DATE_TRUNC('WEEK', CURRENT_DATE()), 0), 'yyyyMMdd') AS monday_date; SELECT DATE_FORMAT(DATE_ADD(DATE_TRUNC('WEEK', CURRENT_DATE()), -7), 'yyyyMMdd') AS monday_date; -- 获取本月初/上月初日期 SELECT DATE_FORMAT(ADD_MONTHS(DATE_TRUNC('MM', CURRENT_DATE()), 0), 'yyyyMMdd') AS monday_date; SELECT DATE_FORMAT(ADD_MONTHS(DATE_TRUNC('MM', CURRENT_DATE()), -1), 'yyyyMMdd') AS monday_date; -- 获取本月末/上月末日期 SELECT DATE_FORMAT(ADD_MONTHS(LAST_DAY(CURRENT_DATE()), 0), 'yyyyMMdd') AS monday_date; SELECT DATE_FORMAT(ADD_MONTHS(LAST_DAY(CURRENT_DATE()), -1), 'yyyyMMdd') AS monday_date;

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 1:13:25

多线程高并发编程(4) -- ReentrantReadWriteLock读写锁源码分析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 1:12:39

开发常用工具

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 1:12:02

全局快门CMOS传感器OG05C:DCG HDR与Nyxel近红外增强解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 1:11:07

从需求到模型:SysML/UML系统建模方法论SYSMOD实战拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 1:11:00

双通道数字温度传感器与PIC18F45K80的暖通测温实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 1:09:18

PJ85718DM与STM32F401RB温控系统设计实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华