Ticket #19704: 19704.patch

File 19704.patch, 5.9 KB (added by simon04, 5 years ago)
  • src/org/openstreetmap/josm/tools/date/DateUtils.java

    diff --git a/src/org/openstreetmap/josm/tools/date/DateUtils.java b/src/org/openstreetmap/josm/tools/date/DateUtils.java
    index 9cd7cc82e..09ba101a7 100644
    a b  
    1414import java.util.TimeZone;
    1515import java.util.concurrent.TimeUnit;
    1616
    17 import javax.xml.datatype.DatatypeConfigurationException;
    18 import javax.xml.datatype.DatatypeFactory;
    19 
    2017import org.openstreetmap.josm.data.preferences.BooleanProperty;
    2118import org.openstreetmap.josm.tools.CheckParameterUtil;
    22 import org.openstreetmap.josm.tools.Logging;
    2319import org.openstreetmap.josm.tools.UncheckedParseException;
    2420
    2521/**
     
    4339     */
    4440    public static final BooleanProperty PROP_ISO_DATES = new BooleanProperty("iso.dates", false);
    4541
    46     private static final DatatypeFactory XML_DATE;
    47 
    48     static {
    49         DatatypeFactory fact = null;
    50         try {
    51             fact = DatatypeFactory.newInstance();
    52         } catch (DatatypeConfigurationException e) {
    53             Logging.error(e);
    54         }
    55         XML_DATE = fact;
    56     }
    57 
    5842    /**
    5943     * Constructs a new {@code DateUtils}.
    6044     */
    private DateUtils() {  
    6953     * @throws UncheckedParseException if the date does not match any of the supported date formats
    7054     * @throws DateTimeException if the value of any field is out of range, or if the day-of-month is invalid for the month-year
    7155     */
    72     public static synchronized Date fromString(String str) {
     56    public static Date fromString(String str) {
    7357        return new Date(tsFromString(str));
    7458    }
    7559
    public static synchronized Date fromString(String str) {  
    8064     * @throws UncheckedParseException if the date does not match any of the supported date formats
    8165     * @throws DateTimeException if the value of any field is out of range, or if the day-of-month is invalid for the month-year
    8266     */
    83     public static synchronized long tsFromString(String str) {
     67    public static long tsFromString(String str) {
    8468        // "2007-07-25T09:26:24{Z|{+|-}01[:00]}"
    85         if (checkLayout(str, "xxxx-xx-xxTxx:xx:xxZ") ||
     69        if (checkLayout(str, "xxxx-xx-xx")) {
     70            final ZonedDateTime local = ZonedDateTime.of(
     71                    parsePart4(str, 0),
     72                    parsePart2(str, 5),
     73                    parsePart2(str, 8),
     74                    0,0,0, 0, ZoneOffset.UTC);
     75            return local.toInstant().toEpochMilli();
     76        } else if (checkLayout(str, "xxxx-xx-xxTxx:xx:xxZ") ||
    8677                checkLayout(str, "xxxx-xx-xxTxx:xx:xx") ||
    8778                checkLayout(str, "xxxx:xx:xx xx:xx:xx") ||
    8879                checkLayout(str, "xxxx-xx-xx xx:xx:xxZ") ||
    public static synchronized long tsFromString(String str) {  
    133124            if (d != null)
    134125                return d.getTime();
    135126        }
    136 
    137         try {
    138             return XML_DATE.newXMLGregorianCalendar(str).toGregorianCalendar().getTimeInMillis();
    139         } catch (IllegalArgumentException ex) {
    140             throw new UncheckedParseException("The date string (" + str + ") could not be parsed.", ex);
    141         }
     127        throw new UncheckedParseException("The date string (" + str + ") could not be parsed.");
    142128    }
    143129
    144130    /**
    public static String fromTimestamp(long timestamp) {  
    157143     * @return The formatted date
    158144     * @since 14434
    159145     */
    160     public static synchronized String fromTimestampInMillis(long timestamp) {
     146    public static String fromTimestampInMillis(long timestamp) {
    161147        final ZonedDateTime temporal = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.UTC);
    162148        return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(temporal);
    163149    }
    public static synchronized String fromTimestampInMillis(long timestamp) {  
    167153     * @param timestamp number of seconds since the epoch
    168154     * @return The formatted date
    169155     */
    170     public static synchronized String fromTimestamp(int timestamp) {
     156    public static String fromTimestamp(int timestamp) {
    171157        return fromTimestamp(Integer.toUnsignedLong(timestamp));
    172158    }
    173159
    public static synchronized String fromTimestamp(int timestamp) {  
    176162     * @param date The date to format
    177163     * @return The formatted date
    178164     */
    179     public static synchronized String fromDate(Date date) {
     165    public static String fromDate(Date date) {
    180166        final ZonedDateTime temporal = date.toInstant().atZone(ZoneOffset.UTC);
    181167        return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(temporal);
    182168    }
  • test/unit/org/openstreetmap/josm/tools/date/DateUtilsTest.java

    diff --git a/test/unit/org/openstreetmap/josm/tools/date/DateUtilsTest.java b/test/unit/org/openstreetmap/josm/tools/date/DateUtilsTest.java
    index 3e9efe675..d6bcc949c 100644
    a b  
    99
    1010import java.text.DateFormat;
    1111import java.util.Date;
     12import java.util.Random;
    1213import java.util.TimeZone;
     14import java.util.concurrent.ForkJoinPool;
    1315
     16import org.junit.Ignore;
    1417import org.junit.Rule;
    1518import org.junit.Test;
    1619import org.openstreetmap.josm.testutils.JOSMTestRules;
    public void testTsFromString() {  
    191194        assertEquals(1459695600123L + 5 * 3600 * 1000, DateUtils.tsFromString("2016-04-03T15:00:00.123-05:00"));
    192195
    193196        // Local time
    194         TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"));
     197        setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
    195198        assertEquals(1459688400000L, DateUtils.tsFromString("03-APR-16 15:00:00"));
    196199    }
    197200
     201    @Test
     202    @Ignore("slow, for thread safety testing")
     203    public void testTsFromString800k() throws Exception {
     204        new ForkJoinPool(64).submit(() -> new Random()
     205                .longs(800_000)
     206                .parallel()
     207                .forEach(ignore -> testTsFromString())).get();
     208        // 13.992s → 2.213s
     209    }
     210
    198211    /**
    199212     * Unit test of {@link DateUtils#tsFromString} method.
    200213     */