2017-06-27 34 views
2

我需要帮助,因为它似乎我失去了时区:)如何unix时间戳转换成给定时区星火

我用星火1.6.2

我有这样的时代:

+--------------+-------------------+-------------------+ 
|unix_timestamp|UTC    |Europe/Helsinki | 
+--------------+-------------------+-------------------+ 
|1491771599 |2017-04-09 20:59:59|2017-04-09 23:59:59| 
|1491771600 |2017-04-09 21:00:00|2017-04-10 00:00:00| 
|1491771601 |2017-04-09 21:00:01|2017-04-10 00:00:01| 
+--------------+-------------------+-------------------+ 

默认时区是在火花机执行以下操作:

#timezone = DefaultTz:欧洲/布拉格,SparkUtilTz:欧洲/布拉格

logger.info("#timezone = DefaultTz: {}, SparkUtilTz: {}", TimeZone.getDefault.getID, org.apache.spark.sql.catalyst.util.DateTimeUtils.defaultTimeZone.getID) 

我想,以计算日期和时间在给定的时区分组的时间戳输出(现在是欧洲/赫尔辛基+ 3小时)。

我期待什么:

+----------+---------+-----+ 
|date  |hour  |count| 
+----------+---------+-----+ 
|2017-04-09|23  |1 | 
|2017-04-10|0  |2 | 
+----------+---------+-----+ 

代码(使用from_utc_timestamp):

def getCountsPerTime(sqlContext: SQLContext, inputDF: DataFrame, timeZone: String, aggr: String): DataFrame = { 

    import sqlContext.implicits._ 

    val onlyTime = inputDF.select(
     from_utc_timestamp($"unix_timestamp".cast(DataTypes.TimestampType), timeZone).alias("time") 
    ) 

    val visitsPerTime = 
     if (aggr.equalsIgnoreCase("hourly")) { 
      onlyTime.groupBy(
       date_format($"time", "yyyy-MM-dd").alias("date"), 
       date_format($"time", "H").cast(DataTypes.IntegerType).alias("hour"), 
      ).count() 
     } else if (aggr.equalsIgnoreCase("daily")) { 
      onlyTime.groupBy(
       date_format($"time", "yyyy-MM-dd").alias("date") 
      ).count() 
     } 

    visitsPerTime.show(false) 

    visitsPerTime 
} 

我得到了什么:'(

+----------+---------+-----+ 
|date  |hour  |count| 
+----------+---------+-----+ 
|2017-04-09|22  |1 | 
|2017-04-09|23  |2 | 
+----------+---------+-----+ 

试图与to_utc_timestamp把它包起来:

def getCountsPerTime(sqlContext: SQLContext, inputDF: DataFrame, timeZone: String, aggr: String): DataFrame = { 

    import sqlContext.implicits._ 

    val onlyTime = inputDF.select(
     to_utc_timestamp(from_utc_timestamp($"unix_timestamp".cast(DataTypes.TimestampType), timeZone), DateTimeUtils.defaultTimeZone.getID).alias("time") 
    ) 

    val visitsPerTime = ... //same as above 

    visitsPerTime.show(false) 

    visitsPerTime 
} 

我得到了什么:(

+----------+---------+-----+ 
|tradedate |tradehour|count| 
+----------+---------+-----+ 
|2017-04-09|20  |1 | 
|2017-04-09|21  |2 | 
+----------+---------+-----+ 

你有什么想法的妥善解决是什么?

在此先感谢您的帮助

+0

看来下面的代码解决了这个问题:'to_utc_timestamp(from_utc_timestamp($ “UNIX_TIMESTAMP”。投(DataTypes.TimestampType)的timeZone),TimeZone.getDefault.getID).alias(“时代”)' – albundyszabolcs

+0

如果你能解释一下实际上在各种情况下发生了什么事,我认为这将让这个一个不错的,可重复使用的答案 –

+2

快速术语教训:““我有这样epocs”' - 不,你不知道。你有“Unix时间戳”。一个“划时代”是好的开始,在这种情况下,时代被固定在'1970-01-01T00:00:00Z'。计算中使用了许多不同的时代,但Unix时间只有一个。 –

回答

0

你的代码不为我工作,所以我不能复制你拿到了最后两个输出。

但我会向你提供关于如何可以实现我假设你预计

输出一些提示你已经有dataframe作为

+--------------+---------------------+---------------------+ 
|unix_timestamp|UTC     |Europe/Helsinki  | 
+--------------+---------------------+---------------------+ 
|1491750899 |2017-04-09 20:59:59.0|2017-04-09 23:59:59.0| 
|1491750900 |2017-04-09 21:00:00.0|2017-04-10 00:00:00.0| 
|1491750901 |2017-04-09 21:00:01.0|2017-04-10 00:00:01.0| 
+--------------+---------------------+---------------------+ 

我用下面的代码

得到这个 dataframe
import sqlContext.implicits._ 
import org.apache.spark.sql.functions._ 

val inputDF = Seq(
    "2017-04-09 20:59:59", 
    "2017-04-09 21:00:00", 
    "2017-04-09 21:00:01" 
).toDF("unix_timestamp") 

val onlyTime = inputDF.select(
    unix_timestamp($"unix_timestamp").alias("unix_timestamp"), 
    from_utc_timestamp($"unix_timestamp".cast(DataTypes.TimestampType), "UTC").alias("UTC"), 
    from_utc_timestamp($"unix_timestamp".cast(DataTypes.TimestampType), "Europe/Helsinki").alias("Europe/Helsinki") 
) 

onlyTime.show(false) 

一旦你有以上dataframe,得到输出dataframe你desi重新将要求您split日期,groupbycount如下

onlyTime.select(split($"Europe/Helsinki", " ")(0).as("date"), split(split($"Europe/Helsinki", " ")(1).as("time"), ":")(0).as("hour")) 
     .groupBy("date", "hour").agg(count("date").as("count")) 
    .show(false) 

所得dataframe

+----------+----+-----+ 
|date  |hour|count| 
+----------+----+-----+ 
|2017-04-09|23 |1 | 
|2017-04-10|00 |2 | 
+----------+----+-----+ 
相关问题