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        c = str.charAt(index);
85        if (c == 'T') {
86            index++;
87        }
88
89        int n = 0;
90        for (; index < len; index++) {
91            c = str.charAt(index);
92            if (c >= '0' && c <= '9') {
93                n *= 10;
94                n += ((int)(c-'0'));
95            }
96            else if (c == 'W') {
97                weeks = n;
98                n = 0;
99            }
100            else if (c == 'H') {
101                hours = n;
102                n = 0;
103            }
104            else if (c == 'M') {
105                minutes = n;
106                n = 0;
107            }
108            else if (c == 'S') {
109                seconds = n;
110                n = 0;
111            }
112            else if (c == 'D') {
113                days = n;
114                n = 0;
115            }
116            else if (c == 'T') {
117            }
118            else {
119                throw new DateException (
120                        "Duration.parse(str='" + str + "') unexpected char '"
121                        + c + "' at index=" + index);
122            }
123        }
124    }
125
126    /**
127     * Add this to the calendar provided, in place, in the calendar.
128     */
129    public void addTo(Calendar cal)
130    {
131        cal.add(Calendar.DAY_OF_MONTH, sign*weeks*7);
132        cal.add(Calendar.DAY_OF_MONTH, sign*days);
133        cal.add(Calendar.HOUR, sign*hours);
134        cal.add(Calendar.MINUTE, sign*minutes);
135        cal.add(Calendar.SECOND, sign*seconds);
136    }
137
138    public long addTo(long dt) {
139        return dt + getMillis();
140    }
141
142    public long getMillis() {
143        long factor = 1000 * sign;
144        return factor * ((7*24*60*60*weeks)
145                + (24*60*60*days)
146                + (60*60*hours)
147                + (60*minutes)
148                + seconds);
149    }
150}
151