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 
17 package com.android.calendarcommon2;
18 
19 import 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  */
29 public 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 
Duration()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      */
parse(String str)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      */
addTo(Calendar cal)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 
addTo(long dt)141     public long addTo(long dt) {
142         return dt + getMillis();
143     }
144 
getMillis()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