view backend/src/main/java/org/dive4elements/river/backend/utils/DateGuesser.java @ 9055:df5c5614e9a7

New pseudo datetime for year-only values (31.12. instead of 15.6.)
author mschaefer
date Fri, 04 May 2018 14:03:47 +0200
parents fe81eb39080c
children
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.backend.utils;

import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.dive4elements.river.model.TimeInterval;

public final class DateGuesser {
    public static final String [] MONTH = {
            "jan", "feb", "mrz", "apr", "mai", "jun",
            "jul", "aug", "sep", "okt", "nov", "dez"
    };

    public static final int guessMonth(final String s) {
        final String t = s.toLowerCase();
        for (int i = 0; i < MONTH.length; ++i)
            if (MONTH[i].equals(t)) {
                return i;
            }
        return -1;
    }

    public static final Pattern YYYY_MM_DD =
            Pattern.compile("^(\\d{4})-(\\d{2})-(\\d{2})$");

    public static final Pattern DD_MM_YYYY =
            Pattern.compile("^(\\d{1,2})\\.(\\d{1,2})\\.(\\d{2,4})$");

    public static final Pattern MMM_YYYY =
            Pattern.compile("^((\\d{1,2})\\.)?(\\w{3})[\\. -]?((\\d\\d)|(\\d{4}))$");

    public static final Pattern GARBAGE_YYYY =
            Pattern.compile("^[^\\d=]*((\\d\\d)|([12]\\d{3}))$");

    public static final Pattern YYYY_MM_DDThh_mm =
            Pattern.compile("^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})$");

    public static final Pattern YYYY_MM_DDThh_mm_ss =
            Pattern.compile(
                    "^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})$");

    public static final Pattern DD_MM_YYYYThh_mm =
            Pattern.compile(
                    "^(\\d{1,2})\\.(\\d{1,2})\\.(\\d{2,4})T(\\d{1,2}):(\\d{2})$");

    public static final Pattern DD_MM_YYYYThh_mm_ss =
            Pattern.compile("^(\\d{1,2})\\.(\\d{1,2})\\.(\\d{2,4})"
                    + "T(\\d{1,2}):(\\d{2}):(\\d{2})$");

    public static final Pattern DDMMYY =
            Pattern.compile("^(\\d{2})(\\d{2})(\\d{2})$");

    private DateGuesser() {
    }

    public static final int calendarMonth(final String month) {
        return calendarMonth(Integer.parseInt(month));
    }

    public static final int calendarMonth(final int month) {
        return Math.max(Math.min(month-1, 11), 0);
    }

