Когда я пробовал разницу между тем же штампом времени, он дал 0 дней 5 часов 30 минут
, поэтому, чтобы получить его точно, я вычитал 5 часов и 30 минут
function get_time_diff( datetime )
{
var datetime = typeof datetime !== 'undefined' ? datetime : "2014-01-01 01:02:03.123456";
var datetime = new Date(datetime).getTime();
var now = new Date().getTime();
if( isNaN(datetime) )
{
return "";
}
console.log( datetime + " " + now);
if (datetime < now) {
var milisec_diff = now - datetime;
}else{
var milisec_diff = datetime - now;
}
var days = Math.floor(milisec_diff / 1000 / 60 / (60 * 24));
var date_diff = new Date( milisec_diff );
return days + "d "+ (date_diff.getHours() - 5) + "h " + (date_diff.getMinutes() - 30) + "m";
}
Я нашел обходной путь для этого, используя функцию to_utc_timestamp в pyspark, однако не совсем уверен, является ли это наиболее эффективным, хотя, похоже, он отлично работает на примерно 100 млн строк данных. Вы можете избежать regex_replace, если ваша строка метки времени выглядела так - 1997-02-28 10: 30: 40.897748
from pyspark.sql.functions import regexp_replace, to_utc_timestamp
df = spark.createDataFrame([('19970228-10:30:40.897748',)], ['new_t'])
df = df.withColumn('t', regexp_replace('new_t', '^(.{4})(.{2})(.{2})-', '$1-$2-$3 '))
df = df.withColumn("time", to_utc_timestamp(df.t, "UTC").alias('t'))
df.show(5,False)
print(df.dtypes)
Обычно гранулярность меток времени указывается в секундах, поэтому я не думаю, что существует прямой метод сохранения гранулярности в миллисекундах.
В pyspark есть функция unix_timestamp
, которая:
unix_timestamp(timestamp=None, format='yyyy-MM-dd HH:mm:ss')
Конвертировать строку времени с данным шаблоном (
'yyyy-MM-dd HH:mm:ss'
по умолчанию) в метку времени Unix ( в секундах ), используя часовой пояс по умолчанию и локаль по умолчанию, возвращают ноль в случае неудачи.blockquote>if `timestamp` is None, then it returns current timestamp. >>> spark.conf.set("spark.sql.session.timeZone", "America/Los_Angeles") >>> time_df = spark.createDataFrame([('2015-04-08',)], ['dt']) >>> time_df.select(unix_timestamp('dt', 'yyyy-MM-dd').alias('unix_time')).collect() [Row(unix_time=1428476400)] >>> spark.conf.unset("spark.sql.session.timeZone")
Пример использования:
import pyspark.sql.functions as F res = df.withColumn(colName, F.unix_timestamp(F.col(colName), \ format='yyyy-MM-dd HH:mm:ss.000').alias(colName) )
Что вы можете сделать, это разделить строку даты (
str.rsplit('.', 1)
), разделяя миллисекунды (например, создавая другой столбец) в ваш фрейм данных.РЕДАКТИРОВАТЬ
В вашем примере проблема в том, что время имеет тип string. Сначала вам нужно преобразовать его в тип
timestamp
: это можно сделать с помощью:res = time_df.withColumn("new_col", to_timestamp("dt", "yyyyMMdd-hh:mm:ss"))
Затем вы можете использовать
unix_timestap
res2 = res.withColumn("time", F.unix_timestamp(F.col("parsed"), format='yyyyMMdd-hh:mm:ss.000').alias("time"))
Наконец, чтобы создать столбцы с миллисекунды:
res3 = res2.withColumn("ms", F.split(res2['dt'], '[.]').getItem(1))