rdblue commented on code in PR #11904: URL: https://github.com/apache/iceberg/pull/11904#discussion_r1917308787
########## parquet/src/main/java/org/apache/iceberg/data/parquet/GenericParquetReaders.java: ########## @@ -92,4 +151,124 @@ protected void set(Record struct, int pos, Object value) { struct.set(pos, value); } } + + private static final OffsetDateTime EPOCH = Instant.ofEpochSecond(0).atOffset(ZoneOffset.UTC); + private static final LocalDate EPOCH_DAY = EPOCH.toLocalDate(); + + private static class DateReader extends ParquetValueReaders.PrimitiveReader<LocalDate> { + private DateReader(ColumnDescriptor desc) { + super(desc); + } + + @Override + public LocalDate read(LocalDate reuse) { + return EPOCH_DAY.plusDays(column.nextInteger()); + } + } + + private static class TimestampReader extends ParquetValueReaders.PrimitiveReader<LocalDateTime> { + private TimestampReader(ColumnDescriptor desc) { + super(desc); + } + + @Override + public LocalDateTime read(LocalDateTime reuse) { + return EPOCH.plus(column.nextLong(), ChronoUnit.MICROS).toLocalDateTime(); + } + } + + private static class TimestampMillisReader + extends ParquetValueReaders.PrimitiveReader<LocalDateTime> { + private TimestampMillisReader(ColumnDescriptor desc) { + super(desc); + } + + @Override + public LocalDateTime read(LocalDateTime reuse) { + return EPOCH.plus(column.nextLong() * 1000, ChronoUnit.MICROS).toLocalDateTime(); + } + } + + private static class TimestampInt96Reader + extends ParquetValueReaders.PrimitiveReader<OffsetDateTime> { + private static final long UNIX_EPOCH_JULIAN = 2_440_588L; + + private TimestampInt96Reader(ColumnDescriptor desc) { + super(desc); + } + + @Override + public OffsetDateTime read(OffsetDateTime reuse) { + final ByteBuffer byteBuffer = + column.nextBinary().toByteBuffer().order(ByteOrder.LITTLE_ENDIAN); + final long timeOfDayNanos = byteBuffer.getLong(); + final int julianDay = byteBuffer.getInt(); + + return Instant.ofEpochMilli(TimeUnit.DAYS.toMillis(julianDay - UNIX_EPOCH_JULIAN)) + .plusNanos(timeOfDayNanos) + .atOffset(ZoneOffset.UTC); + } + } + + private static class TimestamptzReader + extends ParquetValueReaders.PrimitiveReader<OffsetDateTime> { + private TimestamptzReader(ColumnDescriptor desc) { + super(desc); + } + + @Override + public OffsetDateTime read(OffsetDateTime reuse) { + return EPOCH.plus(column.nextLong(), ChronoUnit.MICROS); + } + } + + private static class TimestamptzMillisReader + extends ParquetValueReaders.PrimitiveReader<OffsetDateTime> { + private TimestamptzMillisReader(ColumnDescriptor desc) { + super(desc); + } + + @Override + public OffsetDateTime read(OffsetDateTime reuse) { + return EPOCH.plus(column.nextLong() * 1000, ChronoUnit.MICROS); + } + } + + private static class TimeMillisReader extends ParquetValueReaders.PrimitiveReader<LocalTime> { + private TimeMillisReader(ColumnDescriptor desc) { + super(desc); + } + + @Override + public LocalTime read(LocalTime reuse) { + return LocalTime.ofNanoOfDay(column.nextLong() * 1000000L); Review Comment: Millisecond time must be stored as an INT32 according to the spec, so I think this should call `column.nextLong` instead. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org For additional commands, e-mail: issues-h...@iceberg.apache.org