11244d7e1990844869add117638bead206077372fMichael Chan/*
21244d7e1990844869add117638bead206077372fMichael Chan * Copyright (C) 2011 The Android Open Source Project
31244d7e1990844869add117638bead206077372fMichael Chan *
41244d7e1990844869add117638bead206077372fMichael Chan * Licensed under the Apache License, Version 2.0 (the "License");
51244d7e1990844869add117638bead206077372fMichael Chan * you may not use this file except in compliance with the License.
61244d7e1990844869add117638bead206077372fMichael Chan * You may obtain a copy of the License at
71244d7e1990844869add117638bead206077372fMichael Chan *
81244d7e1990844869add117638bead206077372fMichael Chan *      http://www.apache.org/licenses/LICENSE-2.0
91244d7e1990844869add117638bead206077372fMichael Chan *
101244d7e1990844869add117638bead206077372fMichael Chan * Unless required by applicable law or agreed to in writing, software
111244d7e1990844869add117638bead206077372fMichael Chan * distributed under the License is distributed on an "AS IS" BASIS,
121244d7e1990844869add117638bead206077372fMichael Chan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131244d7e1990844869add117638bead206077372fMichael Chan * See the License for the specific language governing permissions and
141244d7e1990844869add117638bead206077372fMichael Chan * limitations under the License.
151244d7e1990844869add117638bead206077372fMichael Chan */
161244d7e1990844869add117638bead206077372fMichael Chan
171244d7e1990844869add117638bead206077372fMichael Chanpackage com.android.calendar;
181244d7e1990844869add117638bead206077372fMichael Chan
191244d7e1990844869add117638bead206077372fMichael Chanimport com.android.calendarcommon.DateException;
201244d7e1990844869add117638bead206077372fMichael Chanimport java.util.Calendar;
211244d7e1990844869add117638bead206077372fMichael Chan
221244d7e1990844869add117638bead206077372fMichael Chan/**
231244d7e1990844869add117638bead206077372fMichael Chan *
241244d7e1990844869add117638bead206077372fMichael Chan * Dup of packages/providers/CalendarProvider/src/com/android/providers/calendar/Duration.java
251244d7e1990844869add117638bead206077372fMichael Chan *
261244d7e1990844869add117638bead206077372fMichael Chan * According to RFC2445, durations are like this:
271244d7e1990844869add117638bead206077372fMichael Chan *       WEEKS
281244d7e1990844869add117638bead206077372fMichael Chan *     | DAYS [ HOURS [ MINUTES [ SECONDS ] ] ]
291244d7e1990844869add117638bead206077372fMichael Chan *     | HOURS [ MINUTES [ SECONDS ] ]
301244d7e1990844869add117638bead206077372fMichael Chan * it doesn't specifically, say, but this sort of implies that you can't have
311244d7e1990844869add117638bead206077372fMichael Chan * 70 seconds.
321244d7e1990844869add117638bead206077372fMichael Chan */
331244d7e1990844869add117638bead206077372fMichael Chanpublic class Duration
341244d7e1990844869add117638bead206077372fMichael Chan{
351244d7e1990844869add117638bead206077372fMichael Chan    public int sign; // 1 or -1
361244d7e1990844869add117638bead206077372fMichael Chan    public int weeks;
371244d7e1990844869add117638bead206077372fMichael Chan    public int days;
381244d7e1990844869add117638bead206077372fMichael Chan    public int hours;
391244d7e1990844869add117638bead206077372fMichael Chan    public int minutes;
401244d7e1990844869add117638bead206077372fMichael Chan    public int seconds;
411244d7e1990844869add117638bead206077372fMichael Chan
421244d7e1990844869add117638bead206077372fMichael Chan    public Duration()
431244d7e1990844869add117638bead206077372fMichael Chan    {
441244d7e1990844869add117638bead206077372fMichael Chan        sign = 1;
451244d7e1990844869add117638bead206077372fMichael Chan    }
461244d7e1990844869add117638bead206077372fMichael Chan
471244d7e1990844869add117638bead206077372fMichael Chan    /**
481244d7e1990844869add117638bead206077372fMichael Chan     * Parse according to RFC2445 ss4.3.6.  (It's actually a little loose with
491244d7e1990844869add117638bead206077372fMichael Chan     * its parsing, for better or for worse)
501244d7e1990844869add117638bead206077372fMichael Chan     */
511244d7e1990844869add117638bead206077372fMichael Chan    public void parse(String str) throws DateException
521244d7e1990844869add117638bead206077372fMichael Chan    {
531244d7e1990844869add117638bead206077372fMichael Chan        sign = 1;
541244d7e1990844869add117638bead206077372fMichael Chan        weeks = 0;
551244d7e1990844869add117638bead206077372fMichael Chan        days = 0;
561244d7e1990844869add117638bead206077372fMichael Chan        hours = 0;
571244d7e1990844869add117638bead206077372fMichael Chan        minutes = 0;
581244d7e1990844869add117638bead206077372fMichael Chan        seconds = 0;
591244d7e1990844869add117638bead206077372fMichael Chan
601244d7e1990844869add117638bead206077372fMichael Chan        int len = str.length();
611244d7e1990844869add117638bead206077372fMichael Chan        int index = 0;
621244d7e1990844869add117638bead206077372fMichael Chan        char c;
631244d7e1990844869add117638bead206077372fMichael Chan
641244d7e1990844869add117638bead206077372fMichael Chan        if (len < 1) {
651244d7e1990844869add117638bead206077372fMichael Chan            return ;
661244d7e1990844869add117638bead206077372fMichael Chan        }
671244d7e1990844869add117638bead206077372fMichael Chan
681244d7e1990844869add117638bead206077372fMichael Chan        c = str.charAt(0);
691244d7e1990844869add117638bead206077372fMichael Chan        if (c == '-') {
701244d7e1990844869add117638bead206077372fMichael Chan            sign = -1;
711244d7e1990844869add117638bead206077372fMichael Chan            index++;
721244d7e1990844869add117638bead206077372fMichael Chan        }
731244d7e1990844869add117638bead206077372fMichael Chan        else if (c == '+') {
741244d7e1990844869add117638bead206077372fMichael Chan            index++;
751244d7e1990844869add117638bead206077372fMichael Chan        }
761244d7e1990844869add117638bead206077372fMichael Chan
771244d7e1990844869add117638bead206077372fMichael Chan        if (len < index) {
781244d7e1990844869add117638bead206077372fMichael Chan            return ;
791244d7e1990844869add117638bead206077372fMichael Chan        }
801244d7e1990844869add117638bead206077372fMichael Chan
811244d7e1990844869add117638bead206077372fMichael Chan        c = str.charAt(index);
821244d7e1990844869add117638bead206077372fMichael Chan        if (c != 'P') {
831244d7e1990844869add117638bead206077372fMichael Chan            throw new DateException (
841244d7e1990844869add117638bead206077372fMichael Chan                    "Duration.parse(str='" + str + "') expected 'P' at index="
851244d7e1990844869add117638bead206077372fMichael Chan                    + index);
861244d7e1990844869add117638bead206077372fMichael Chan        }
871244d7e1990844869add117638bead206077372fMichael Chan        index++;
881244d7e1990844869add117638bead206077372fMichael Chan
891244d7e1990844869add117638bead206077372fMichael Chan        int n = 0;
901244d7e1990844869add117638bead206077372fMichael Chan        for (; index < len; index++) {
911244d7e1990844869add117638bead206077372fMichael Chan            c = str.charAt(index);
921244d7e1990844869add117638bead206077372fMichael Chan            if (c >= '0' && c <= '9') {
931244d7e1990844869add117638bead206077372fMichael Chan                n *= 10;
941244d7e1990844869add117638bead206077372fMichael Chan                n += ((c-'0'));
951244d7e1990844869add117638bead206077372fMichael Chan            }
961244d7e1990844869add117638bead206077372fMichael Chan            else if (c == 'W') {
971244d7e1990844869add117638bead206077372fMichael Chan                weeks = n;
981244d7e1990844869add117638bead206077372fMichael Chan                n = 0;
991244d7e1990844869add117638bead206077372fMichael Chan            }
1001244d7e1990844869add117638bead206077372fMichael Chan            else if (c == 'H') {
1011244d7e1990844869add117638bead206077372fMichael Chan                hours = n;
1021244d7e1990844869add117638bead206077372fMichael Chan                n = 0;
1031244d7e1990844869add117638bead206077372fMichael Chan            }
1041244d7e1990844869add117638bead206077372fMichael Chan            else if (c == 'M') {
1051244d7e1990844869add117638bead206077372fMichael Chan                minutes = n;
1061244d7e1990844869add117638bead206077372fMichael Chan                n = 0;
1071244d7e1990844869add117638bead206077372fMichael Chan            }
1081244d7e1990844869add117638bead206077372fMichael Chan            else if (c == 'S') {
1091244d7e1990844869add117638bead206077372fMichael Chan                seconds = n;
1101244d7e1990844869add117638bead206077372fMichael Chan                n = 0;
1111244d7e1990844869add117638bead206077372fMichael Chan            }
1121244d7e1990844869add117638bead206077372fMichael Chan            else if (c == 'D') {
1131244d7e1990844869add117638bead206077372fMichael Chan                days = n;
1141244d7e1990844869add117638bead206077372fMichael Chan                n = 0;
1151244d7e1990844869add117638bead206077372fMichael Chan            }
1161244d7e1990844869add117638bead206077372fMichael Chan            else if (c == 'T') {
1171244d7e1990844869add117638bead206077372fMichael Chan            }
1181244d7e1990844869add117638bead206077372fMichael Chan            else {
1191244d7e1990844869add117638bead206077372fMichael Chan                throw new DateException (
1201244d7e1990844869add117638bead206077372fMichael Chan                        "Duration.parse(str='" + str + "') unexpected char '"
1211244d7e1990844869add117638bead206077372fMichael Chan                        + c + "' at index=" + index);
1221244d7e1990844869add117638bead206077372fMichael Chan            }
1231244d7e1990844869add117638bead206077372fMichael Chan        }
1241244d7e1990844869add117638bead206077372fMichael Chan    }
1251244d7e1990844869add117638bead206077372fMichael Chan
1261244d7e1990844869add117638bead206077372fMichael Chan    /**
1271244d7e1990844869add117638bead206077372fMichael Chan     * Add this to the calendar provided, in place, in the calendar.
1281244d7e1990844869add117638bead206077372fMichael Chan     */
1291244d7e1990844869add117638bead206077372fMichael Chan    public void addTo(Calendar cal)
1301244d7e1990844869add117638bead206077372fMichael Chan    {
1311244d7e1990844869add117638bead206077372fMichael Chan        cal.add(Calendar.DAY_OF_MONTH, sign*weeks*7);
1321244d7e1990844869add117638bead206077372fMichael Chan        cal.add(Calendar.DAY_OF_MONTH, sign*days);
1331244d7e1990844869add117638bead206077372fMichael Chan        cal.add(Calendar.HOUR, sign*hours);
1341244d7e1990844869add117638bead206077372fMichael Chan        cal.add(Calendar.MINUTE, sign*minutes);
1351244d7e1990844869add117638bead206077372fMichael Chan        cal.add(Calendar.SECOND, sign*seconds);
1361244d7e1990844869add117638bead206077372fMichael Chan    }
1371244d7e1990844869add117638bead206077372fMichael Chan
1381244d7e1990844869add117638bead206077372fMichael Chan    public long addTo(long dt) {
1391244d7e1990844869add117638bead206077372fMichael Chan        return dt + getMillis();
1401244d7e1990844869add117638bead206077372fMichael Chan    }
1411244d7e1990844869add117638bead206077372fMichael Chan
1421244d7e1990844869add117638bead206077372fMichael Chan    public long getMillis() {
1431244d7e1990844869add117638bead206077372fMichael Chan        long factor = 1000 * sign;
1441244d7e1990844869add117638bead206077372fMichael Chan        return factor * ((7*24*60*60*weeks)
1451244d7e1990844869add117638bead206077372fMichael Chan                + (24*60*60*days)
1461244d7e1990844869add117638bead206077372fMichael Chan                + (60*60*hours)
1471244d7e1990844869add117638bead206077372fMichael Chan                + (60*minutes)
1481244d7e1990844869add117638bead206077372fMichael Chan                + seconds);
1491244d7e1990844869add117638bead206077372fMichael Chan    }
1501244d7e1990844869add117638bead206077372fMichael Chan}
151