diff options
-rw-r--r-- | src/com/android/calendarcommon/Duration.java | 150 | ||||
-rw-r--r-- | tests/src/com/android/calendarcommon/DurationTest.java | 77 |
2 files changed, 227 insertions, 0 deletions
diff --git a/src/com/android/calendarcommon/Duration.java b/src/com/android/calendarcommon/Duration.java new file mode 100644 index 0000000..70fe89d --- /dev/null +++ b/src/com/android/calendarcommon/Duration.java @@ -0,0 +1,150 @@ +/* +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package com.android.calendarcommon; + +import java.util.Calendar; + +/** + * According to RFC2445, durations are like this: + * WEEKS + * | DAYS [ HOURS [ MINUTES [ SECONDS ] ] ] + * | HOURS [ MINUTES [ SECONDS ] ] + * it doesn't specifically, say, but this sort of implies that you can't have + * 70 seconds. + */ +public class Duration +{ + public int sign; // 1 or -1 + public int weeks; + public int days; + public int hours; + public int minutes; + public int seconds; + + public Duration() + { + sign = 1; + } + + /** + * Parse according to RFC2445 ss4.3.6. (It's actually a little loose with + * its parsing, for better or for worse) + */ + public void parse(String str) throws DateException + { + sign = 1; + weeks = 0; + days = 0; + hours = 0; + minutes = 0; + seconds = 0; + + int len = str.length(); + int index = 0; + char c; + + if (len < 1) { + return ; + } + + c = str.charAt(0); + if (c == '-') { + sign = -1; + index++; + } + else if (c == '+') { + index++; + } + + if (len < index) { + return ; + } + + c = str.charAt(index); + if (c != 'P') { + throw new DateException ( + "Duration.parse(str='" + str + "') expected 'P' at index=" + + index); + } + index++; + c = str.charAt(index); + if (c == 'T') { + index++; + } + + int n = 0; + for (; index < len; index++) { + c = str.charAt(index); + if (c >= '0' && c <= '9') { + n *= 10; + n += ((int)(c-'0')); + } + else if (c == 'W') { + weeks = n; + n = 0; + } + else if (c == 'H') { + hours = n; + n = 0; + } + else if (c == 'M') { + minutes = n; + n = 0; + } + else if (c == 'S') { + seconds = n; + n = 0; + } + else if (c == 'D') { + days = n; + n = 0; + } + else if (c == 'T') { + } + else { + throw new DateException ( + "Duration.parse(str='" + str + "') unexpected char '" + + c + "' at index=" + index); + } + } + } + + /** + * Add this to the calendar provided, in place, in the calendar. + */ + public void addTo(Calendar cal) + { + cal.add(Calendar.DAY_OF_MONTH, sign*weeks*7); + cal.add(Calendar.DAY_OF_MONTH, sign*days); + cal.add(Calendar.HOUR, sign*hours); + cal.add(Calendar.MINUTE, sign*minutes); + cal.add(Calendar.SECOND, sign*seconds); + } + + public long addTo(long dt) { + return dt + getMillis(); + } + + public long getMillis() { + long factor = 1000 * sign; + return factor * ((7*24*60*60*weeks) + + (24*60*60*days) + + (60*60*hours) + + (60*minutes) + + seconds); + } +} diff --git a/tests/src/com/android/calendarcommon/DurationTest.java b/tests/src/com/android/calendarcommon/DurationTest.java new file mode 100644 index 0000000..b264713 --- /dev/null +++ b/tests/src/com/android/calendarcommon/DurationTest.java @@ -0,0 +1,77 @@ +/* //device/content/providers/pim/DurationTest.java +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package com.android.calendarcommon; + +import junit.framework.TestCase; + +import android.test.suitebuilder.annotation.SmallTest; + +public class DurationTest extends TestCase { + + private void verifyDuration(String str, + int sign, int weeks, int days, int hours, + int minutes, int seconds) throws DateException { + + Duration duration = new Duration(); + duration.parse(str); + + assertEquals("Duration sign is not equal for " + str, sign, duration.sign); + assertEquals("Duration weeks is not equal for " + str, weeks, duration.weeks); + assertEquals("Duration days is not equal for " + str, days, duration.days); + assertEquals("Duration hours is not equal for " + str, hours, duration.hours); + assertEquals("Duration minutes is not equal for " + str, minutes, duration.minutes); + assertEquals("Duration seconds is not equal for " + str, seconds, duration.seconds); + } + + @SmallTest + public void testParse() throws Exception { + verifyDuration("P7W", 1, 7, 0, 0, 0, 0); + verifyDuration("PT7W", 1, 7, 0, 0, 0, 0); + verifyDuration("-PT7W", -1, 7, 0, 0, 0, 0); + verifyDuration("P15DT5H0M20S", 1, 0, 15, 5, 0, 20); + verifyDuration("-P15DT5H0M20S", -1, 0, 15, 5, 0, 20); + verifyDuration("PT1H2M3S", 1, 0, 0, 1, 2, 3); + + verifyDuration("", 1, 0, 0, 0, 0, 0); + verifyDuration("P", 1, 0, 0, 0, 0, 0); + verifyDuration("P0W", 1, 0, 0, 0, 0, 0); + verifyDuration("P0D", 1, 0, 0, 0, 0, 0); + verifyDuration("PT0H0M0S", 1, 0, 0, 0, 0, 0); + verifyDuration("P0DT0H0M0S", 1, 0, 0, 0, 0, 0); + } + + @SmallTest + public void testParseInvalidStrings() throws Exception { + try { + verifyDuration(" -P15DT5H0M20S", 0, 0, 0, 0, 0, 0); + fail("test didn't throw an exception but we expected it to"); + } catch (DateException e) { + // expected + } + + try { + verifyDuration(" not even close", 0, 0, 0, 0, 0, 0); + fail("test didn't throw an exception but we expected it to"); + } catch (DateException e) { + // expected + } + } +} + + + |