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