    /**
     * Guess date by trying all different patterns.
     * Throws IllegalArgumentException if not able to guess.
     * @param s The date to be guessed (e.g. 11.02.2001).
     * @return the parsed Date.
     */
    public static Date guessDate(final String s) {
        if ((s == null) || s.trim().isEmpty()) {
            throw new IllegalArgumentException();
        }

        final String t = s.trim();
        Matcher m;

        m = YYYY_MM_DD.matcher(t);

        if (m.matches()) {
            final Calendar cal = Calendar.getInstance();
            final String year  = m.group(1);
            final String month = m.group(2);
            final String day   = m.group(3);
            cal.clear();
            cal.set(
                    Integer.parseInt(year),
                    calendarMonth(month),
                    Integer.parseInt(day),
                    12, 0, 0);
            return cal.getTime();
        }

        m = DD_MM_YYYY.matcher(t);

        if (m.matches()) {
            final Calendar cal = Calendar.getInstance();
            final String year  = m.group(3);
            final String month = m.group(2);
            final String day   = m.group(1);
            cal.clear();
            cal.set(
                    Integer.parseInt(year) + (year.length() == 2 ? 1900 : 0),
                    calendarMonth(month),
                    Integer.parseInt(day),
                    12, 0, 0);
            return cal.getTime();
        }

        m = MMM_YYYY.matcher(t);

        if (m.matches()) {
            final int month = guessMonth(m.group(3));
            if (month >= 0) {
                final Calendar cal = Calendar.getInstance();
                final String year = m.group(4);
                final String day = m.group(1);
                cal.clear();
                cal.set(
                        Integer.parseInt(year) + (year.length() == 2 ? 1900 : 0),
                        month,
                        ((day == null) || day.isEmpty()) ? 15 : Integer.parseInt(day),
                                12, 0, 0);
                return cal.getTime();
            }
        }

        m = YYYY_MM_DDThh_mm.matcher(t);

        if (m.matches()) {
            final Calendar cal = Calendar.getInstance();
            final String year = m.group(1);
            final String month = m.group(2);
            final String day = m.group(3);
            final String hour = m.group(4);
            final String minute = m.group(5);
            cal.clear();
            cal.set(
                    Integer.parseInt(year),
                    calendarMonth(month),
                    Integer.parseInt(day),
                    Integer.parseInt(hour),
                    Integer.parseInt(minute),
                    0
                    );
            return cal.getTime();
        }

        m = YYYY_MM_DDThh_mm_ss.matcher(t);

        if (m.matches()) {
            final Calendar cal = Calendar.getInstance();
            final String year = m.group(1);
            final String month = m.group(2);
            final String day = m.group(3);
            final String hour = m.group(4);
            final String minute = m.group(5);
            final String second = m.group(6);
            cal.clear();
            cal.set(
                    Integer.parseInt(year),
                    calendarMonth(month),
                    Integer.parseInt(day),
                    Integer.parseInt(hour),
                    Integer.parseInt(minute),
                    Integer.parseInt(second)
                    );
            return cal.getTime();
        }

        m = DD_MM_YYYYThh_mm.matcher(t);

        if (m.matches()) {
            final Calendar cal = Calendar.getInstance();
            final String year = m.group(3);
            final String month = m.group(2);
            final String day = m.group(1);
            final String hour = m.group(4);
            final String minute = m.group(5);
            cal.clear();
            cal.set(
                    Integer.parseInt(year) + (year.length() == 2 ? 1900 : 0),
                    calendarMonth(month),
                    Integer.parseInt(day),
                    Integer.parseInt(hour),
                    Integer.parseInt(minute),
                    0
                    );
            return cal.getTime();
        }

        m = DD_MM_YYYYThh_mm_ss.matcher(t);

        if (m.matches()) {
            final Calendar cal = Calendar.getInstance();
            final String year = m.group(3);
            final String month = m.group(2);
            final String day = m.group(1);
            final String hour = m.group(4);
            final String minute = m.group(5);
            final String second = m.group(6);
            cal.clear();
            cal.set(
                    Integer.parseInt(year) + (year.length() == 2 ? 1900 : 0),
                    calendarMonth(month),
                    Integer.parseInt(day),
                    Integer.parseInt(hour),
                    Integer.parseInt(minute),
                    Integer.parseInt(second)
                    );
            return cal.getTime();
        }

        m = DDMMYY.matcher(t);

        if (m.matches()) {
            final Calendar cal = Calendar.getInstance();
            final String day   = m.group(1);
            final String month = m.group(2);
            final String yearS = m.group(3);
            int year = Integer.parseInt(yearS);

            if (year <= cal.get(Calendar.YEAR) % 100) {
                year += 2000;
            }
            else {
                year += 1900;
            }
            // TODO Warning: two digit year
            cal.clear();
            cal.set(
                    year,
                    Integer.parseInt(month),  // month
                    Integer.parseInt(day), // day
                    12, 0, 0);
            return cal.getTime();
        }

        m = GARBAGE_YYYY.matcher(t);

        if (m.matches() && !t.contains("HQ") && !t.contains("HW")) {
            final Calendar cal = Calendar.getInstance();
            final String year = m.group(1);
            cal.clear();
            cal.set(Integer.parseInt(year) + (year.length() == 2 ? 1900 : 0),
                    TimeInterval.YEAR_ONLY_DATE.get(Calendar.MONTH),
                    TimeInterval.YEAR_ONLY_DATE.get(Calendar.DAY_OF_MONTH),
                    TimeInterval.YEAR_ONLY_DATE.get(Calendar.HOUR_OF_DAY),
                    TimeInterval.YEAR_ONLY_DATE.get(Calendar.MINUTE),
                    TimeInterval.YEAR_ONLY_DATE.get(Calendar.SECOND));
            return cal.getTime();
        }

        throw new IllegalArgumentException();
    }

    public static void main(final String [] args) {
        for (int i = 0; i < args.length; ++i) {
            System.out.println(args[i] + ": " + guessDate(args[i]));
        }
    }
}
// end of file

http://dive4elements.wald.intevation.org