Embulk uses only {@link java.time.Instant} as its internal timestamp representation.
*
*
@@ -679,6 +687,7 @@ private void appendYearWithoutCentury(
*
* On the other hand, Embulk's legacy {@code TimestampFormatter} has used {@code org.jruby.util.RubyDateFormat}
* directly. Unlike just {@code Time.strptime}, {@code RubyDateFormat} formats {@code "%Z"} into short names.
+ *
* @see RubyDateFormat#compilePattern
* @see RubyDateFormat#format
*
@@ -737,6 +746,8 @@ private void appendTimeZoneName(
builder.append("");
}
break;
+ default:
+ // Pass-through.
}
}
@@ -872,6 +883,7 @@ private void appendLongFormatted(
*
* @see iso8601wknum
*/
+ @SuppressWarnings("checkstyle:LeftCurly")
private static int calculateIso8601WeekNumber(final TemporalAccessor temporal) {
final int jan1DayOfWeek = calculateJan1DayOfWeek(temporal);
diff --git a/src/main/java/org/embulk/util/rubytime/Parsed.java b/src/main/java/org/embulk/util/rubytime/Parsed.java
index 24684e8..974bd17 100644
--- a/src/main/java/org/embulk/util/rubytime/Parsed.java
+++ b/src/main/java/org/embulk/util/rubytime/Parsed.java
@@ -16,13 +16,7 @@
package org.embulk.util.rubytime;
-import java.time.DateTimeException;
-import java.time.Instant;
-import java.time.OffsetDateTime;
import java.time.Period;
-import java.time.ZoneId;
-import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAccessor;
diff --git a/src/main/java/org/embulk/util/rubytime/ParserWithContext.java b/src/main/java/org/embulk/util/rubytime/ParserWithContext.java
index fe66e1b..28f1b7b 100644
--- a/src/main/java/org/embulk/util/rubytime/ParserWithContext.java
+++ b/src/main/java/org/embulk/util/rubytime/ParserWithContext.java
@@ -16,10 +16,10 @@
package org.embulk.util.rubytime;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import java.time.Instant;
import java.time.Year;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
final class ParserWithContext {
ParserWithContext(final CharSequence text) {
@@ -717,7 +717,7 @@ private static int toInt(final char c) {
* @see ext/date/date_strptime.c
*/
private static final Pattern ZONE_PARSE_REGEX =
- Pattern.compile("\\A("
+ Pattern.compile("\\A("
+ "(?:gmt|utc?)?[-+]\\d+(?:[,.:]\\d+(?::\\d+)?)?"
+ "|(?-i:[[\\p{Alpha}].\\s]+)(?:standard|daylight)\\s+time\\b"
+ "|(?-i:[[\\p{Alpha}]]+)(?:\\s+dst)?\\b"
diff --git a/src/main/java/org/embulk/util/rubytime/RubyDateTimeParsedElementsQuery.java b/src/main/java/org/embulk/util/rubytime/RubyDateTimeParsedElementsQuery.java
index dd2bb1d..b531622 100644
--- a/src/main/java/org/embulk/util/rubytime/RubyDateTimeParsedElementsQuery.java
+++ b/src/main/java/org/embulk/util/rubytime/RubyDateTimeParsedElementsQuery.java
@@ -63,6 +63,7 @@ public final class RubyDateTimeParsedElementsQuery implements TemporalQuery
*/
+ @SuppressWarnings("checkstyle:LineLength")
public static interface FractionalSecondConverter {
/**
* Converts fractional second, a pair of an integer part and a fraction part, into an arbitrary {@link java.lang.Object} to be stored in the result {@link java.util.Map} of {@link RubyDateTimeParsedElementsQuery}.
@@ -324,21 +325,21 @@ private Map build() {
private static final MillisecondToBigDecimalConverter MILLISECOND_TO_BIG_DECIMAL;
private static final StringAsIs STRING_AS_IS;
- private final static class FractionalSecondToBigDecimalConverter implements FractionalSecondConverter {
+ private static final class FractionalSecondToBigDecimalConverter implements FractionalSecondConverter {
@Override
public Object convertFractionalSecond(final long integer, final int nano) {
return BigDecimal.valueOf(integer).add(BigDecimal.valueOf(nano, 9));
}
}
- private final static class MillisecondToBigDecimalConverter implements MillisecondConverter {
+ private static final class MillisecondToBigDecimalConverter implements MillisecondConverter {
@Override
public Object convertMillisecond(final long millisecond) {
return BigDecimal.valueOf(millisecond, 3);
}
}
- private final static class StringAsIs implements MapKeyConverter {
+ private static final class StringAsIs implements MapKeyConverter {
@Override
public String convertMapKey(final String mapKey) {
return mapKey;
diff --git a/src/main/java/org/embulk/util/rubytime/RubyDateTimeZones.java b/src/main/java/org/embulk/util/rubytime/RubyDateTimeZones.java
index f9add52..3b2cabb 100644
--- a/src/main/java/org/embulk/util/rubytime/RubyDateTimeZones.java
+++ b/src/main/java/org/embulk/util/rubytime/RubyDateTimeZones.java
@@ -55,6 +55,7 @@
* irb(main):008:0> Time.strptime("2017-12-31 12:34:56 PST", "%Y-%m-%d %H:%M:%S %z")
* => 2017-12-31 12:34:56 -0800}
*/
+@SuppressWarnings("checkstyle:Indentation")
public final class RubyDateTimeZones {
private RubyDateTimeZones() {
// No instantiation.
@@ -142,6 +143,7 @@ static int mapZoneNameToOffsetInSecondsForTesting(final String zone) {
*
* @see the latter part of date_zone_to_diff
*/
+ @SuppressWarnings("checkstyle:IllegalTokenText")
private static String normalize(final String original) {
final int originalLength = original.length();
StringBuilder normalized = null;
@@ -550,6 +552,7 @@ private static int mapZoneNameToOffsetInSeconds(final String zone) {
case "WEST ASIA": return 18000;
case "WEST PACIFIC": return 36000;
case "YAKUTSK": return 32400;
+ default: // Pass-through.
}
return Integer.MIN_VALUE;
}
diff --git a/src/main/java/org/embulk/util/rubytime/RubyTemporalQueries.java b/src/main/java/org/embulk/util/rubytime/RubyTemporalQueries.java
index 1fcb43a..ac59a9a 100644
--- a/src/main/java/org/embulk/util/rubytime/RubyTemporalQueries.java
+++ b/src/main/java/org/embulk/util/rubytime/RubyTemporalQueries.java
@@ -17,7 +17,6 @@
package org.embulk.util.rubytime;
import java.time.temporal.TemporalAccessor;
-import java.time.temporal.TemporalField;
import java.time.temporal.TemporalQuery;
/**
diff --git a/src/main/java/org/embulk/util/rubytime/RubyTemporalQueryResolver.java b/src/main/java/org/embulk/util/rubytime/RubyTemporalQueryResolver.java
index 175d044..496a51c 100644
--- a/src/main/java/org/embulk/util/rubytime/RubyTemporalQueryResolver.java
+++ b/src/main/java/org/embulk/util/rubytime/RubyTemporalQueryResolver.java
@@ -21,6 +21,8 @@
*/
public interface RubyTemporalQueryResolver {
String getOriginalText();
+
String getZone();
+
String getLeftover();
}
diff --git a/src/main/java/org/embulk/util/rubytime/RubyTimeZones.java b/src/main/java/org/embulk/util/rubytime/RubyTimeZones.java
index 5990b83..a33af45 100644
--- a/src/main/java/org/embulk/util/rubytime/RubyTimeZones.java
+++ b/src/main/java/org/embulk/util/rubytime/RubyTimeZones.java
@@ -58,6 +58,7 @@
* irb(main):008:0> Time.strptime("2017-12-31 12:34:56 PST", "%Y-%m-%d %H:%M:%S %z")
* => 2017-12-31 12:34:56 -0800}
*/
+@SuppressWarnings("checkstyle:Indentation")
public final class RubyTimeZones {
private RubyTimeZones() {
// No instantiation.
@@ -105,19 +106,19 @@ private static boolean matchesOffsetRepresentation(final String zone) {
case 3: // +HH
return Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2));
case 5: // +HHMM
- return Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2)) &&
- Character.isDigit(zone.charAt(3)) && Character.isDigit(zone.charAt(4));
+ return Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2))
+ && Character.isDigit(zone.charAt(3)) && Character.isDigit(zone.charAt(4));
case 6: // +HH:MM
- return Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2)) &&
- zone.charAt(3) == ':' && Character.isDigit(zone.charAt(4)) && Character.isDigit(zone.charAt(5));
+ return Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2))
+ && zone.charAt(3) == ':' && Character.isDigit(zone.charAt(4)) && Character.isDigit(zone.charAt(5));
case 7: // +HHMMSS
- return Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2)) &&
- Character.isDigit(zone.charAt(3)) && Character.isDigit(zone.charAt(4)) &&
- Character.isDigit(zone.charAt(5)) && Character.isDigit(zone.charAt(6));
+ return Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2))
+ && Character.isDigit(zone.charAt(3)) && Character.isDigit(zone.charAt(4))
+ && Character.isDigit(zone.charAt(5)) && Character.isDigit(zone.charAt(6));
case 9: // +HH:MM:SS
- return Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2)) &&
- zone.charAt(3) == ':' && Character.isDigit(zone.charAt(4)) && Character.isDigit(zone.charAt(5)) &&
- zone.charAt(6) == ':' && Character.isDigit(zone.charAt(7)) && Character.isDigit(zone.charAt(8));
+ return Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2))
+ && zone.charAt(3) == ':' && Character.isDigit(zone.charAt(4)) && Character.isDigit(zone.charAt(5))
+ && zone.charAt(6) == ':' && Character.isDigit(zone.charAt(7)) && Character.isDigit(zone.charAt(8));
default:
return false;
}
@@ -131,37 +132,39 @@ private static int extractOffsetRepresentation(final String zone) {
}
return Integer.MIN_VALUE;
case 5: // +HHMM
- if (Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2)) &&
- Character.isDigit(zone.charAt(3)) && Character.isDigit(zone.charAt(4))) {
- return (Character.digit(zone.charAt(1), 10) * 10 + Character.digit(zone.charAt(2), 10)) * 3600 +
- (Character.digit(zone.charAt(3), 10) * 10 + Character.digit(zone.charAt(4), 10)) * 60;
+ if (Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2))
+ && Character.isDigit(zone.charAt(3)) && Character.isDigit(zone.charAt(4))) {
+ return (Character.digit(zone.charAt(1), 10) * 10 + Character.digit(zone.charAt(2), 10)) * 3600
+ + (Character.digit(zone.charAt(3), 10) * 10 + Character.digit(zone.charAt(4), 10)) * 60;
}
return Integer.MIN_VALUE;
case 6: // +HH:MM
- if (Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2)) &&
- zone.charAt(3) == ':' && Character.isDigit(zone.charAt(4)) && Character.isDigit(zone.charAt(5))) {
- return (Character.digit(zone.charAt(1), 10) * 10 + Character.digit(zone.charAt(2), 10)) * 3600 +
- (Character.digit(zone.charAt(4), 10) * 10 + Character.digit(zone.charAt(5), 10)) * 60;
+ if (Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2))
+ && zone.charAt(3) == ':' && Character.isDigit(zone.charAt(4)) && Character.isDigit(zone.charAt(5))) {
+ return (Character.digit(zone.charAt(1), 10) * 10 + Character.digit(zone.charAt(2), 10)) * 3600
+ + (Character.digit(zone.charAt(4), 10) * 10 + Character.digit(zone.charAt(5), 10)) * 60;
}
return Integer.MIN_VALUE;
case 7: // +HHMMSS
- if (Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2)) &&
- Character.isDigit(zone.charAt(3)) && Character.isDigit(zone.charAt(4)) &&
- Character.isDigit(zone.charAt(5)) && Character.isDigit(zone.charAt(6))) {
- return (Character.digit(zone.charAt(1), 10) * 10 + Character.digit(zone.charAt(2), 10)) * 3600 +
- (Character.digit(zone.charAt(3), 10) * 10 + Character.digit(zone.charAt(4), 10)) * 60 +
- (Character.digit(zone.charAt(5), 10) * 10 + Character.digit(zone.charAt(6), 10));
+ if (Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2))
+ && Character.isDigit(zone.charAt(3)) && Character.isDigit(zone.charAt(4))
+ && Character.isDigit(zone.charAt(5)) && Character.isDigit(zone.charAt(6))) {
+ return (Character.digit(zone.charAt(1), 10) * 10 + Character.digit(zone.charAt(2), 10)) * 3600
+ + (Character.digit(zone.charAt(3), 10) * 10 + Character.digit(zone.charAt(4), 10)) * 60
+ + (Character.digit(zone.charAt(5), 10) * 10 + Character.digit(zone.charAt(6), 10));
}
return Integer.MIN_VALUE;
case 9: // +HH:MM:SS
- if (Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2)) &&
- zone.charAt(3) == ':' && Character.isDigit(zone.charAt(4)) && Character.isDigit(zone.charAt(5)) &&
- zone.charAt(6) == ':' && Character.isDigit(zone.charAt(7)) && Character.isDigit(zone.charAt(8))) {
- return (Character.digit(zone.charAt(1), 10) * 10 + Character.digit(zone.charAt(2), 10)) * 3600 +
- (Character.digit(zone.charAt(4), 10) * 10 + Character.digit(zone.charAt(5), 10)) * 60 +
- (Character.digit(zone.charAt(7), 10) * 10 + Character.digit(zone.charAt(8), 10));
+ if (Character.isDigit(zone.charAt(1)) && Character.isDigit(zone.charAt(2))
+ && zone.charAt(3) == ':' && Character.isDigit(zone.charAt(4)) && Character.isDigit(zone.charAt(5))
+ && zone.charAt(6) == ':' && Character.isDigit(zone.charAt(7)) && Character.isDigit(zone.charAt(8))) {
+ return (Character.digit(zone.charAt(1), 10) * 10 + Character.digit(zone.charAt(2), 10)) * 3600
+ + (Character.digit(zone.charAt(4), 10) * 10 + Character.digit(zone.charAt(5), 10)) * 60
+ + (Character.digit(zone.charAt(7), 10) * 10 + Character.digit(zone.charAt(8), 10));
}
return Integer.MIN_VALUE;
+ default:
+ // Pass-through.
}
return Integer.MIN_VALUE;
}
@@ -230,6 +233,7 @@ private static ZoneOffset mapZoneNametoZoneOffset(final String name) {
case "W": return OFFSET_N_10;
case "X": return OFFSET_N_11;
case "Y": return OFFSET_N_12;
+ default: // Pass-through.
}
return null;
}
diff --git a/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeFormatterFormat.java b/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeFormatterFormat.java
index 0ceb150..23cbb1c 100644
--- a/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeFormatterFormat.java
+++ b/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeFormatterFormat.java
@@ -16,18 +16,8 @@
package org.embulk.util.rubytime;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
-
-import java.time.DateTimeException;
-import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
-import java.time.format.DateTimeParseException;
-import java.time.temporal.ChronoField;
-import java.time.temporal.TemporalAccessor;
import org.junit.jupiter.api.Test;
/**
diff --git a/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeFormatterParse.java b/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeFormatterParse.java
index 00a47c1..7d2b828 100644
--- a/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeFormatterParse.java
+++ b/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeFormatterParse.java
@@ -18,7 +18,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.time.DateTimeException;
@@ -429,7 +428,7 @@ public void testLarge() {
assertParsedTime("-31556889832780799", "%s", Instant.ofEpochSecond(-31556889832780799L, 0));
assertParsedTime("-31556889832780800", "%s", Instant.ofEpochSecond(-31556889832780800L, 0)); // Sure
- assertParsedTime( "-31556889864403199", "%s", Instant.ofEpochSecond(-31556889864403199L, 0));
+ assertParsedTime("-31556889864403199", "%s", Instant.ofEpochSecond(-31556889864403199L, 0));
assertFailToParse("-31556889864403200", "%s"); // To succeed? -(Instant.MAX + 1)
assertFailToParse("-31557014135596799", "%s"); // To succeed? -999999999-01-01T00:00:00
assertFailToParse("-31557014167219200", "%s"); // To succeed? Instant.MIN.
diff --git a/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeZones.java b/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeZones.java
index 9edcb77..7f7bce7 100644
--- a/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeZones.java
+++ b/src/test/java/org/embulk/util/rubytime/TestRubyDateTimeZones.java
@@ -54,13 +54,19 @@ public void testNormalize() {
public void testParseOffsetTooLongFraction() {
assertThrows(
NumberFormatException.class,
- () -> { RubyDateTimeZones.parseOffsetForTesting("UTC+19.001953125"); });
+ () -> {
+ RubyDateTimeZones.parseOffsetForTesting("UTC+19.001953125");
+ });
assertThrows(
NumberFormatException.class,
- () -> { RubyDateTimeZones.parseOffsetForTesting("UTC+19.0009765625"); });
+ () -> {
+ RubyDateTimeZones.parseOffsetForTesting("UTC+19.0009765625");
+ });
assertThrows(
NumberFormatException.class,
- () -> { RubyDateTimeZones.parseOffsetForTesting("UTC+19.0000111111"); });
+ () -> {
+ RubyDateTimeZones.parseOffsetForTesting("UTC+19.0000111111");
+ });
}
@Test
@@ -285,7 +291,7 @@ public void testMatchingZoneTab(final String name, final String expectedOffsetIn
"!",
"?",
"*",
- })
+ })
public void testUnmatchingZoneTab(final String name) {
assertEquals(Integer.MIN_VALUE, RubyDateTimeZones.mapZoneNameToOffsetInSecondsForTesting(name.toUpperCase()));
}