sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/03: Accept parsing timezone name (e.g. "UTC") in addition of timezone offsets. Add links in javadoc and fix the value shown in an error message.
Date Thu, 22 Oct 2020 14:14:09 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 5f774e8869329061f51868403ea8be97102d65c4
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Wed Oct 21 12:36:48 2020 +0200

    Accept parsing timezone name (e.g. "UTC") in addition of timezone offsets.
    Add links in javadoc and fix the value shown in an error message.
---
 .../org/apache/sis/coverage/grid/GridExtent.java   |  4 ++-
 .../java/org/apache/sis/referencing/CommonCRS.java |  7 +++-
 .../sis/internal/util/StandardDateFormat.java      | 42 +++++++++++-----------
 .../sis/internal/util/StandardDateFormatTest.java  |  4 ++-
 4 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
index 7652d5b..40696b9 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java
@@ -824,8 +824,10 @@ public class GridExtent implements GridEnvelope, LenientComparable, Serializable
                 if (count < s) {
                     selected[count++] = i;
                 } else {
+                    long size = high - low;
+                    if (size != -1) size++;     // When interpreted as unsigned long, -1
is the maximal value.
                     throw new SubspaceNotSpecifiedException(Resources.format(Resources.Keys.NoNDimensionalSlice_3,
-                                    s, getAxisIdentification(i,i), Numerics.toUnsignedDouble(high
- low)));
+                                s, getAxisIdentification(i,i), Numerics.toUnsignedDouble(size)));
                 }
             }
         }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
