dateparser.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 724 行 · 第 1/2 页

JAVA
724
字号
/* *    * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.util;import java.util.Hashtable;/** * This class implements somewhat of a subset of the J2SE Date class. * However, since the semantics of parse() is slightly different * (DateParser will not handle dates prior to 1/1/1970, amd to * be able to provide methods that will set timezone and DST * information, it is called DateParser. */public class DateParser {    /** The year represented by this date */    protected int year;    /** The month represented by this date */    protected int month;    /** The day of the month represented by this date */    protected int day;    /** The hour represented by this date */    protected int hour;    /** The minute represented by this date */    protected int minute;    /** The second represented by this date */    protected int second;    /** The millisecond represented by this date */    protected int milli;    /** The offset, in milliseconds, from GMT represented by this date */    protected int tzoffset;    /** The offset, in milliseconds, from GMT for the local time zone */    protected static int local_tz;    /**     * Allocates a <code>DateParser</code> object and initializes it so that      * it represents the instant at the start of the second specified      * by the <code>year</code>, <code>month</code>, <code>date</code>,      * <code>hrs</code>, <code>min</code>, and <code>sec</code> arguments,      * in the local time zone.      *     * @param   inp_year    the year, >= 1583.     * @param   inp_month   the month between 0-11.     * @param   inp_day     the day of the month between 1-31.     * @param   inp_hour    the hours between 0-23.     * @param   inp_minute  the minutes between 0-59.     * @param   inp_second  the seconds between 0-59.     */    DateParser(int inp_year, int inp_month, int inp_day,                int inp_hour, int inp_minute, int inp_second) {        if (inp_year < 1583            || inp_month < 0 || inp_month > 11            || inp_day < 0 || (inp_day > days_in_month[inp_month]                    && !(inp_month == 1 && inp_day == 29 && inp_year % 4 == 0))            || inp_hour < 0 || inp_hour > 23            || inp_minute < 0 || inp_minute > 59            || inp_second < 0 || inp_second > 59) {            throw new IllegalArgumentException();        }                year   = inp_year;        month  = inp_month;        day    = inp_day;        hour   = inp_hour;        minute = inp_minute;        second = inp_second;        milli = 0;    }        /**     * Allocates a <code>DateParser</code> object and initializes it so that      * it represents the date and time indicated by the string      * <code>s</code>, which is interpreted as if by the      * {@link DateParser#parse} method.      *     * @param   s   a string representation of the date.     */    DateParser(String s) {        internalParse(s);    }        /**     * Allocates a <code>DateParser</code> object and initializes it so that      * it represents the date and time indicated by the string      * <code>s</code>, which is interpreted as if by the      * {@link DateParser#parse} method.      *     * @param   s   a string representation of the date.     */    DateParser(String s, boolean iso) {        if (iso == false) {            internalParse(s);        } else {            internalParseISO(s);        }    }    /**      * Set the local time zone for the DateParser class.     * <code>tz</code> must in abbreviated format, e.g. "PST"     * for Pacific Standard Time.     *     * @param tz The time zone string in abbreviated format.     */    static void setTimeZone(String tz) {        if (timezones.get(tz) == null) {            return;        }        local_tz = ((Integer)timezones.get(tz)).intValue();    }        /**     * Attempts to interpret the string <tt>s</tt> as a representation      * of a date and time. If the attempt is successful, the time      * indicated is returned represented as teh distance, measured in      * milliseconds, of that time from the epoch (00:00:00 GMT on      * January 1, 1970). If the attempt fails, an      * <tt>IllegalArgumentException</tt> is thrown.     * <p>     * It accepts many syntaxes; in particular, it recognizes the IETF      * standard date syntax: "Sat, 12 Aug 1995 13:30:00 GMT". It also      * understands the continental U.S. time-zone abbreviations, but for      * general use, a time-zone offset should be used: "Sat, 12 Aug 1995      * 13:30:00 GMT+0430" (4 hours, 30 minutes west of the Greenwich      * meridian). If no time zone is specified, the local time zone is      * assumed. GMT and UTC are considered equivalent.     * <p>     * The string <tt>s</tt> is processed from left to right, looking for      * data of interest. Any material in <tt>s</tt> that is within the      * ASCII parenthesis characters <tt>(</tt> and <tt>)</tt> is ignored.      * Parentheses may be nested. Otherwise, the only characters permitted      * within <tt>s</tt> are these ASCII characters:     * <blockquote><pre>     * abcdefghijklmnopqrstuvwxyz     * ABCDEFGHIJKLMNOPQRSTUVWXYZ     * 0123456789,+-:/</pre></blockquote>     * and whitespace characters.<p>     * A consecutive sequence of decimal digits is treated as a decimal      * number:<ul>     * <li>If a number is preceded by <tt>+</tt> or <tt>-</tt> and a year      *     has already been recognized, then the number is a time-zone      *     offset. If the number is less than 24, it is an offset measured      *     in hours. Otherwise, it is regarded as an offset in minutes,      *     expressed in 24-hour time format without punctuation. A      *     preceding <tt>-</tt> means a westward offset. Time zone offsets      *     are always relative to UTC (Greenwich). Thus, for example,      *     <tt>-5</tt> occurring in the string would mean "five hours west      *     of Greenwich" and <tt>+0430</tt> would mean "four hours and      *     thirty minutes east of Greenwich." It is permitted for the      *     string to specify <tt>GMT</tt>, <tt>UT</tt>, or <tt>UTC</tt>      *     redundantly-for example, <tt>GMT-5</tt> or <tt>utc+0430</tt>.     * <li>If a number is greater than 70, it is regarded as a year number.      *     It must be followed by a space, comma, slash, or end of string.      * <li>If the number is followed by a colon, it is regarded as an hour,      *     unless an hour has already been recognized, in which case it is      *     regarded as a minute.     * <li>If the number is followed by a slash, it is regarded as a month      *     (it is decreased by 1 to produce a number in the range <tt>0</tt>      *     to <tt>11</tt>), unless a month has already been recognized, in      *     which case it is regarded as a day of the month.     * <li>If the number is followed by whitespace, a comma, a hyphen, or      *     end of string, then if an hour has been recognized but not a      *     minute, it is regarded as a minute; otherwise, if a minute has      *     been recognized but not a second, it is regarded as a second;      *     otherwise, it is regarded as a day of the month. </ul><p>     * A consecutive sequence of letters is regarded as a word and treated      * as follows:<ul>     * <li>A word that matches <tt>AM</tt>, ignoring case, is ignored (but      *     the parse fails if an hour has not been recognized or is less      *     than <tt>1</tt> or greater than <tt>12</tt>).     * <li>A word that matches <tt>PM</tt>, ignoring case, adds <tt>12</tt>      *     to the hour (but the parse fails if an hour has not been      *     recognized or is less than <tt>1</tt> or greater than <tt>12</tt>).     * <li>Any word that matches any prefix of <tt>SUNDAY, MONDAY, TUESDAY,      *     WEDNESDAY, THURSDAY, FRIDAY</tt>, or <tt>SATURDAY</tt>, ignoring      *     case, is ignored. For example, <tt>sat, Friday, TUE</tt>, and      *     <tt>Thurs</tt> are ignored.     * <li>Otherwise, any word that matches any prefix of <tt>JANUARY,      *     FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER,      *     OCTOBER, NOVEMBER</tt>, or <tt>DECEMBER</tt>, ignoring case, and      *     considering them in the order given here, is recognized as     *     specifying a month and is converted to a number (<tt>0</tt> to      *     <tt>11</tt>). For example, <tt>aug, Sept, april</tt>, and      *     <tt>NOV</tt> are recognized as months. So is <tt>Ma</tt>, which      *     is recognized as <tt>MARCH</tt>, not <tt>MAY</tt>.     * <li>Any word that matches <tt>GMT, UT</tt>, or <tt>UTC</tt>, ignoring      *     case, is treated as referring to UTC.      * <li>Any word that matches <tt>EST, CST, MST</tt>, or <tt>PST</tt>,      *     ignoring case, is recognized as referring to the time zone in      *     North America that is five, six, seven, or eight hours west of      *     Greenwich, respectively. Any word that matches <tt>EDT, CDT,      *     MDT</tt>, or <tt>PDT</tt>, ignoring case, is recognized as      *     referring to the same time zone, respectively, during daylight      *     saving time.</ul><p>     * Once the entire string s has been scanned, it is converted to a time      * result in one of two ways. If a time zone or time-zone offset has been      * recognized, then the year, month, day of month, hour, minute, and      * second are interpreted in UTC and then the time-zone offset is      * applied. Otherwise, the year, month, day of month, hour, minute, and      * second are interpreted in the local time zone.     *     * @param   s   a string to be parsed as a date.     * @return  the distance in milliseconds from January 1, 1970, 00:00:00 GMT     *          represented by the string argument. Note that this method will     *          throw an <code>IllegalArgumentException</code> if the year      *          indicated in <code>s</code> is less than 1583.     */    public static long parse(String s) {        return (new DateParser(s)).getTime();    }        /**     * Parses a date string according to the ISO 8601 standard.     *     * @param date the date string in the format YYYY-MM-DDTHH:MM[:SS][[+|-]     *      HH[MM]]     * @return the number of milliseconds elapsed since 1970-1-1 GMT to this     *      date     * @throws IllegalArgumentException if the format of the date string is     *      incorrect or the date is invalid     */    public static long parseISO(String date) {        return (new DateParser(date, true)).getTime();    }            private void internalParseISO(String date) {        int field[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};        int field_ptr = 0;        boolean field_ok;                int c = -1;        int i = 0;        int num_dig = 4; /* 4 digits for YEAR and 2 for the rest fields */        int n = -1;        int prevc = 0;        if (date == null) {            throw new IllegalArgumentException();        }        int limit = date.length();        while (i < limit) {            /* read next char */            c = date.charAt(i);            i++;            if (c == '+' || c == '-' || c == 'Z' ||                     c == ' ' || c == 'T' || c == ':') {                prevc = c;                continue;            }                        /* it is digit */            if (c < '0' || '9' < c) {                throw new IllegalArgumentException();            } else {                n = c - '0';                num_dig--;                while (i < limit && num_dig > 0) {                    if ('0' <= (c = date.charAt(i)) && c <= '9')  {                        n = n * 10 + c - '0';                        i++;                        num_dig--;                    } else                        break;                }                num_dig = 2; /* only tear has 4 digits, the rest - 2 */                                field_ok = false;                switch (field_ptr) {                    case 0: /* year */                        if (prevc == 0)                            field_ok = true;                        break;                    case 1: /* month */                        if ((prevc == '-') || (prevc == 0))                            field_ok = true;                        break;                    case 2: /* day */                        if ((prevc == '-') || (prevc == 0))                            field_ok = true;                        break;                    case 3: /* hour */                        if ((prevc == ' ') || (prevc == 'T'))                            field_ok = true;                        break;                    case 4: /* min */                        if ((prevc == ':') || (prevc == 0))                            field_ok = true;                        break;                    case 5: /* sec */                        if ((prevc == ':') || (prevc == 0)) {                            field_ok = true;                        } else if ((prevc == '+') || (prevc == '-')) {                            field[field_ptr++] = 0;                            field[field_ptr++] = (prevc == '-')?-1:+1;                            field_ok = true;                        }                        break;                    /* tz_sign can not be reached here */                    case 7: /* tz_hour */                        if ((prevc == '+') || (prevc == '-') || (prevc == 0)) {                            field[field_ptr++] = (prevc == '-')?-1:+1;                            field_ok = true;                        }                        break;                    case 8: /* tz_min */                        if ((prevc == ':') || (prevc == 0)) {                            field_ok = true;                        }                        break;                }                if (field_ok) {                    field[field_ptr++] = n;                } else {                    throw new IllegalArgumentException();                }                prevc = 0;            }           }            if ((field_ptr >= 5) || (prevc == 'Z')) {            field_ptr = 9;        }        if (field_ptr < 8) {            throw new IllegalArgumentException();        }        year = field[0];        month = field[1]-1;        day = field[2];        hour = field[3];        minute = field[4];        second = field[5];        tzoffset = field[6] * ((((field[7]*60) + field[8]) * 60) * 1000);        milli = 0;    }    /**

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?