【问题标题】:How to Update a column in Scala which is in Date Format如何更新 Scala 中日期格式的列
【发布时间】:2019-09-16 15:04:00
【问题描述】:

在 Spark Scala 中需要帮助来编写以下问题的代码。 我有一个包含如下记录的文件。

aaa|2019-07-11 02:15:50

bbb|2019-07-03 22:21:50

vvv|2019-07-03 19:30:40

bzx|2019-07-11 02:15:30

rrr|2019-06-24 01:29:10

mmm|2019-06-23 20:35:05

qqq|2019-07-12 08:10:15

eee|2019-07-11 01:49:30

iii|2019-06-23 22:31:45

我已拆分文件并取了第二列

val file = spark.read.format("csv").option("delimiter", """|""").load(pathOfDumpfile).toDF()  

现在我需要将“0000-00-00 00:00:05”添加到所有 文件的值(日期格式的第二列)并将其另存为文件,如下所示

aaa|2019-07-11 02:15:55

bbb|2019-07-03 22:21:55

vvv|2019-07-03 19:30:45

bzx|2019-07-11 02:15:35

rrr|2019-06-24 01:29:15

mmm|2019-06-23 20:35:10

qqq|2019-07-12 08:10:20

eee|2019-07-11 01:49:35

iii|2019-06-23 22:31:50

谁能建议我如何将 + 5 秒添加到文件/列中的所有记录。

真的很有帮助。在日期时间字段中添加后,秒或分钟应该改变,它不应该像它的 2019-07-11 23:59:59 那样影响日期,然后即使在秒上加 1 也会是 2019-07-12 00: 00:00。我想添加但不想更改日期,所以我怎么做

【问题讨论】:

    标签: java scala apache-spark apache-spark-sql


    【解决方案1】:

    你可以使用 unix_timestamp 来做

    scala>  var dfv = Seq(("aaa","2019-07-11 23:59:59"),("bbb","2019-07-03 22:21:50"),("vvv","2019-07-03 19:30:40"),("bzx","2019-07-11 02:15:30"),("rrr","2019-06-24 01:29:10"),("mmm","2019-06-23 20:35:05"),("qqq","2019-07-12 08:10:15"),("eee","2019-07-11 01:49:30"),("iii","2019-06-23 22:31:45")).toDF("value","_date")
    
    scala> dfv.show
    +-----+-------------------+
    |value|              _date|
    +-----+-------------------+
    |  aaa|2019-07-11 23:59:59|
    |  bbb|2019-07-03 22:21:50|
    |  vvv|2019-07-03 19:30:40|
    |  bzx|2019-07-11 02:15:30|
    |  rrr|2019-06-24 01:29:10|
    |  mmm|2019-06-23 20:35:05|
    |  qqq|2019-07-12 08:10:15|
    |  eee|2019-07-11 01:49:30|
    |  iii|2019-06-23 22:31:45|
    +-----+-------------------+
    
    scala> dfv.withColumn("_date_v1",when(date_format(from_unixtime(unix_timestamp($"_date")),"HH:mm:ss ")>"23:59:55",$"_date").otherwise(from_unixtime(unix_timestamp($"_date")+5,"yyyy-MM-dd HH:mm:ss"))).show
    +-----+-------------------+-------------------+
    |value|              _date|           _date_v1|
    +-----+-------------------+-------------------+
    |  aaa|2019-07-11 23:59:59|2019-07-11 23:59:59|
    |  bbb|2019-07-03 22:21:50|2019-07-03 22:21:55|
    |  vvv|2019-07-03 19:30:40|2019-07-03 19:30:45|
    |  bzx|2019-07-11 02:15:30|2019-07-11 02:15:35|
    |  rrr|2019-06-24 01:29:10|2019-06-24 01:29:15|
    |  mmm|2019-06-23 20:35:05|2019-06-23 20:35:10|
    |  qqq|2019-07-12 08:10:15|2019-07-12 08:10:20|
    |  eee|2019-07-11 01:49:30|2019-07-11 01:49:35|
    |  iii|2019-06-23 22:31:45|2019-06-23 22:31:50|
    +-----+-------------------+-------------------+
    

    如果您有任何与此相关的问题,请告诉我。

    【讨论】:

    • 嗨,你能帮我吗?如何在 unix_timestamp($"_date")+5 stackoverflow.com/users/5303116/mahesh-gupta 中将变量作为列名而不是硬编码的列名 (_date)
    • @Arush70 如果您有单列日期并且您想在每行中添加 5 秒。所以你必须这样做,如果你将使用 withColumn
    • 嗨 Mahesh,是的,得到了​​答案,但问题是列名可以说 _date 我需要通过变量从 config.yml 文件中调用它,所以我该怎么做。在配置文件中,我添加了 a= _date 并且 a 在代码中定义为字符串,因此当尝试在 unix_timestamp($"_date")+5 中添加 a 作为 unix_timestamp(a)+5 时出现错误 'a' 是字符串需要列名.那么你能帮助如何添加这个stackoverflow.com/users/5303116/mahesh-gupta
    • 尝试将列名字符串包装在 col 中,例如:unix_timestamp(col(a))+5
    • 所以@Arush70 尝试使用 sc.getConf.get() 获取该列名
    【解决方案2】:

    您可以在自定义 udf 的帮助下执行此操作,例如:

    import org.apache.spark.sql.functions.{col, udf}
    
    val file = spark.read.format("csv").option("delimiter", """|""").load(pathOfDumpfile).toDF("a", "b")
    
    val timeUDF = udf((x: java.sql.Timestamp) => new java.sql.Timestamp(time.getTime + 5000)) //getTime returns ms
    
    file.select(col("a"), timeUDF(col("b")))
    .write(...)
    

    【讨论】:

    • UDF 在这里是多余的,因为我们已经在 Spark SQL 中内置了日期/时间函数,它们完全可以胜任这项工作。
    【解决方案3】:

    您可以在 spark 中使用 INTERVAL 语法。

    使用数据框:

    val foo = spark.sql(""" select current_timestamp as ts """)
    foo.select($"ts", $"ts" + expr("INTERVAL 5 SECONDS") as "ts_plus").show(false)
    +-----------------------+-----------------------+
    |ts                     |ts_plus                |
    +-----------------------+-----------------------+
    |2019-09-16 10:33:17.626|2019-09-16 10:33:22.626|
    +-----------------------+-----------------------+
    

    使用 Spark SQL:

    foo.createOrReplaceTempView("fooView")
    spark.sql(""" select ts, ts + INTERVAL 5 seconds from fooView""").show(false)
    +-----------------------+------------------------------------------+
    |ts                     |CAST(ts + interval 5 seconds AS TIMESTAMP)|
    +-----------------------+------------------------------------------+
    |2019-09-16 10:35:12.847|2019-09-16 10:35:17.847                   |
    +-----------------------+------------------------------------------+
    

    【讨论】:

      猜你喜欢
      • 2015-04-15
      • 1970-01-01
      • 2014-04-03
      • 2015-01-06
      • 2020-05-27
      • 1970-01-01
      • 2021-10-04
      • 2019-03-30
      相关资源
      最近更新 更多