index aee861f..e064e18 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
@@ -1528,7 +1528,10 @@ public enum CommonCRS {
      *
      * @author  Martin Desruisseaux (Geomatys)
      * @version 1.0
-     * @since   0.4
+     *
+     * @see Engineering#TIME
+     *
+     * @since 0.4
      * @module
      */
     public enum Temporal {
@@ -1862,6 +1865,8 @@ public enum CommonCRS {
          *     <td>{@link AxisDirection#FUTURE}</td></tr>
          *   <tr><th>Unit:</th> <td>{@link Units#SECOND}</td></tr>
          * </table></blockquote>
+         *
+         * @see Temporal
          */
         TIME(new DefaultEngineeringDatum(singletonMap(EngineeringDatum.NAME_KEY, "Time")));
 
diff --git a/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java
b/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java
index f058773..284bab4 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/internal/util/StandardDateFormat.java
@@ -61,7 +61,7 @@ import org.apache.sis.util.CharSequences;
  * but nevertheless allows to specify a timezone.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.1
  * @since   0.6
  * @module
  */
@@ -87,6 +87,8 @@ public final class StandardDateFormat extends DateFormat {
      * The thread-safe instance to use for reading and formatting dates.
      * Only the year is mandatory, all other fields are optional at parsing time.
      * However all fields are written, including milliseconds at formatting time.
+     *
+     * @see #parseInstantUTC(CharSequence, int, int)
      */
     public static final DateTimeFormatter FORMAT = new DateTimeFormatterBuilder()
             .parseLenient()                    // For allowing fields with one digit instead
of two.
@@ -98,16 +100,18 @@ public final class StandardDateFormat extends DateFormat {
             .optionalStart().appendLiteral(':').appendValue(ChronoField.SECOND_OF_MINUTE,
2)
                                                .appendFraction(ChronoField.MILLI_OF_SECOND,
3, 3, true)
             .optionalEnd().optionalEnd().optionalEnd()    // Move back to the optional block
of HOUR_OF_DAY.
-//          .optionalStart().appendOffset("+H:MM:ss", "Z")
-            .optionalStart().appendOffsetId()               // TODO: replace by above line
after we migrated to JDK10.
+            .optionalStart().appendZoneOrOffsetId()
             .toFormatter(Locale.ROOT);
 
     /**
      * The kinds of objects to get from calls to {@link #parseBest(CharSequence)}, in preference
order.
      * The time is converted to UTC timezone if possible.
      *
-     * Tip: if we want to preserve the timezone instead than converting to UTC, we could
try replacing
-     * {@code Instant::from} by {@code ZonedDateTime::from, OffsetDateTime::from}.
+     * <div class="note"><b>Tip:</b>
+     * if we want to preserve the timezone instead than converting to UTC, we could try replacing
+     * {@code Instant::from} by {@code ZonedDateTime::from, OffsetDateTime::from}.</div>
+     *
+     * @see #parseInstantUTC(CharSequence, int, int)
      */
     private static TemporalQuery<?>[] QUERIES = {
         Instant::from, LocalDateTime::from, LocalDate::from
@@ -175,18 +179,18 @@ public final class StandardDateFormat extends DateFormat {
      * @return sub-sequence of {@code text} from {@code lower} to {@code upper}, potentially
modified.
      */
     static CharSequence toISO(CharSequence text, int lower, int upper) {
-        boolean isCopied = false;
         lower = CharSequences.skipLeadingWhitespaces (text, lower, upper);
         upper = CharSequences.skipTrailingWhitespaces(text, lower, upper);
+        StringBuilder buffer = null;
         int cp = 0;   // Non-whitespace character from previous iteration.
         for (int i = upper; i > lower;) {
             int c = Character.codePointBefore(text, i);
             int n = Character.charCount(c);
 replace:    if (Character.isWhitespace(c)) {
                 /*
-                 * Found whitespaces from 'i' inclusive (after computation below) to 'end'
exclusive.
+                 * Found whitespaces from `i` inclusive (after computation below) to `end`
exclusive.
                  * If no concurrent change, i > lower because text.charAt(lower) is not
a whitespace.
-                 * Set 'c' to the character before whitespaces. 'cp' is the character after
spaces.
+                 * Set `c` to the character before whitespaces. `cp` is the character after
spaces.
                  */
                 int end = i;
                 i = CharSequences.skipTrailingWhitespaces(text, lower, i - n);
@@ -196,27 +200,23 @@ replace:    if (Character.isWhitespace(c)) {
                 if (Character.isDigit(cp) && Character.isDigit(c)) {
                     /*
                      * If the character before and after whitespaces are digits, maybe we
have
-                     * the separation between date and timezone. Use ':' position as a check.
+                     * the separation between date and timezone. Use `:` position as a check.
                      */
                     isDateTimeSeparator = CharSequences.indexOf(text, ':', lower, upper)
> end;
                     if (!isDateTimeSeparator) break replace;               // Skip replacement.
                 }
-                final StringBuilder b;
-                if (isCopied) {
-                    b = (StringBuilder) text;
-                } else {
-                    text = b = new StringBuilder(upper - lower).append(text, lower, upper);
-                    i       -= lower;
-                    end     -= lower;
-                    lower    = 0;
-                    isCopied = true;
+                if (buffer == null) {
+                    text  = buffer = new StringBuilder(upper - lower).append(text, lower,
upper);
+                    i    -= lower;
+                    end  -= lower;
+                    lower = 0;
                 }
                 if (isDateTimeSeparator) {
-                    b.replace(i, end, "T");
+                    buffer.replace(i, end, "T");
                 } else {
-                    b.delete(i, end);
+                    buffer.delete(i, end);
                 }
-                upper = b.length();
+                upper = buffer.length();
             }
             i -= n;
             cp = c;
diff --git a/core/sis-utility/src/test/java/org/apache/sis/internal/util/StandardDateFormatTest.java
b/core/sis-utility/src/test/java/org/apache/sis/internal/util/StandardDateFormatTest.java
index be4386d..58acc1e 100644
--- a/core/sis-utility/src/test/java/org/apache/sis/internal/util/StandardDateFormatTest.java
+++ b/core/sis-utility/src/test/java/org/apache/sis/internal/util/StandardDateFormatTest.java
@@ -34,7 +34,7 @@ import static org.junit.Assert.*;
  * Tests the {@link StandardDateFormat} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.1
  * @since   0.6
  * @module
  */
@@ -60,6 +60,7 @@ public final strictfp class StandardDateFormatTest extends TestCase {
         assertSame  ("2005-09-22",                toISO("2005-09-22"));
         assertEquals("2005-09-22T04:30:15",       toISO("  2005-09-22   04 : 30 : 15 "));
         assertEquals("1992-10-8T15:15:42.5-6:00", toISO("1992-10-8 15:15:42.5 -6:00"));
+        assertEquals("1960-01-01T00:00:00Z",      toISO("1960-01-01 00:00:00 Z"));
     }
 
     /**
@@ -129,6 +130,7 @@ public final strictfp class StandardDateFormatTest extends TestCase {
         assertEquals(Instant.ofEpochMilli(day + ((16*60 + 48)*60     )*1000),      StandardDateFormat.parseInstantUTC("2016-06-27T16:48"));
         assertEquals(Instant.ofEpochMilli(day + ((16*60 + 48)*60     )*1000),      StandardDateFormat.parseInstantUTC("2016-06-27
16:48"));
         assertEquals(Instant.ofEpochMilli(day),                                    StandardDateFormat.parseInstantUTC("2016-06-27"));
+        assertEquals(Instant.ofEpochMilli(day + 2000),                             StandardDateFormat.parseInstantUTC("2016-06-27
00:00:02 UTC"));
     }
 
     /**


Mime
View raw message