181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath/*
281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * Copyright (C) 2007 The Android Open Source Project
381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath *
481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * Licensed under the Apache License, Version 2.0 (the "License");
581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * you may not use this file except in compliance with the License.
681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * You may obtain a copy of the License at
781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath *
881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath *      http://www.apache.org/licenses/LICENSE-2.0
981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath *
1081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * Unless required by applicable law or agreed to in writing, software
1181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * distributed under the License is distributed on an "AS IS" BASIS,
1281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * See the License for the specific language governing permissions and
1481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * limitations under the License.
1581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath */
1681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
1781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamathpackage com.android.common;
1881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
1981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamathimport android.text.format.Time;
2081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
2181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamathimport java.util.Calendar;
2281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamathimport java.util.regex.Matcher;
2381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamathimport java.util.regex.Pattern;
2481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
2581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath/**
2681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath * Helper for parsing an HTTP date.
2781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath */
2881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamathfinal class LegacyHttpDateTime {
2981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
3081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    /*
3181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Regular expression for parsing HTTP-date.
3281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     *
3381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy, DD Mon YYYY HH:MM:SS GMT
3481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * RFC 822, updated by RFC 1123
3581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     *
3681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Weekday, DD-Mon-YY HH:MM:SS GMT
3781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * RFC 850, obsoleted by RFC 1036
3881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     *
3981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy Mon DD HH:MM:SS YYYY
4081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * ANSI C's asctime() format
4181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     *
4281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * with following variations
4381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     *
4481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy, DD-Mon-YYYY HH:MM:SS GMT
4581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy, (SP)D Mon YYYY HH:MM:SS GMT
4681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy,DD Mon YYYY HH:MM:SS GMT
4781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy, DD-Mon-YY HH:MM:SS GMT
4881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy, DD Mon YYYY HH:MM:SS -HHMM
4981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy, DD Mon YYYY HH:MM:SS
5081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy Mon (SP)D HH:MM:SS YYYY
5181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Wdy Mon DD HH:MM:SS YYYY GMT
5281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     *
5381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * HH can be H if the first digit is zero.
5481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     *
5581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * Mon can be the full name of the month.
5681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     */
5781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    private static final String HTTP_DATE_RFC_REGEXP =
5881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            "([0-9]{1,2})[- ]([A-Za-z]{3,9})[- ]([0-9]{2,4})[ ]"
5981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])";
6081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
6181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    private static final String HTTP_DATE_ANSIC_REGEXP =
6281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            "[ ]([A-Za-z]{3,9})[ ]+([0-9]{1,2})[ ]"
6381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            + "([0-9]{1,2}:[0-9][0-9]:[0-9][0-9])[ ]([0-9]{2,4})";
6481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
6581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    /**
6681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * The compiled version of the HTTP-date regular expressions.
6781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     */
6881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    private static final Pattern HTTP_DATE_RFC_PATTERN =
6981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            Pattern.compile(HTTP_DATE_RFC_REGEXP);
7081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    private static final Pattern HTTP_DATE_ANSIC_PATTERN =
7181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            Pattern.compile(HTTP_DATE_ANSIC_REGEXP);
7281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
7381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    private static class TimeOfDay {
7481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        TimeOfDay(int h, int m, int s) {
7581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            this.hour = h;
7681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            this.minute = m;
7781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            this.second = s;
7881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        }
7981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
8081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int hour;
8181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int minute;
8281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int second;
8381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    }
8481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
8581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    public static long parse(String timeString)
8681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            throws IllegalArgumentException {
8781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
8881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int date = 1;
8981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int month = Calendar.JANUARY;
9081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int year = 1970;
9181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        TimeOfDay timeOfDay;
9281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
9381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        Matcher rfcMatcher = HTTP_DATE_RFC_PATTERN.matcher(timeString);
9481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        if (rfcMatcher.find()) {
9581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            date = getDate(rfcMatcher.group(1));
9681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            month = getMonth(rfcMatcher.group(2));
9781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            year = getYear(rfcMatcher.group(3));
9881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            timeOfDay = getTime(rfcMatcher.group(4));
9981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        } else {
10081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            Matcher ansicMatcher = HTTP_DATE_ANSIC_PATTERN.matcher(timeString);
10181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            if (ansicMatcher.find()) {
10281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                month = getMonth(ansicMatcher.group(1));
10381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                date = getDate(ansicMatcher.group(2));
10481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                timeOfDay = getTime(ansicMatcher.group(3));
10581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                year = getYear(ansicMatcher.group(4));
10681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            } else {
10781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                throw new IllegalArgumentException();
10881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            }
10981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        }
11081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
11181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        // FIXME: Y2038 BUG!
11281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        if (year >= 2038) {
11381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            year = 2038;
11481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            month = Calendar.JANUARY;
11581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            date = 1;
11681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        }
11781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
11881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        Time time = new Time(Time.TIMEZONE_UTC);
11981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        time.set(timeOfDay.second, timeOfDay.minute, timeOfDay.hour, date,
12081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                month, year);
12181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        return time.toMillis(false /* use isDst */);
12281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    }
12381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
12481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    private static int getDate(String dateString) {
12581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        if (dateString.length() == 2) {
12681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            return (dateString.charAt(0) - '0') * 10
12781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                    + (dateString.charAt(1) - '0');
12881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        } else {
12981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            return (dateString.charAt(0) - '0');
13081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        }
13181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    }
13281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
13381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    /*
13481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * jan = 9 + 0 + 13 = 22
13581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * feb = 5 + 4 + 1 = 10
13681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * mar = 12 + 0 + 17 = 29
13781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * apr = 0 + 15 + 17 = 32
13881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * may = 12 + 0 + 24 = 36
13981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * jun = 9 + 20 + 13 = 42
14081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * jul = 9 + 20 + 11 = 40
14181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * aug = 0 + 20 + 6 = 26
14281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * sep = 18 + 4 + 15 = 37
14381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * oct = 14 + 2 + 19 = 35
14481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * nov = 13 + 14 + 21 = 48
14581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     * dec = 3 + 4 + 2 = 9
14681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath     */
14781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    private static int getMonth(String monthString) {
14881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int hash = Character.toLowerCase(monthString.charAt(0)) +
14981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                Character.toLowerCase(monthString.charAt(1)) +
15081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                Character.toLowerCase(monthString.charAt(2)) - 3 * 'a';
15181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        switch (hash) {
15281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 22:
15381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.JANUARY;
15481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 10:
15581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.FEBRUARY;
15681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 29:
15781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.MARCH;
15881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 32:
15981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.APRIL;
16081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 36:
16181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.MAY;
16281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 42:
16381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.JUNE;
16481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 40:
16581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.JULY;
16681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 26:
16781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.AUGUST;
16881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 37:
16981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.SEPTEMBER;
17081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 35:
17181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.OCTOBER;
17281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 48:
17381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.NOVEMBER;
17481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            case 9:
17581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return Calendar.DECEMBER;
17681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            default:
17781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                throw new IllegalArgumentException();
17881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        }
17981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    }
18081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
18181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    private static int getYear(String yearString) {
18281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        if (yearString.length() == 2) {
18381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            int year = (yearString.charAt(0) - '0') * 10
18481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                    + (yearString.charAt(1) - '0');
18581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            if (year >= 70) {
18681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return year + 1900;
18781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            } else {
18881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                return year + 2000;
18981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            }
19081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        } else if (yearString.length() == 3) {
19181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            // According to RFC 2822, three digit years should be added to 1900.
19281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            int year = (yearString.charAt(0) - '0') * 100
19381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                    + (yearString.charAt(1) - '0') * 10
19481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                    + (yearString.charAt(2) - '0');
19581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            return year + 1900;
19681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        } else if (yearString.length() == 4) {
19781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath             return (yearString.charAt(0) - '0') * 1000
19881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                    + (yearString.charAt(1) - '0') * 100
19981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                    + (yearString.charAt(2) - '0') * 10
20081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                    + (yearString.charAt(3) - '0');
20181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        } else {
20281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath             return 1970;
20381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        }
20481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    }
20581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
20681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    private static TimeOfDay getTime(String timeString) {
20781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        // HH might be H
20881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int i = 0;
20981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int hour = timeString.charAt(i++) - '0';
21081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        if (timeString.charAt(i) != ':')
21181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath            hour = hour * 10 + (timeString.charAt(i++) - '0');
21281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        // Skip ':'
21381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        i++;
21481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
21581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int minute = (timeString.charAt(i++) - '0') * 10
21681d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                    + (timeString.charAt(i++) - '0');
21781d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        // Skip ':'
21881d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        i++;
21981d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
22081d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        int second = (timeString.charAt(i++) - '0') * 10
22181d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath                  + (timeString.charAt(i++) - '0');
22281d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath
22381d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath        return new TimeOfDay(hour, minute, second);
22481d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath    }
22581d4875bd9a69efb1aa59ce0dab2ce5449c3448eNarayan Kamath}
226