Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moved Parquet specific methods out of DateTimeUtils #4819

Merged
merged 3 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 0 additions & 52 deletions engine/time/src/main/java/io/deephaven/time/DateTimeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -982,21 +982,6 @@ public static long epochNanos(@Nullable final ZonedDateTime dateTime) {
return safeComputeNanos(dateTime.toEpochSecond(), dateTime.getNano());
}

/**
* Returns nanoseconds from the Epoch for a {@link LocalDateTime} value in UTC timezone.
*
* @param localDateTime the local date time to compute the Epoch offset for
* @return nanoseconds since Epoch, or a NULL_LONG value if the local date time is null
*/
@ScriptApi
public static long epochNanosUTC(@Nullable final LocalDateTime localDateTime) {
if (localDateTime == null) {
return NULL_LONG;
}
return TimeUnit.SECONDS.toNanos(localDateTime.toEpochSecond(ZoneOffset.UTC))
+ localDateTime.toLocalTime().getNano();
}

/**
* Returns microseconds from the Epoch for an {@link Instant} value.
*
Expand Down Expand Up @@ -1415,43 +1400,6 @@ public static ZonedDateTime excelToZonedDateTime(final double excel, @Nullable f
return epochMillisToZonedDateTime(excelTimeToEpochMillis(excel, timeZone), timeZone);
}

/**
* Converts nanoseconds from the Epoch to a {@link LocalDateTime} in UTC timezone.
*
* @param nanos nanoseconds since Epoch
* @return {@code null} if the input is {@link QueryConstants#NULL_LONG}; otherwise the input nanoseconds from the
* Epoch converted to a {@link LocalDateTime} in UTC timezone
*/
public static @Nullable LocalDateTime epochNanosToLocalDateTimeUTC(final long nanos) {
return nanos == NULL_LONG ? null
: LocalDateTime.ofEpochSecond(nanos / 1_000_000_000L, (int) (nanos % 1_000_000_000L), ZoneOffset.UTC);
}

/**
* Converts microseconds from the Epoch to a {@link LocalDateTime} in UTC timezone.
*
* @param micros microseconds since Epoch
* @return {@code null} if the input is {@link QueryConstants#NULL_LONG}; otherwise the input microseconds from the
* Epoch converted to a {@link LocalDateTime} in UTC timezone
*/
public static @Nullable LocalDateTime epochMicrosToLocalDateTimeUTC(final long micros) {
return micros == NULL_LONG ? null
: LocalDateTime.ofEpochSecond(micros / 1_000_000L, (int) ((micros % 1_000_000L) * MICRO),
ZoneOffset.UTC);
}

/**
* Converts milliseconds from the Epoch to a {@link LocalDateTime} in UTC timezone.
*
* @param millis milliseconds since Epoch
* @return {@code null} if the input is {@link QueryConstants#NULL_LONG}; otherwise the input milliseconds from the
* Epoch converted to a {@link LocalDateTime} in UTC timezone
*/
public static @Nullable LocalDateTime epochMillisToLocalDateTimeUTC(final long millis) {
return millis == NULL_LONG ? null
: LocalDateTime.ofEpochSecond(millis / 1_000L, (int) ((millis % 1_000L) * MILLI), ZoneOffset.UTC);
}

// endregion

// region Arithmetic
Expand Down
16 changes: 0 additions & 16 deletions engine/time/src/test/java/io/deephaven/time/TestDateTimeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -1391,10 +1391,6 @@ public void testEpochNanos() {

TestCase.assertEquals(nanos, DateTimeUtils.epochNanos(dt3));
TestCase.assertEquals(NULL_LONG, DateTimeUtils.epochNanos((ZonedDateTime) null));

final LocalDateTime ldt = LocalDateTime.ofInstant(dt2, ZoneId.of("UTC"));
TestCase.assertEquals(nanos, DateTimeUtils.epochNanosUTC(ldt));
TestCase.assertEquals(NULL_LONG, DateTimeUtils.epochNanosUTC(null));
}

