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

org.apache.chemistry.opencmis.commons.impl.DateTimeHelper Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.chemistry.opencmis.commons.impl;

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

public final class DateTimeHelper {

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

    private static final Pattern XML_DATETIME = Pattern
            .compile("(\\d{4,9})-([01]\\d)-([0-3]\\d)T([0-2]\\d):([0-5]\\d):([0-5]\\d)(\\.(\\d+))?(([+-][0-2]\\d:[0-5]\\d)|Z)?");
    private static final BigDecimal BD1000 = new BigDecimal(1000);

    private static final String[] WDAYS = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

    private static final String[] MONTHS = new String[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
            "Sep", "Oct", "Nov", "Dec" };

    private static final Map MONTHS_MAP = new HashMap();
    static {
        for (int i = 0; i < MONTHS.length; i++) {
            MONTHS_MAP.put(MONTHS[i], i);
        }
    }

    private static final Pattern HTTP_DATETIME1 = Pattern
            .compile("\\w{3}, ([0-3]\\d) (\\w{3}) (\\d{4}) ([0-2]\\d):([0-5]\\d):([0-5]\\d) GMT");

    private static final Pattern HTTP_DATETIME2 = Pattern
            .compile("\\w{6,9}, ([0-3]\\d)-(\\w{3})-(\\d{2}) ([0-2]\\d):([0-5]\\d):([0-5]\\d) GMT");

    private static final Pattern HTTP_DATETIME3 = Pattern
            .compile("\\w{3} (\\w{3}) ([0-3 ]\\d) ([0-2]\\d):([0-5]\\d):([0-5]\\d) (\\d{4})");

    private DateTimeHelper() {
    }

    /**
     * Parses a xsd:dateTime string.
     */
    public static GregorianCalendar parseXmlDateTime(String s) {
        if (s == null) {
            return null;
        }

        final Matcher m = XML_DATETIME.matcher(s);

        if (!m.matches()) {
            return null;
        }

        try {
            int year = Integer.parseInt(m.group(1));
            int month = Integer.parseInt(m.group(2));
            int day = Integer.parseInt(m.group(3));
            int hour = Integer.parseInt(m.group(4));
            int minute = Integer.parseInt(m.group(5));
            int second = Integer.parseInt(m.group(6));
            int millisecond = 0;

            if (m.group(8) != null) {
                millisecond = (new BigDecimal("0." + m.group(8))).multiply(BD1000).intValue();
            }

            TimeZone tz = GMT;

            if (m.group(10) != null) {
                tz = TimeZone.getTimeZone("GMT" + m.group(10));
            }

            final GregorianCalendar result = new GregorianCalendar();
            result.clear();

            result.setTimeZone(tz);
            result.set(year, month - 1, day, hour, minute, second);
            result.set(Calendar.MILLISECOND, millisecond);

            return result;
        } catch (NumberFormatException e) {
            return null;
        }
    }

    /**
     * Returns a xsd:dateTime string.
     */
    public static String formatXmlDateTime(long millis) {
        final GregorianCalendar cal = new GregorianCalendar(GMT);
        cal.setTimeInMillis(millis);

        return formatXmlDateTime(cal);
    }

    /**
     * Returns a xsd:dateTime string.
     */
    public static String formatXmlDateTime(GregorianCalendar cal) {
        if (cal == null) {
            throw new IllegalArgumentException();
        }

        final StringBuilder sb = new StringBuilder();
        add4d(sb, cal.get(Calendar.YEAR));
        sb.append('-');
        add2d(sb, cal.get(Calendar.MONTH) + 1);
        sb.append('-');
        add2d(sb, cal.get(Calendar.DAY_OF_MONTH));
        sb.append('T');
        add2d(sb, cal.get(Calendar.HOUR_OF_DAY));
        sb.append(':');
        add2d(sb, cal.get(Calendar.MINUTE));
        sb.append(':');
        add2d(sb, cal.get(Calendar.SECOND));

        int ms = cal.get(Calendar.MILLISECOND);
        if (ms > 0) {
            sb.append('.');
            add3d(sb, ms);
            while (sb.charAt(sb.length() - 1) == '0') {
                sb.deleteCharAt(sb.length() - 1);
            }
        }

        int tz = cal.getTimeZone().getOffset(cal.getTimeInMillis());
        if (tz == 0) {
            sb.append('Z');
        } else {
            if (tz > 0) {
                sb.append('+');
            } else {
                sb.append('-');
                tz *= -1;
            }
            add2d(sb, tz / 3600000);
            sb.append(':');
            int tzm = tz % 3600000;
            add2d(sb, tzm == 0 ? 0 : tzm / 60000);
        }

        return sb.toString();
    }

