[
https://issues.apache.org/jira/browse/PARQUET-1436?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=16639525#comment-16639525
]
ASF GitHub Bot commented on PARQUET-1436:
-
zivanfi closed pull request #529: PARQUET-1436: TimestampMicrosStringifier
shows wrong microseconds for timestamps before 1970
URL: https://github.com/apache/parquet-mr/pull/529
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/parquet-column/src/main/java/org/apache/parquet/schema/PrimitiveStringifier.java
b/parquet-column/src/main/java/org/apache/parquet/schema/PrimitiveStringifier.java
index 3c3417e0d..03786ed73 100644
---
a/parquet-column/src/main/java/org/apache/parquet/schema/PrimitiveStringifier.java
+++
b/parquet-column/src/main/java/org/apache/parquet/schema/PrimitiveStringifier.java
@@ -29,8 +29,9 @@
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.text.SimpleDateFormat;
-import java.util.TimeZone;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
import javax.naming.OperationNotSupportedException;
@@ -243,80 +244,68 @@ String stringifyNotNull(Binary value) {
};
private static class DateStringifier extends PrimitiveStringifier {
-private final SimpleDateFormat formatter;
-private static final TimeZone UTC = TimeZone.getTimeZone("utc");
+private final DateTimeFormatter formatter;
private DateStringifier(String name, String format) {
super(name);
- formatter = new SimpleDateFormat(format);
- formatter.setTimeZone(UTC);
+ formatter = DateTimeFormatter.ofPattern(format).withZone(ZoneOffset.UTC);
}
@Override
public String stringify(int value) {
- return toFormattedString(toMillis(value));
+ return toFormattedString(getInstant(value));
}
@Override
public String stringify(long value) {
- return toFormattedString(toMillis(value));
+ return toFormattedString(getInstant(value));
}
-private String toFormattedString(long millis) {
- return formatter.format(millis);
+private String toFormattedString(Instant instant) {
+ return formatter.format(instant);
}
-long toMillis(int value) {
+Instant getInstant(int value) {
// throw the related unsupported exception
super.stringify(value);
- return 0;
+ return null;
}
-long toMillis(long value) {
+Instant getInstant(long value) {
// throw the related unsupported exception
super.stringify(value);
- return 0;
+ return null;
}
}
static final PrimitiveStringifier DATE_STRINGIFIER = new
DateStringifier("DATE_STRINGIFIER", "-MM-dd") {
@Override
-long toMillis(int value) {
- return TimeUnit.DAYS.toMillis(value);
+Instant getInstant(int value) {
+ return Instant.ofEpochMilli(TimeUnit.DAYS.toMillis(value));
};
};
static final PrimitiveStringifier TIMESTAMP_MILLIS_STRINGIFIER = new
DateStringifier(
"TIMESTAMP_MILLIS_STRINGIFIER", "-MM-dd'T'HH:mm:ss.SSS") {
@Override
-long toMillis(long value) {
- return value;
+Instant getInstant(long value) {
+ return Instant.ofEpochMilli(value);
}
};
static final PrimitiveStringifier TIMESTAMP_MICROS_STRINGIFIER = new
DateStringifier(
- "TIMESTAMP_MICROS_STRINGIFIER", "-MM-dd'T'HH:mm:ss.SSS") {
+ "TIMESTAMP_MICROS_STRINGIFIER", "-MM-dd'T'HH:mm:ss.SS") {
@Override
-public String stringify(long value) {
- return super.stringify(value) + String.format("%03d", Math.abs(value %
1000));
-}
-
-@Override
-long toMillis(long value) {
- return value / 1000;
+Instant getInstant(long value) {
+ return Instant.ofEpochSecond(MICROSECONDS.toSeconds(value),
MICROSECONDS.toNanos(value % SECONDS.toMicros(1)));
}
};
static final PrimitiveStringifier TIMESTAMP_NANOS_STRINGIFIER = new
DateStringifier(
-"TIMESTAMP_NANOS_STRINGIFIER", "-MM-dd'T'HH:mm:ss.SSS") {
-@Override
-public String stringify(long value) {
- return super.stringify(value) + String.format("%06d", Math.abs(value %
1_000_000));
-}
-
+"TIMESTAMP_NANOS_STRINGIFIER", "-MM-dd'T'HH:mm:ss.S") {
@Override
-long toMillis(long value) {
- return value / 1_000_000;
+Instant getInstant(long value) {
+ return Instant.ofEpochSecond(NANOSECONDS.toSeconds(value),
NANOSECONDS.toNanos(value % SECONDS.toNanos(1)));
}
};
diff --git
a/parquet-column/src/test/java/org/apache/parquet/schema/TestPrimitiveStringifier.java