Приведите метку времени int96 от паркета к голангу - PullRequest
0 голосов
/ 01 ноября 2018

Наличие этого 12-байтового массива (int96) для отметки времени.

[128 76 69 116 64 7 0 0 48 131 37 0]

Как мне привести его к метке времени?

Я понимаю, что первые 8 байтов должны быть преобразованы в int64 миллисекунды, которые представляют дату и время эпохи.

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

@ Золтан, ты определенно заслуживаешь голоса, хотя ты не поставил sulotion Голанга.

Спасибо вам и https://github.com/carlosjhr64/jd

Я написал функцию func int96ToJulian(parquetDate []byte) time.Time

детская площадка

func int96ToJulian(parquetDate []byte) time.Time {
    nano := binary.LittleEndian.Uint64(parquetDate[:8])
    dt := binary.LittleEndian.Uint32(parquetDate[8:])

    l := dt + 68569
    n := 4 * l / 146097
    l = l - (146097*n+3)/4
    i := 4000 * (l + 1) / 1461001
    l = l - 1461*i/4 + 31
    j := 80 * l / 2447
    k := l - 2447*j/80
    l = j / 11
    j = j + 2 - 12*l
    i = 100*(n-49) + i + l

    tm := time.Date(int(i), time.Month(j), int(k), 0, 0, 0, 0, time.UTC)
    return tm.Add(time.Duration(nano))
}
0 голосов
/ 01 ноября 2018

Первые 8 байтов - это время в наносекциях, а не миллисекундах. Они тоже измеряются не с эпохи, а с полуночи. Часть даты хранится отдельно в последних 4 байтах как Юлианский номер дня .

Вот результат эксперимента, который я провел ранее, который может помочь. Я хранил '2000-01-01 12:34:56' как int96 и выгружал с паркетными инструментами:

$ parquet-tools dump hdfs://path/to/parquet/file | tail -n 1
value 1: R:0 D:1 V:117253024523396126668760320

Поскольку 117253024523396126668760320 = 0x60FD4B3229000059682500, 12 байтов равны 00 60 FD 4B 32 29 00 00 | 59 68 25 00, где | показывает границу между частями времени и даты.

00 60 FD 4B 32 29 00 00 - это временная часть. Нам нужно обратить байты обратно, потому что временная метка int96 использует обратный порядок байтов, поэтому мы получаем 0x000029324BFD6000 = 45296 * 10 ^ 9 наносекунд = 45296 секунд = 12 часов + 34 минуты + 56 секунд.

59 68 25 00 - это часть даты, если мы поменяем местами байты, мы получим 0x00256859 = 2451545 как номер юлианского дня, что соответствует 2000-01-01.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...