public void testEpochMicros() {
Expand Down Expand Up @@ -1460,10 +1456,6 @@ public void testEpochNanosTo() {
TestCase.assertEquals(dt3, DateTimeUtils.epochNanosToZonedDateTime(nanos, TZ_JP));
TestCase.assertNull(DateTimeUtils.epochNanosToZonedDateTime(NULL_LONG, TZ_JP));
TestCase.assertNull(DateTimeUtils.epochNanosToZonedDateTime(nanos, null));

final LocalDateTime ldt = LocalDateTime.ofInstant(dt2, ZoneId.of("UTC"));
TestCase.assertEquals(ldt, DateTimeUtils.epochNanosToLocalDateTimeUTC(nanos));
TestCase.assertNull(DateTimeUtils.epochNanosToLocalDateTimeUTC(NULL_LONG));
}

public void testEpochMicrosTo() {
Expand All @@ -1479,10 +1471,6 @@ public void testEpochMicrosTo() {
TestCase.assertEquals(dt3, DateTimeUtils.epochMicrosToZonedDateTime(micros, TZ_JP));
TestCase.assertNull(DateTimeUtils.epochMicrosToZonedDateTime(NULL_LONG, TZ_JP));
TestCase.assertNull(DateTimeUtils.epochMicrosToZonedDateTime(micros, null));

final LocalDateTime ldt = LocalDateTime.ofInstant(dt2, ZoneId.of("UTC"));
TestCase.assertEquals(ldt, DateTimeUtils.epochMicrosToLocalDateTimeUTC(micros));
TestCase.assertNull(DateTimeUtils.epochMicrosToLocalDateTimeUTC(NULL_LONG));
}

public void testEpochMillisTo() {
Expand All @@ -1498,10 +1486,6 @@ public void testEpochMillisTo() {
TestCase.assertEquals(dt3, DateTimeUtils.epochMillisToZonedDateTime(millis, TZ_JP));
TestCase.assertNull(DateTimeUtils.epochMillisToZonedDateTime(NULL_LONG, TZ_JP));
TestCase.assertNull(DateTimeUtils.epochMillisToZonedDateTime(millis, null));

final LocalDateTime ldt = LocalDateTime.ofInstant(dt2, ZoneId.of("UTC"));
TestCase.assertEquals(ldt, DateTimeUtils.epochMillisToLocalDateTimeUTC(millis));
TestCase.assertNull(DateTimeUtils.epochMillisToLocalDateTimeUTC(NULL_LONG));
}

public void testEpochSecondsTo() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import io.deephaven.chunk.ChunkType;
import io.deephaven.chunk.attributes.Any;
import io.deephaven.time.DateTimeUtils;
import io.deephaven.parquet.table.util.TransferUtils;
import io.deephaven.util.QueryConstants;
import org.apache.parquet.schema.LogicalTypeAnnotation;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -79,21 +79,21 @@ private static LocalDateTime[] convertResultHelper(@NotNull final Object result,
private static final class ToLocalDateTimePageFromMillis<ATTR extends Any> extends ToLocalDateTimePage<ATTR> {
@Override
public LocalDateTime[] convertResult(@NotNull final Object result) {
return convertResultHelper(result, DateTimeUtils::epochMillisToLocalDateTimeUTC);
return convertResultHelper(result, TransferUtils::epochMillisToLocalDateTimeUTC);
}
}

private static final class ToLocalDateTimePageFromMicros<ATTR extends Any> extends ToLocalDateTimePage<ATTR> {
@Override
public LocalDateTime[] convertResult(@NotNull final Object result) {
return convertResultHelper(result, DateTimeUtils::epochMicrosToLocalDateTimeUTC);
return convertResultHelper(result, TransferUtils::epochMicrosToLocalDateTimeUTC);
}
}

private static final class ToLocalDateTimePageFromNanos<ATTR extends Any> extends ToLocalDateTimePage<ATTR> {
@Override
public LocalDateTime[] convertResult(@NotNull final Object result) {
return convertResultHelper(result, DateTimeUtils::epochNanosToLocalDateTimeUTC);
return convertResultHelper(result, TransferUtils::epochNanosToLocalDateTimeUTC);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import io.deephaven.engine.rowset.RowSequence;
import io.deephaven.engine.table.ColumnSource;
import io.deephaven.time.DateTimeUtils;
import io.deephaven.parquet.table.util.TransferUtils;
import org.jetbrains.annotations.NotNull;

import java.nio.LongBuffer;
Expand Down Expand Up @@ -38,7 +38,7 @@ void resizeBuffer(final int length) {
@Override
void copyToBuffer(@NotNull final EncodedData<LocalDateTime[]> data) {
for (final LocalDateTime t : data.encodedValues) {
buffer.put(DateTimeUtils.epochNanosUTC(t));
buffer.put(TransferUtils.epochNanosUTC(t));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import io.deephaven.chunk.attributes.Values;
import io.deephaven.engine.rowset.RowSequence;
import io.deephaven.engine.table.ColumnSource;
import io.deephaven.time.DateTimeUtils;
import io.deephaven.parquet.table.util.TransferUtils;
import org.jetbrains.annotations.NotNull;

import java.nio.LongBuffer;
Expand All @@ -31,7 +31,7 @@ final class LocalDateTimeTransfer extends GettingPrimitiveTransfer<ObjectChunk<L
void copyAllFromChunkToBuffer() {
final int chunkSize = chunk.size();
for (int chunkIdx = 0; chunkIdx < chunkSize; ++chunkIdx) {
buffer.put(DateTimeUtils.epochNanosUTC(chunk.get(chunkIdx)));
buffer.put(TransferUtils.epochNanosUTC(chunk.get(chunkIdx)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import io.deephaven.engine.primitive.iterator.CloseableIterator;
import io.deephaven.engine.rowset.RowSequence;
import io.deephaven.engine.table.ColumnSource;
import io.deephaven.time.DateTimeUtils;
import io.deephaven.parquet.table.util.TransferUtils;
import io.deephaven.vector.ObjectVector;
import org.jetbrains.annotations.NotNull;

Expand All @@ -34,7 +34,7 @@ void resizeBuffer(final int length) {
@Override
void copyToBuffer(@NotNull final EncodedData<ObjectVector<LocalDateTime>> data) {
try (final CloseableIterator<LocalDateTime> dataIterator = data.encodedValues.iterator()) {
dataIterator.forEachRemaining((LocalDateTime t) -> buffer.put(DateTimeUtils.epochNanosUTC(t)));
dataIterator.forEachRemaining((LocalDateTime t) -> buffer.put(TransferUtils.epochNanosUTC(t)));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package io.deephaven.parquet.table.util;

import io.deephaven.time.DateTimeUtils;
import io.deephaven.util.QueryConstants;
import org.jetbrains.annotations.Nullable;

import java.time.LocalDateTime;
import java.time.ZoneOffset;

/**
* Internal library with utility methods for converting data between Deephaven and Parquet.
*/
public class TransferUtils {
/**
* Returns nanoseconds from the Epoch for a {@link LocalDateTime} value in UTC timezone.
*
* @param localDateTime the local date time to compute the Epoch offset for
* @return nanoseconds since Epoch, or a NULL_LONG value if the local date time is null
*/
public static long epochNanosUTC(@Nullable final LocalDateTime localDateTime) {
if (localDateTime == null) {
return QueryConstants.NULL_LONG;
}
return DateTimeUtils.secondsToNanos(localDateTime.toEpochSecond(ZoneOffset.UTC))
+ localDateTime.toLocalTime().getNano();
}

/**
* Converts nanoseconds from the Epoch to a {@link LocalDateTime} in UTC timezone.
*
* @param nanos nanoseconds since Epoch
* @return {@code null} if the input is {@link QueryConstants#NULL_LONG}; otherwise the input nanoseconds from the
* Epoch converted to a {@link LocalDateTime} in UTC timezone
*/
public static @Nullable LocalDateTime epochNanosToLocalDateTimeUTC(final long nanos) {
return nanos == QueryConstants.NULL_LONG ? null
: LocalDateTime.ofEpochSecond(nanos / 1_000_000_000L, (int) (nanos % 1_000_000_000L), ZoneOffset.UTC);
}

/**
* Converts microseconds from the Epoch to a {@link LocalDateTime} in UTC timezone.
*
* @param micros microseconds since Epoch
* @return {@code null} if the input is {@link QueryConstants#NULL_LONG}; otherwise the input microseconds from the
* Epoch converted to a {@link LocalDateTime} in UTC timezone
*/
public static @Nullable LocalDateTime epochMicrosToLocalDateTimeUTC(final long micros) {
return micros == QueryConstants.NULL_LONG ? null
: LocalDateTime.ofEpochSecond(micros / 1_000_000L, (int) ((micros % 1_000_000L) * DateTimeUtils.MICRO),
ZoneOffset.UTC);
}

/**
* Converts milliseconds from the Epoch to a {@link LocalDateTime} in UTC timezone.
*
* @param millis milliseconds since Epoch
* @return {@code null} if the input is {@link QueryConstants#NULL_LONG}; otherwise the input milliseconds from the
* Epoch converted to a {@link LocalDateTime} in UTC timezone
*/
public static @Nullable LocalDateTime epochMillisToLocalDateTimeUTC(final long millis) {
return millis == QueryConstants.NULL_LONG ? null
: LocalDateTime.ofEpochSecond(millis / 1_000L, (int) ((millis % 1_000L) * DateTimeUtils.MILLI),
ZoneOffset.UTC);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2016-2022 Deephaven Data Labs and Patent Pending
*/
package io.deephaven.parquet.table;

import io.deephaven.parquet.table.util.TransferUtils;
import io.deephaven.time.DateTimeUtils;
import io.deephaven.util.QueryConstants;
import junit.framework.TestCase;
import org.junit.Test;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

final public class TestTransferUtils {

@Test
public void testEpochNanosUTC() {
final long nanos = 123456789123456789L;
final Instant dt2 = Instant.ofEpochSecond(0, nanos);
final LocalDateTime ldt = LocalDateTime.ofInstant(dt2, ZoneId.of("UTC"));
TestCase.assertEquals(nanos, TransferUtils.epochNanosUTC(ldt));
TestCase.assertEquals(QueryConstants.NULL_LONG, TransferUtils.epochNanosUTC(null));
}

@Test
public void testEpochNanosTo() {
final long nanos = 123456789123456789L;
final Instant dt2 = Instant.ofEpochSecond(0, nanos);
final LocalDateTime ldt = LocalDateTime.ofInstant(dt2, ZoneId.of("UTC"));
TestCase.assertEquals(ldt, TransferUtils.epochNanosToLocalDateTimeUTC(nanos));
TestCase.assertNull(TransferUtils.epochNanosToLocalDateTimeUTC(QueryConstants.NULL_LONG));
}

@Test
public void testEpochMicrosTo() {
long nanos = 123456789123456789L;
final long micros = DateTimeUtils.nanosToMicros(nanos);
nanos = DateTimeUtils.microsToNanos(micros);
final Instant dt2 = Instant.ofEpochSecond(0, nanos);
final LocalDateTime ldt = LocalDateTime.ofInstant(dt2, ZoneId.of("UTC"));
TestCase.assertEquals(ldt, TransferUtils.epochMicrosToLocalDateTimeUTC(micros));
TestCase.assertNull(TransferUtils.epochMicrosToLocalDateTimeUTC(QueryConstants.NULL_LONG));
}

@Test
public void testEpochMillisTo() {
long nanos = 123456789123456789L;
final long millis = DateTimeUtils.nanosToMillis(nanos);
nanos = DateTimeUtils.millisToNanos(millis);
final Instant dt2 = Instant.ofEpochSecond(0, nanos);
final LocalDateTime ldt = LocalDateTime.ofInstant(dt2, ZoneId.of("UTC"));
TestCase.assertEquals(ldt, TransferUtils.epochMillisToLocalDateTimeUTC(millis));
TestCase.assertNull(TransferUtils.epochMillisToLocalDateTimeUTC(QueryConstants.NULL_LONG));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ public static void main(String[] args) throws IOException {
replaceAll(PARQUET_INSTANT_VECTOR_TRANSFER_PATH, PARQUET_TIME_VECTOR_TRANSFER_PATH, null, NO_EXCEPTIONS, pairs);

pairs = new String[][] {
{"io.deephaven.time.DateTimeUtils", "io.deephaven.parquet.table.util.TransferUtils"},
{"InstantArrayTransfer", "LocalDateTimeArrayTransfer"},
{"InstantVectorTransfer", "LocalDateTimeVectorTransfer"},
{"DateTimeUtils.epochNanos", "DateTimeUtils.epochNanosUTC"},
{"DateTimeUtils.epochNanos", "TransferUtils.epochNanosUTC"},
{"Instant", "LocalDateTime"}
};
replaceAll(PARQUET_INSTANT_ARRAY_TRANSFER_PATH, PARQUET_LOCAL_DATE_TIME_ARRAY_TRANSFER_PATH, null,
Expand All @@ -80,9 +81,10 @@ public static void main(String[] args) throws IOException {
NO_EXCEPTIONS, pairs);

pairs = new String[][] {
{"io.deephaven.time.DateTimeUtils", "io.deephaven.parquet.table.util.TransferUtils"},
{"TimeTransfer", "LocalDateTimeTransfer"},
{"LocalTime", "LocalDateTime"},
{"DateTimeUtils.nanosOfDay", "DateTimeUtils.epochNanosUTC"}
{"DateTimeUtils.nanosOfDay", "TransferUtils.epochNanosUTC"}
};
replaceAll(PARQUET_TIME_TRANSFER_PATH, PARQUET_LOCAL_DATE_TIME_TRANSFER_PATH, null, NO_EXCEPTIONS, pairs);

Expand Down
Loading