Строка Int96Value to Date - PullRequest
       5

Строка Int96Value to Date

0 голосов
/ 09 декабря 2018

При чтении файла паркета (используя Scala) я считываю поле метки времени как:

Int96Value{Binary{12 constant bytes, [0, 44, 84, 119, 54, 49, 0, 0, -62, -127, 37, 0]}}

Как я могу преобразовать его в строку даты?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

java.time поддерживает юлианские дни.

Кредиты Игорю для проведения исследования и выяснения, как интерпретировать 12 байтов вашего массива.

    byte[] int96Bytes = { 0, 44, 84, 119, 54, 49, 0, 0, -62, -127, 37, 0 };

    // Find Julian day
    int julianDay = 0;
    int index = int96Bytes.length;
    while (index > 8) {
        index--;
        julianDay <<= 8;
        julianDay += int96Bytes[index] & 0xFF;
    }

    // Find nanos since midday (since Julian days start at midday)
    long nanos = 0;
    // Continue from the index we got to
    while (index > 0) {
        index--;
        nanos <<= 8;
        nanos += int96Bytes[index] & 0xFF;
    }

    LocalDateTime timestamp = LocalDate.MIN
            .with(JulianFields.JULIAN_DAY, julianDay)
            .atTime(LocalTime.NOON)
            .plusNanos(nanos);
    System.out.println("Timestamp: " + timestamp);

Это печатает:

Метка времени: 2017-10-24T03: 01: 50

Я не рад преобразовать ваш байтовый массив в int и long вручную,но я не знаю, Паркет будет достаточно, чтобы использовать преобразования, которые, вероятно, доступны там.Используйте их, если можете.

Неважно, какую LocalDate мы используем в качестве отправной точки, так как мы все равно меняем ее на правильный юлианский день, поэтому я выбрал LocalDate.MIN, чтобы выбрать одну.

Как я читаю документацию, юлианские дни всегда в местном часовом поясе, то есть часовой пояс не понимается, и они всегда начинаются в полдень (а не в полночь).

Ссылка: Документация JulianFields в java.time

0 голосов
/ 09 декабря 2018

Я провел небольшое исследование для вас.Формат Int96 довольно специфичен и, похоже, не рекомендуется.

Вот обсуждение о преобразовании Int96 в Date.

На основании этого,Я создал следующий фрагмент кода:

  def main(args: Array[String]): Unit = {
    import java.util.Date
    import org.apache.parquet.example.data.simple.{Int96Value, NanoTime}
    import org.apache.parquet.io.api.Binary

    val int96Value = new Int96Value(Binary.fromConstantByteArray(Array(0, 44, 84, 119, 54, 49, 0, 0, -62, -127, 37, 0)))
    val nanoTime = NanoTime.fromInt96(int96Value)
    val nanosecondsSinceUnixEpoch = (nanoTime.getJulianDay - 2440588) * (86400 * 1000 * 1000 * 1000) + nanoTime.getTimeOfDayNanos
    val date = new Date(nanosecondsSinceUnixEpoch / (1000 * 1000))
    println(date)
  }

Однако он печатает Sun Sep 27 17:05:55 CEST 2093.Я не уверен, если это дата, которую вы ожидали.

Редактировать: , используя Instance, как предложено:

val nanosInSecond = 1000 * 1000 * 1000;
val instant = Instant.ofEpochSecond(nanosecondsSinceUnixEpoch / nanosInSecond, nanosecondsSinceUnixEpoch % nanosInSecond)
println(instant) // prints 2093-09-27T15:05:55.933865216Z
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...