1dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank/* Copyright 2010, The Android Open Source Project
2dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank **
3dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank ** Licensed under the Apache License, Version 2.0 (the "License");
4dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank ** you may not use this file except in compliance with the License.
5dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank ** You may obtain a copy of the License at
6dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank **
7dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank **     http://www.apache.org/licenses/LICENSE-2.0
8dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank **
9dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank ** Unless required by applicable law or agreed to in writing, software
10dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank ** distributed under the License is distributed on an "AS IS" BASIS,
11dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank ** See the License for the specific language governing permissions and
13dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank ** limitations under the License.
14dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank */
15dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
16dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blankpackage com.android.exchange.utility;
17dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
188068c99945661c7a32d3ae45e3a630d165fa2e3fMakoto Onukiimport java.text.ParseException;
19dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blankimport java.util.Calendar;
20dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
21dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank/**
22dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank * Note: This class was simply copied from the class in CalendarProvider, since we don't have access
23dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank * to it from the Email app.  I reformated some lines, but otherwise haven't altered the code.
24dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank */
25dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blankpublic class Duration {
26dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public int sign; // 1 or -1
27dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public int weeks;
28dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public int days;
29dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public int hours;
30dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public int minutes;
31dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public int seconds;
32dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
33dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public Duration() {
34dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        sign = 1;
35dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    }
36dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
37dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    /**
38dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank     * Parse according to RFC2445 ss4.3.6.  (It's actually a little loose with
39dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank     * its parsing, for better or for worse)
40dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank     */
418068c99945661c7a32d3ae45e3a630d165fa2e3fMakoto Onuki    public void parse(String str) throws ParseException {
42dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        sign = 1;
43dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        weeks = 0;
44dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        days = 0;
45dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        hours = 0;
46dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        minutes = 0;
47dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        seconds = 0;
48dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
49dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        int len = str.length();
50dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        int index = 0;
51dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        char c;
52dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
53dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        if (len < 1) {
54dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            return;
55dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        }
56dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
57dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        c = str.charAt(0);
58dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        if (c == '-') {
59dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            sign = -1;
60dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            index++;
61dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        } else if (c == '+') {
62dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            index++;
63dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        }
64dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
65dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        if (len < index) {
66dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            return;
67dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        }
68dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
69dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        c = str.charAt(index);
70dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        if (c != 'P') {
718068c99945661c7a32d3ae45e3a630d165fa2e3fMakoto Onuki            throw new ParseException (
72dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                    "Duration.parse(str='" + str + "') expected 'P' at index="
738068c99945661c7a32d3ae45e3a630d165fa2e3fMakoto Onuki                    + index, index);
74dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        }
75dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        index++;
76dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
77dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        int n = 0;
78dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        for (; index < len; index++) {
79dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            c = str.charAt(index);
80dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            if (c >= '0' && c <= '9') {
81dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                n *= 10;
82dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                n += (c - '0');
83dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            } else if (c == 'W') {
84dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                weeks = n;
85dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                n = 0;
86dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            } else if (c == 'H') {
87dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                hours = n;
88dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                n = 0;
89dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            } else if (c == 'M') {
90dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                minutes = n;
91dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                n = 0;
92dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            } else if (c == 'S') {
93dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                seconds = n;
94dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                n = 0;
95dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            } else if (c == 'D') {
96dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                days = n;
97dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                n = 0;
98dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            } else if (c == 'T') {
99dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            } else {
1008068c99945661c7a32d3ae45e3a630d165fa2e3fMakoto Onuki                throw new ParseException (
101dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                        "Duration.parse(str='" + str + "') unexpected char '"
1028068c99945661c7a32d3ae45e3a630d165fa2e3fMakoto Onuki                        + c + "' at index=" + index, index);
103dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank            }
104dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        }
105dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    }
106dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
107dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    /**
108dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank     * Add this to the calendar provided, in place, in the calendar.
109dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank     */
110dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public void addTo(Calendar cal) {
111dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        cal.add(Calendar.DAY_OF_MONTH, sign*weeks*7);
112dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        cal.add(Calendar.DAY_OF_MONTH, sign*days);
113dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        cal.add(Calendar.HOUR, sign*hours);
114dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        cal.add(Calendar.MINUTE, sign*minutes);
115dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        cal.add(Calendar.SECOND, sign*seconds);
116dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    }
117dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
118dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public long addTo(long dt) {
119dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        return dt + getMillis();
120dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    }
121dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank
122dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    public long getMillis() {
123dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        long factor = 1000 * sign;
124dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank        return factor * ((7*24*60*60*weeks) + (24*60*60*days) + (60*60*hours) + (60*minutes) +
125dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank                seconds);
126dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank    }
127dc6930c0b36950d420c8da0e70164c5c4e083fbeMarc Blank}
128