All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.deephacks.tools4j.config.test.DateTime Maven / Gradle / Ivy

There is a newer version: 0.15.0
Show newest version
package org.deephacks.tools4j.config.test;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Represents a date/time closely to xs:dateTime ISO8601, or a date without a
 * time. Optionally includes a time zone.
 * 
 * See: http://www.w3.org/TR/xmlschema-2/#isoformats
 */
public final class DateTime {

    /** date/time pattern. */
    private static final Pattern dateTimePattern = Pattern
            .compile("(\\d\\d\\d\\d)\\-(\\d\\d)\\-(\\d\\d)[Tt]"
                    + "(\\d\\d):(\\d\\d):(\\d\\d)(\\.(\\d+))?"
                    + "([Zz]|((\\+|\\-)(\\d\\d):(\\d\\d)))?");

    /** date pattern. */
    private static final Pattern datePattern = Pattern
            .compile("(\\d\\d\\d\\d)\\-(\\d\\d)\\-(\\d\\d)"
                    + "([Zz]|((\\+|\\-)(\\d\\d):(\\d\\d)))?");

    private static final TimeZone GMT = TimeZone.getTimeZone("GMT");

    private String dateTimeString;

    public DateTime(String dateTime) {
        this.dateTimeString = dateTime;
    }

    public String getDateTimeString() {
        return dateTimeString;
    }

    public Date parseDateTimeOrDate() throws NumberFormatException {
        NumberFormatException exception;

        try {
            return parseDateTime();
        } catch (NumberFormatException e) {
            exception = e;
        }

        try {
            return parseDate();
        } catch (NumberFormatException e) {
            exception = e;
        }

        throw exception;
    }

    /**
     * Parses an xs:dateTime string. If the time zone is specified, this value
     * is normalized to UTC, so to format this date/time value, the time zone
     * shift has to be applied. If no time zone or shifts is specified, the
     * local time is assumed.
     */
    public Date parseDateTime() throws NumberFormatException {

        Matcher m = dateTimeString == null ? null : dateTimePattern.matcher(dateTimeString);

        if (dateTimeString == null || !m.matches()) {
            throw new NumberFormatException("Invalid date/time format.");
        }
        String year = m.group(1);
        String month = m.group(2);
        String day = m.group(3);
        String hour = m.group(4);
        String minute = m.group(5);
        String sec = m.group(6);
        String secFraction = m.group(8);
        String timezone = m.group(9);
        String timezoneShift = m.group(11);
        String timezoneHour = m.group(12);
        String timezoneMinute = m.group(13);
        /**
         * Time zone shift from UTC in minutes.
         */
        Integer tzShift;
        Calendar dateTime = null;

        if (timezone == null) {
            // No time zone specified. Use local time.
            dateTime = new GregorianCalendar();
            tzShift = 0;
        } else if (timezone.equalsIgnoreCase("Z")) {
            // Use UTC, no shift
            dateTime = new GregorianCalendar(GMT);
            tzShift = 0;
        } else {
            // shift from UTC
            dateTime = new GregorianCalendar(GMT);
            tzShift = new Integer(
                    (Integer.valueOf(timezoneHour) * 60 + Integer.valueOf(timezoneMinute)));
            if (timezoneShift.equals("-")) {
                tzShift = new Integer(-tzShift.intValue());
            }
        }
        dateTime.clear();
        dateTime.set(Integer.valueOf(year), Integer.valueOf(month) - 1, Integer.valueOf(day),
                Integer.valueOf(hour), Integer.valueOf(minute), Integer.valueOf(sec));
        if (secFraction != null && secFraction.length() > 0) {
            final BigDecimal bd = new BigDecimal("0." + secFraction);
            // we care only for milliseconds, so movePointRight(3)
            dateTime.set(Calendar.MILLISECOND, bd.movePointRight(3).intValue());
        }

        long time = dateTime.getTimeInMillis();

        time -= tzShift.intValue() * 60000;

        return new Date(time);
    }

    /** Parses an xs:date string. */
    public Date parseDate() throws NumberFormatException {

        Matcher m = dateTimeString == null ? null : datePattern.matcher(dateTimeString);

        if (dateTimeString == null || !m.matches()) {
            throw new NumberFormatException("Invalid date format.");
        }

        String year = m.group(1);
        String month = m.group(2);
        String day = m.group(3);
        String timezone = m.group(4);
        String timezoneShift = m.group(6);
        String timezoneHour = m.group(7);
        String timezoneMinute = m.group(8);
        Integer tzShift = null;

        Calendar dateTime = null;

        if (timezone == null) {
            // No time zone specified.
            dateTime = new GregorianCalendar();
            tzShift = 0;
        } else if (timezone.equalsIgnoreCase("Z")) {
            tzShift = 0;
            dateTime = new GregorianCalendar(GMT);
        } else {
            tzShift = new Integer(
                    (Integer.valueOf(timezoneHour) * 60 + Integer.valueOf(timezoneMinute)));
            if (timezoneShift.equals("-")) {
                tzShift = new Integer(-tzShift.intValue());
            }
            dateTime = new GregorianCalendar(GMT);
        }

        dateTime.clear();
        dateTime.set(Integer.valueOf(year), Integer.valueOf(month) - 1, Integer.valueOf(day));

        long time = dateTime.getTimeInMillis();
        time -= tzShift.intValue() * 60000;

        return new Date(time);
    }

    @Override
    public String toString() {
        return dateTimeString;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((dateTimeString == null) ? 0 : dateTimeString.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        DateTime other = (DateTime) obj;
        if (dateTimeString == null) {
            if (other.dateTimeString != null)
                return false;
        } else if (!dateTimeString.equals(other.dateTimeString))
            return false;
        return true;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy