brooklyn-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ahgittin <...@git.apache.org>
Subject [GitHub] incubator-brooklyn pull request: Date parsing and type coercion fi...
Date Fri, 12 Jun 2015 16:46:18 GMT
Github user ahgittin commented on a diff in the pull request:

    https://github.com/apache/incubator-brooklyn/pull/682#discussion_r32332569
  
    --- Diff: utils/common/src/main/java/brooklyn/util/time/Time.java ---
    @@ -443,36 +500,466 @@ else if (s.equalsIgnoreCase("d") || s.equalsIgnoreCase("day") ||
s.equalsIgnoreC
             }
         }
     
    +    public static Calendar newCalendarFromMillisSinceEpochUtc(long timestamp) {
    +        GregorianCalendar cal = new GregorianCalendar();
    +        cal.setTimeInMillis(timestamp);
    +        return cal;
    +    }
    +
    +    public static Calendar newCalendarFromDate(Date date) {
    +        return newCalendarFromMillisSinceEpochUtc(date.getTime());
    +    }
    +    
    +    /** As {@link #parseCalendar(String)} but returning a {@link Date},
    +     * (i.e. a record where the time zone has been applied and forgotten). */
    +    public static Date parseDate(String input) {
    +        if (input==null) return null;
    +        return parseCalendarMaybe(input).get().getTime();
    +    }
    +
    +    /** Parses dates from string, accepting many formats including ISO-8601 and http://yaml.org/type/timestamp.html,

    +     * e.g. 2015-06-15 16:00:00 +0000.
    +     * <p>
    +     * Millis since epoch (1970) is also supported to represent the epoch (0) or dates
in this millenium,
    +     * but to prevent ambiguity of e.g. "20150615", any other dates prior to the year
2001 are not accepted.
    +     * (However if a type Long is supplied, e.g. from a YAML parse, it will always be
treated as millis since epoch.) 
    +     * <p>
    +     * Other formats including locale-specific variants, e.g. recognising month names,
    +     * are supported but this may vary from platform to platform and may change between
versions. */
    +    public static Calendar parseCalendar(String input) {
    +        if (input==null) return null;
    +        return parseCalendarMaybe(input).get();
    +    }
    +    
    +    /** as {@link #parseCalendar(String)} but returning a {@link Maybe} rather than throwing
or returning null */
    +    public static Maybe<Calendar> parseCalendarMaybe(String input) {
    +        if (input==null) return Maybe.absent("value is null");
    +        input = input.trim();
    +        Maybe<Calendar> result;
    +
    +        result = parseCalendarUtc(input);
    +        if (result.isPresent()) return result;
    +
    +        result = parseCalendarSimpleFlexibleFormatParser(input);
    +        if (result.isPresent()) return result;
    +        // return the error from this method
    +        Maybe<Calendar> returnResult = result;
    +
    +//        // see natty method comments below
    +//        Maybe<Date> result = parseDateNatty(input);
    +//        if (result.isPresent()) return result;
    +
    +        result = parseCalendarFormat(input, new SimpleDateFormat(DATE_FORMAT_OF_DATE_TOSTRING));
    +        if (result.isPresent()) return result;
    +        result = parseCalendarDefaultParse(input);
    +        if (result.isPresent()) return result;
    +
    +        return returnResult;
    +    }
    +
    +    @SuppressWarnings("deprecation")
    +    private static Maybe<Calendar> parseCalendarDefaultParse(String input) {
    +        try {
    +            long ms = Date.parse(input);
    +            if (ms>=new Date(1999, 12, 25).getTime() && ms <= new Date(2200,
1, 2).getTime()) {
    +                // accept default date parse for this century and next
    +                GregorianCalendar c = new GregorianCalendar();
    +                c.setTimeInMillis(ms);
    +                return Maybe.of((Calendar)c);
    +            }
    +        } catch (Exception e) {
    +            Exceptions.propagateIfFatal(e);
    +        }
    +        return Maybe.absent();
    +    }
    +
    +    private static Maybe<Calendar> parseCalendarUtc(String input) {
    +        input = input.trim();
    +        if (input.matches("\\d+")) {
    +            if ("0".equals(input)) {
    +                // accept 0 as epoch UTC
    +                return Maybe.of(newCalendarFromMillisSinceEpochUtc(0));
    +            }
    +            Maybe<Calendar> result = Maybe.of(newCalendarFromMillisSinceEpochUtc(Long.parseLong(input)));
    +            if (result.isPresent()) {
    +                int year = result.get().get(Calendar.YEAR);
    +                if (year >= 2000 && year < 2200) {
    +                    // only applicable for dates in this century
    +                    return result;
    +                } else {
    +                    return Maybe.absent("long is probably not millis since epoch UTC;
millis as string is not in acceptable range");
    +                }
    +            }
    +        }
    +        return Maybe.absent("not long millis since epoch UTC");
    +    }
    +
    +    private final static String DIGIT = "\\d";
    +    private final static String LETTER = "\\p{L}";
    +    private final static String COMMON_SEPARATORS = "-\\.";
    +    private final static String TIME_SEPARATOR = COMMON_SEPARATORS+":";
    +    private final static String DATE_SEPARATOR = COMMON_SEPARATORS+"/ ";
    +    private final static String DATE_TIME_ANY_ORDER_GROUP_SEPARATOR = COMMON_SEPARATORS+":/
";
    +
    +    private final static String DATE_ONLY_WITH_INNER_SEPARATORS = 
    +            namedGroup("year", DIGIT+DIGIT+DIGIT+DIGIT)
    +            + anyChar(DATE_SEPARATOR)
    +            + namedGroup("month", options(optionally(DIGIT)+DIGIT, anyChar(LETTER)+"+"))
    +            + anyChar(DATE_SEPARATOR)
    +            + namedGroup("day", optionally(DIGIT)+DIGIT);
    +    private final static String DATE_WORDS_2 = 
    +        namedGroup("month", anyChar(LETTER)+"+")
    +        + anyChar(DATE_SEPARATOR)
    +        + namedGroup("day", optionally(DIGIT)+DIGIT)
    +        + ",?"+anyChar(DATE_SEPARATOR)+"+"
    +        + namedGroup("year", DIGIT+DIGIT+DIGIT+DIGIT);
    +    // we could parse NN-NN-NNNN as DD-MM-YYYY always, but could be confusing for MM-DD-YYYY
oriented people, so require month named
    +    private final static String DATE_WORDS_3 = 
    +        namedGroup("day", optionally(DIGIT)+DIGIT)
    +        + anyChar(DATE_SEPARATOR)
    +        + namedGroup("month", anyChar(LETTER)+"+")
    --- End diff --
    
    agree


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

Mime
View raw message