1/* //device/content/providers/pim/Duration.java
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18package com.android.providers.calendar;
19
20import com.android.calendarcommon.DateException;
21import java.util.Calendar;
22
23/**
24 * According to RFC2445, durations are like this:
25 *       WEEKS
26 *     | DAYS [ HOURS [ MINUTES [ SECONDS ] ] ]
27 *     | HOURS [ MINUTES [ SECONDS ] ]
28 * it doesn't specifically, say, but this sort of implies that you can't have
29 * 70 seconds.
30 */
31public class Duration
32{
33    public int sign; // 1 or -1
34    public int weeks;
35    public int days;
36    public int hours;
37    public int minutes;
38    public int seconds;
39
40    public Duration()
41    {
42        sign = 1;
43    }
44
45    /**
46     * Parse according to RFC2445 ss4.3.6.  (It's actually a little loose with
47     * its parsing, for better or for worse)
48     */
49    public void parse(String str) throws DateException
50    {
51        sign = 1;
52        weeks = 0;
53        days = 0;
54        hours = 0;
55        minutes = 0;
56        seconds = 0;
57
58        int len = str.length();
59        int index = 0;
60        char c;
61
62        if (len < 1) {
63            return ;
64        }
65
66        c = str.charAt(0);
67        if (c == '-') {
68            sign = -1;
69            index++;
70        }
71        else if (c == '+') {
72            index++;
73        }
74
75        if (len < index) {
76            return ;
77        }
78
79        c = str.charAt(index);
80        if (c != 'P') {
81            throw new DateException (
82                    "Duration.parse(str='" + str + "') expected 'P' at index="
83                    + index);
84        }
85        index++;
86
87        int n = 0;
88        for (; index < len; index++) {
89            c = str.charAt(index);
90            if (c >= '0' && c <= '9') {
91                n *= 10;
92                n += ((int)(c-'0'));
93            }
94            else if (c == 'W') {
95                weeks = n;
96                n = 0;
97            }
98            else if (c == 'H') {
99                hours = n;
100                n = 0;
101            }
102            else if (c == 'M') {
103                minutes = n;
104                n = 0;
105            }
106            else if (c == 'S') {
107                seconds = n;
108                n = 0;
109            }
110            else if (c == 'D') {
111                days = n;
112                n = 0;
113            }
114            else if (c == 'T') {
115            }
116            else {
117                throw new DateException (
118                        "Duration.parse(str='" + str + "') unexpected char '"
119                        + c + "' at index=" + index);
120            }
121        }
122    }
123
124    /**
125     * Add this to the calendar provided, in place, in the calendar.
126     */
127    public void addTo(Calendar cal)
128    {
129        cal.add(Calendar.DAY_OF_MONTH, sign*weeks*7);
130        cal.add(Calendar.DAY_OF_MONTH, sign*days);
131        cal.add(Calendar.HOUR, sign*hours);
132        cal.add(Calendar.MINUTE, sign*minutes);
133        cal.add(Calendar.SECOND, sign*seconds);
134    }
135
136    public long addTo(long dt) {
137        return dt + getMillis();
138    }
139
140    public long getMillis() {
141        long factor = 1000 * sign;
142        return factor * ((7*24*60*60*weeks)
143                + (24*60*60*days)
144                + (60*60*hours)
145                + (60*minutes)
146                + seconds);
147    }
148}
149