Problem: How to add or subtract hours, minutes, and seconds to/from Spark DataFrame date or timestamp columns?
Solution: Spark SQL has no functions that add/subtract time unit hours, minutes, and seconds to or from a Timestamp column, however, SQL defines Interval to do it.
Refer to Spark SQL Date and Timestamp Functions for all Date & Time functions.
<a id="h-1-using-spark-sql-interval"></a>
1. Using Spark SQL Interval
Since Spark doesn't have any functions to add units to the Timestamp, we use INTERVAL to do our job.
// Using Spark SQL Interval
import org.apache.spark.sql.functions._
import spark.sqlContext.implicits._
spark.sql( "select current_timestamp," +
"cast(current_timestamp as TIMESTAMP) + INTERVAL 2 hours as added_hours," +
"cast(current_timestamp as TIMESTAMP) + INTERVAL 5 minutes as added_minutes," +
"cast(current_timestamp as TIMESTAMP) + INTERVAL 55 seconds as added_seconds"
).show(false)
Before we apply INTERVAL, first you need to convert timestamp column from string to TimestampType using cast.
Yields below output:
// Output:
+----------------------+----------------------+----------------------+----------------------+
|current_timestamp() |added_hours |added_minutes |added_seconds |
+----------------------+----------------------+----------------------+----------------------+
|2019-11-17 05:54:22.87|2019-11-17 07:54:22.87|2019-11-17 05:59:22.87|2019-11-17 05:55:17.87|
+----------------------+----------------------+----------------------+----------------------+
The above example directly uses spark select without DataFrame, below example demonstrates how to do the same when we have a timestamp as a DataFrame column
import org.apache.spark.sql.functions._
val df = Seq(("2019-07-01 12:01:19.101"),
("2019-06-24 12:01:19.222"),
("2019-11-16 16:44:55.406"),
("2019-11-16 16:50:59.406")).toDF("input_timestamp")
df.createOrReplaceTempView("AddTimeExample")
val df2 = spark.sql("select input_timestamp, " +
"cast(input_timestamp as TIMESTAMP) + INTERVAL 2 hours as added_hours," +
"cast(input_timestamp as TIMESTAMP) + INTERVAL 5 minutes as added_minutes," +
"cast(input_timestamp as TIMESTAMP) + INTERVAL 55 seconds as added_seconds from AddTimeExample"
)
df2.show(false)
Here, first, we create a temporary table using createOrReplaceTempView() and then use this on SQL select.
+-----------------------+-----------------------+-----------------------+-----------------------+
|input_timestamp |added_hours |added_minutes |added_seconds |
+-----------------------+-----------------------+-----------------------+-----------------------+
|2019-07-01 12:01:19.101|2019-07-01 14:01:19.101|2019-07-01 12:06:19.101|2019-07-01 12:02:14.101|
|2019-06-24 12:01:19.222|2019-06-24 14:01:19.222|2019-06-24 12:06:19.222|2019-06-24 12:02:14.222|
|2019-11-16 16:44:55.406|2019-11-16 18:44:55.406|2019-11-16 16:49:55.406|2019-11-16 16:45:50.406|
|2019-11-16 16:50:59.406|2019-11-16 18:50:59.406|2019-11-16 16:55:59.406|2019-11-16 16:51:54.406|
+-----------------------+-----------------------+-----------------------+-----------------------+
Let's see the same example without creating a temporary table but use <a href="https://aistudylabs.com/apache-spark/spark-dataframe-withcolumn/">withColumn()</a> and expr() function
import org.apache.spark.sql.functions._
df.withColumn("added_hours",col("input_timestamp") + expr("INTERVAL 2 HOURS"))
.withColumn("added_minutes",col("input_timestamp") + expr("INTERVAL 2 minutes"))
.withColumn("added_seconds",col("input_timestamp") + expr("INTERVAL 2 seconds"))
.show(false)
<a id="h-2-spark-subtract-hours-minutes-and-seconds-from-timestamp"></a>
2. Spark Subtract Hours, Minutes, and Seconds from Timestamp
By just using - instead of +, you can subtract an hour, minute, and second from Timestamp.
// Spark Subtract Hours, Minutes, and Seconds from Timestamp
import org.apache.spark.sql.functions._
df.withColumn("sub_hours",col("input_timestamp") - expr("INTERVAL 2 HOURS"))
.withColumn("sub_minutes",col("input_timestamp") - expr("INTERVAL 2 minutes"))
.withColumn("sub_seconds",col("input_timestamp") - expr("INTERVAL 2 seconds"))
.show(false)
<a id="h-3-complete-example"></a>
3. Complete Example
Below is a complete example of how to add or subtract hours, minutes, and seconds from the DataFrame Timestamp column. This example is also available at Spark Examples Git Hub project
// Complete Example
package com.aistudylabs.spark.dataframe.functions.datetime
import org.apache.spark.sql.SparkSession
object AddTime extends App {
val spark:SparkSession = SparkSession.builder()
.master("local")
.appName("AIStudyLabs.com")
.getOrCreate()
spark.sparkContext.setLogLevel("ERROR")
import spark.sqlContext.implicits._
spark.sql( "select current_timestamp," +
"cast(current_timestamp as TIMESTAMP) + INTERVAL 2 hours as added_hours," +
"cast(current_timestamp as TIMESTAMP) + INTERVAL 5 minutes as added_minutes," +
"cast(current_timestamp as TIMESTAMP) + INTERVAL 55 seconds as added_seconds"
).show(false)
val df = Seq(("2019-07-01 12:01:19.101"),
("2019-06-24 12:01:19.222"),
("2019-11-16 16:44:55.406"),
("2019-11-16 16:50:59.406")).toDF("input_timestamp")
df.createOrReplaceTempView("AddTimeExample")
val df2 = spark.sql("select input_timestamp, " +
"cast(input_timestamp as TIMESTAMP) + INTERVAL 2 hours as added_hours," +
"cast(input_timestamp as TIMESTAMP) + INTERVAL 5 minutes as added_minutes," +
"cast(input_timestamp as TIMESTAMP) + INTERVAL 55 seconds as added_seconds from AddTimeExample"
)
df2.show(false)
// Alternate way
df.withColumn("added_hours",col("input_timestamp") + expr("INTERVAL 2 HOURS"))
.withColumn("added_minutes",col("input_timestamp") + expr("INTERVAL 2 minutes"))
.withColumn("added_seconds",col("input_timestamp") + expr("INTERVAL 2 seconds"))
.show(false)
}
Happy Learning!!
<a id="h-related-articles"></a>
Related Articles
- Spark SQL - Add Day, Month, and Year to Date
- Spark Timestamp - Extract hour, minute and second
- Spark SQL - Working with Unix Timestamp
- Spark date_format() - Convert Timestamp to String
- Spark to_timestamp() - Convert String to Timestamp Type
- Spark Add Constant Column to DataFrame
- Add Multiple Jars to Spark Submit Classpath?
- Spark – Add New Column & Multiple Columns to DataFrame
- Cannot call methods on a stopped SparkContext in Spark
- Tune Spark Executor Number, Cores, and Memory
- Calculate difference between two dates in days, months and years
