Ignore:
Timestamp:
2016-09-20T22:46:47+02:00 (5 years ago)
Author:
simon04
Message:

see #13376 - Replace Calendar usages with Java 8 Date API

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/date/DateUtils.java

    r10513 r11035  
    55import java.text.ParsePosition;
    66import java.text.SimpleDateFormat;
    7 import java.util.Calendar;
     7import java.time.Instant;
     8import java.time.ZoneId;
     9import java.time.ZoneOffset;
     10import java.time.ZonedDateTime;
     11import java.time.format.DateTimeFormatter;
    812import java.util.Date;
    9 import java.util.GregorianCalendar;
    1013import java.util.Locale;
    1114import java.util.TimeZone;
     
    1316import javax.xml.datatype.DatatypeConfigurationException;
    1417import javax.xml.datatype.DatatypeFactory;
    15 import javax.xml.datatype.XMLGregorianCalendar;
    1618
    1719import org.openstreetmap.josm.Main;
     
    4143    public static final BooleanProperty PROP_ISO_DATES = new BooleanProperty("iso.dates", false);
    4244
    43     /**
    44      * A shared instance used for conversion between individual date fields
    45      * and long millis time. It is guarded against conflict by the class lock.
    46      * The shared instance is used because the construction, together
    47      * with the timezone lookup, is very expensive.
    48      */
    49     private static final GregorianCalendar calendar = new GregorianCalendar(UTC);
    50     /**
    51      * A shared instance to convert local times. The time zone should be set before every conversion.
    52      */
    53     private static final GregorianCalendar calendarLocale = new GregorianCalendar(TimeZone.getDefault());
    5445    private static final DatatypeFactory XML_DATE;
    5546
    5647    static {
    57         calendar.setTimeInMillis(0);
    58         calendarLocale.setTimeInMillis(0);
    59 
    6048        DatatypeFactory fact = null;
    6149        try {
     
    9785                checkLayout(str, "xxxx-xx-xxTxx:xx:xx+xx:00") ||
    9886                checkLayout(str, "xxxx-xx-xxTxx:xx:xx-xx:00")) {
    99             final Calendar c; // consider EXIF date in default timezone
    100             if (checkLayout(str, "xxxx:xx:xx xx:xx:xx")) {
    101                 c = getLocalCalendar();
    102             } else {
    103                 c = calendar;
    104             }
    105             c.set(
     87            final ZonedDateTime local = ZonedDateTime.of(
    10688                parsePart4(str, 0),
    107                 parsePart2(str, 5)-1,
     89                parsePart2(str, 5),
    10890                parsePart2(str, 8),
    10991                parsePart2(str, 11),
    11092                parsePart2(str, 14),
    111                 parsePart2(str, 17));
    112             c.set(Calendar.MILLISECOND, 0);
    113 
     93                parsePart2(str, 17),
     94                0,
     95                // consider EXIF date in default timezone
     96                checkLayout(str, "xxxx:xx:xx xx:xx:xx") ? ZoneId.systemDefault() : ZoneOffset.UTC
     97            );
    11498            if (str.length() == 22 || str.length() == 25) {
    115                 int plusHr = parsePart2(str, 20);
    116                 int mul = str.charAt(19) == '+' ? -3600000 : 3600000;
    117                 return c.getTimeInMillis()+plusHr*mul;
     99                final int plusHr = parsePart2(str, 20);
     100                final int mul = str.charAt(19) == '+' ? -1 : 1;
     101                return local.plusHours(plusHr * mul).toInstant().toEpochMilli();
    118102            }
    119 
    120             return c.getTimeInMillis();
     103            return local.toInstant().toEpochMilli();
    121104        } else if (checkLayout(str, "xxxx-xx-xxTxx:xx:xx.xxxZ") ||
    122105                checkLayout(str, "xxxx-xx-xxTxx:xx:xx.xxx") ||
     
    124107                checkLayout(str, "xxxx-xx-xxTxx:xx:xx.xxx+xx:00") ||
    125108                checkLayout(str, "xxxx-xx-xxTxx:xx:xx.xxx-xx:00")) {
    126             // consider EXIF date in default timezone
    127             final Calendar c = checkLayout(str, "xxxx:xx:xx xx:xx:xx.xxx") ? getLocalCalendar() : calendar;
    128             c.set(
     109            final ZonedDateTime local = ZonedDateTime.of(
    129110                parsePart4(str, 0),
    130                 parsePart2(str, 5)-1,
     111                parsePart2(str, 5),
    131112                parsePart2(str, 8),
    132113                parsePart2(str, 11),
    133114                parsePart2(str, 14),
    134                 parsePart2(str, 17));
    135             c.set(Calendar.MILLISECOND, 0);
    136             long millis = parsePart3(str, 20);
     115                parsePart2(str, 17),
     116                parsePart3(str, 20) * 1_000_000,
     117                // consider EXIF date in default timezone
     118                checkLayout(str, "xxxx:xx:xx xx:xx:xx.xxx") ? ZoneId.systemDefault() : ZoneOffset.UTC
     119            );
    137120            if (str.length() == 29) {
    138                 millis += parsePart2(str, 24) * (str.charAt(23) == '+' ? -3600000 : 3600000);
     121                final int plusHr = parsePart2(str, 24);
     122                final int mul = str.charAt(23) == '+' ? -1 : 1;
     123                return local.plusHours(plusHr * mul).toInstant().toEpochMilli();
    139124            }
    140 
    141             return c.getTimeInMillis() + millis;
     125            return local.toInstant().toEpochMilli();
    142126        } else {
    143127            // example date format "18-AUG-08 13:33:03"
     
    155139    }
    156140
    157     private static Calendar getLocalCalendar() {
    158         final Calendar c = calendarLocale;
    159         c.setTimeZone(TimeZone.getDefault());
    160         return c;
    161     }
    162 
    163     private static String toXmlFormat(GregorianCalendar cal) {
    164         XMLGregorianCalendar xgc = XML_DATE.newXMLGregorianCalendar(cal);
    165         if (cal.get(Calendar.MILLISECOND) == 0) {
    166             xgc.setFractionalSecond(null);
    167         }
    168         return xgc.toXMLFormat();
    169     }
    170 
    171141    /**
    172142     * Formats a date to the XML UTC format regardless of current locale.
     
    175145     */
    176146    public static synchronized String fromTimestamp(int timestamp) {
    177         calendar.setTimeInMillis(timestamp * 1000L);
    178         return toXmlFormat(calendar);
     147        final ZonedDateTime temporal = Instant.ofEpochMilli(timestamp * 1000L).atZone(ZoneOffset.UTC);
     148        return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(temporal);
    179149    }
    180150
     
    185155     */
    186156    public static synchronized String fromDate(Date date) {
    187         calendar.setTime(date);
    188         return toXmlFormat(calendar);
     157        final ZonedDateTime temporal = date.toInstant().atZone(ZoneOffset.UTC);
     158        return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(temporal);
    189159    }
    190160
Note: See TracChangeset for help on using the changeset viewer.