    /**
     * Parses a HTTP date.
     */
    public static Date parseHttpDateTime(String s) {
        if (s == null) {
            return null;
        }

        s = s.trim();
        if (s.length() > 1 && s.charAt(0) == '\'' && s.endsWith("'")) {
            s = s.substring(1, s.length() - 1);
        }

        final GregorianCalendar cal = new GregorianCalendar(GMT);
        cal.set(Calendar.MILLISECOND, 0);

        Matcher m = null;

        m = HTTP_DATETIME1.matcher(s);
        if (m.matches()) {
            final Integer month = MONTHS_MAP.get(m.group(2));
            if (month == null) {
                return null;
            }

            cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(1)));
            cal.set(Calendar.MONTH, month);
            cal.set(Calendar.YEAR, Integer.parseInt(m.group(3)));
            cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(4)));
            cal.set(Calendar.MINUTE, Integer.parseInt(m.group(5)));
            cal.set(Calendar.SECOND, Integer.parseInt(m.group(6)));

            return cal.getTime();
        }

        m = HTTP_DATETIME2.matcher(s);
        if (m.matches()) {
            final Integer month = MONTHS_MAP.get(m.group(2));
            if (month == null) {
                return null;
            }

            cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(1)));
            cal.set(Calendar.MONTH, month);
            int year = Integer.parseInt(m.group(3));
            if (year < 100) {
                final int thisYear = (new GregorianCalendar(GMT)).get(Calendar.YEAR);
                final int testYear = year + thisYear - thisYear % 100;
                year = (testYear < thisYear + 20 ? testYear : testYear - 100);
            }
            cal.set(Calendar.YEAR, year);
            cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(4)));
            cal.set(Calendar.MINUTE, Integer.parseInt(m.group(5)));
            cal.set(Calendar.SECOND, Integer.parseInt(m.group(6)));

            return cal.getTime();
        }

        m = HTTP_DATETIME3.matcher(s);
        if (m.matches()) {
            final Integer month = MONTHS_MAP.get(m.group(1));
            if (month == null) {
                return null;
            }

            cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(m.group(2).trim()));
            cal.set(Calendar.MONTH, month);
            cal.set(Calendar.YEAR, Integer.parseInt(m.group(6)));
            cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(m.group(3)));
            cal.set(Calendar.MINUTE, Integer.parseInt(m.group(4)));
            cal.set(Calendar.SECOND, Integer.parseInt(m.group(5)));

            return cal.getTime();
        }

        return null;
    }

    /**
     * Returns a HTTP date.
     */
    public static String formatHttpDateTime(long millis) {
        final GregorianCalendar cal = new GregorianCalendar(GMT);
        cal.setTimeInMillis(millis);

        final StringBuilder sb = new StringBuilder();
        sb.append(WDAYS[cal.get(Calendar.DAY_OF_WEEK) - 1]);
        sb.append(", ");
        add2d(sb, cal.get(Calendar.DAY_OF_MONTH));
        sb.append(' ');
        sb.append(MONTHS[cal.get(Calendar.MONTH)]);
        sb.append(' ');
        add4d(sb, cal.get(Calendar.YEAR));
        sb.append(' ');
        add2d(sb, cal.get(Calendar.HOUR_OF_DAY));
        sb.append(':');
        add2d(sb, cal.get(Calendar.MINUTE));
        sb.append(':');
        add2d(sb, cal.get(Calendar.SECOND));
        sb.append(" GMT");

        return sb.toString();
    }

    /**
     * Returns a HTTP date.
     */
    public static String formatHttpDateTime(final Date date) {
        return formatHttpDateTime(date.getTime());
    }

    /**
     * Returns a HTTP date.
     */
    public static String formatHttpDateTime(final GregorianCalendar cal) {
        return formatHttpDateTime(cal.getTimeInMillis());
    }

    private static void add2d(final StringBuilder sb, int value) {
        assert sb != null;
        assert value >= 0;

        if (value < 10) {
            sb.append('0');
        }
        sb.append(value);
    }

    private static void add3d(final StringBuilder sb, int value) {
        assert sb != null;
        assert value >= 0;

        if (value < 10) {
            sb.append('0');
        }
        if (value < 100) {
            sb.append('0');
        }
        sb.append(value);
    }

    private static void add4d(final StringBuilder sb, int value) {
        assert sb != null;
        assert value >= 0;

        if (value < 10) {
            sb.append('0');
        }
        if (value < 100) {
            sb.append('0');
        }
        if (value < 1000) {
            sb.append('0');
        }
        sb.append(value);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy