Home | History | Annotate | Download | only in calendarcommon
      1 /* //device/content/providers/pim/RecurrenceProcessorTest.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 
     18 package com.android.calendarcommon;
     19 
     20 import android.os.Debug;
     21 import android.test.suitebuilder.annotation.LargeTest;
     22 import android.test.suitebuilder.annotation.MediumTest;
     23 import android.test.suitebuilder.annotation.SmallTest;
     24 import android.text.TextUtils;
     25 import android.text.format.Time;
     26 import android.util.Log;
     27 import android.util.TimeFormatException;
     28 import junit.framework.TestCase;
     29 
     30 import java.util.TreeSet;
     31 
     32 public class RecurrenceProcessorTest extends TestCase {
     33     private static final String TAG = "RecurrenceProcessorTest";
     34     private static final boolean SPEW = true;
     35     private static final boolean METHOD_TRACE = false;
     36 
     37     private static String[] getFormattedDates(long[] dates, Time time) {
     38         String[] out = new String[dates.length];
     39         int i = 0;
     40         for (long date : dates) {
     41             time.set(date);
     42             out[i] = time.format2445();
     43             ++i;
     44         }
     45         return out;
     46     }
     47 
     48     private static void printLists(String[] expected, String[] out) {
     49         Log.i(TAG, "        expected        out");
     50         int i;
     51         for (i = 0; i < expected.length && i < out.length; i++) {
     52             Log.i(TAG, "  [" + i + "] " + expected[i]
     53                     + "  " + out[i]);
     54         }
     55         for (; i < expected.length; i++) {
     56             Log.i(TAG, "  [" + i + "] " + expected[i]);
     57         }
     58         for (; i < out.length; i++) {
     59             Log.i(TAG, "  [" + i + "]                   " + out[i]);
     60         }
     61     }
     62 
     63     public void verifyRecurrence(String dtstartStr, String rrule, String rdate, String exrule,
     64             String exdate, String rangeStartStr, String rangeEndStr, String[] expected)
     65             throws Exception {
     66         verifyRecurrence(dtstartStr, rrule, rdate, exrule, exdate, rangeStartStr,
     67                 rangeEndStr, expected, expected[expected.length - 1]);
     68     }
     69 
     70     public void verifyRecurrence(String dtstartStr, String rrule, String rdate, String exrule,
     71             String exdate, String rangeStartStr, String rangeEndStr, String[] expected,
     72             String last) throws Exception {
     73 
     74         // note that the zulu of all parameters here must be the same, expand
     75         // doesn't work otherwise
     76 
     77         if (SPEW) {
     78             Log.i(TAG, "DTSTART:" + dtstartStr
     79                     + " RRULE:" + rrule
     80                     + " RDATE:" + rdate
     81                     + " EXRULE:" + exrule
     82                     + " EXDATE:" + exdate);
     83         }
     84 
     85         // we could use any timezone, incl. UTC, but we use a non-UTC
     86         // timezone to make sure there are no UTC assumptions in the
     87         // recurrence processing code.
     88         String tz = "America/Los_Angeles";
     89         Time dtstart = new Time(tz);
     90         Time rangeStart = new Time(tz);
     91         Time rangeEnd = new Time(tz);
     92         Time outCal = new Time(tz);
     93 
     94         dtstart.parse(dtstartStr);
     95 
     96         rangeStart.parse(rangeStartStr);
     97         rangeEnd.parse(rangeEndStr);
     98 
     99         if (METHOD_TRACE) {
    100             String fn = "/tmp/trace/" + this.getClass().getName().replace('$', '_');
    101             String df = fn + ".data";
    102             String kf = fn + ".key";
    103             Debug.startMethodTracing(fn, 8 * 1024 * 1024);
    104         }
    105 
    106         RecurrenceProcessor rp = new RecurrenceProcessor();
    107         RecurrenceSet recur = new RecurrenceSet(rrule, rdate, exrule, exdate);
    108 
    109         long[] out = rp.expand(dtstart, recur, rangeStart.toMillis(false /* use isDst */),
    110                 rangeEnd.toMillis(false /* use isDst */));
    111 
    112         if (METHOD_TRACE) {
    113             Debug.stopMethodTracing();
    114         }
    115 
    116         int count = out.length;
    117         String[] actual = getFormattedDates(out, outCal);
    118 
    119         if (count != expected.length) {
    120             if (SPEW) {
    121                 Log.i(TAG, "DTSTART:" + dtstartStr + " RRULE:" + rrule);
    122                 printLists(expected, actual);
    123             }
    124             throw new RuntimeException("result lengths don't match.  "
    125                     + " expected=" + expected.length
    126                     + " actual=" + count);
    127         }
    128 
    129         for (int i = 0; i < count; i++) {
    130             String s = actual[i];
    131             if (!s.equals(expected[i])) {
    132                 if (SPEW) {
    133                     Log.i(TAG, "DTSTART:" + dtstartStr + " RRULE:" + rrule);
    134                     printLists(expected, actual);
    135                     Log.i(TAG, "i=" + i);
    136                 }
    137                 throw new RuntimeException("expected[" + i + "]="
    138                         + expected[i] + " actual=" + actual[i]);
    139             }
    140         }
    141 
    142         long lastOccur = rp.getLastOccurence(dtstart, rangeEnd, recur);
    143         if (lastOccur == 0 && out.length == 0) {
    144             // No occurrence found and 0 returned for lastOccur, this is ok.
    145             return;
    146         }
    147         long lastMillis = -1;
    148         long expectedMillis = -1;
    149         String lastStr = "";
    150         if (lastOccur != -1) {
    151             outCal.set(lastOccur);
    152             lastStr = outCal.format2445();
    153             lastMillis = outCal.toMillis(true /* ignore isDst */);
    154         }
    155         if (last != null && last.length() > 0) {
    156             Time expectedLast = new Time(tz);
    157             expectedLast.parse(last);
    158             expectedMillis = expectedLast.toMillis(true /* ignore isDst */);
    159         }
    160         if (lastMillis != expectedMillis) {
    161             if (SPEW) {
    162                 Log.i(TAG, "DTSTART:" + dtstartStr + " RRULE:" + rrule);
    163                 Log.i(TAG, "Expected: " + last + "; Actual: " + lastStr);
    164                 printLists(expected, actual);
    165             }
    166 
    167             throw new RuntimeException("expected last occurrence date does not match."
    168                     + " expected=" + last
    169                     + " actual=" + lastStr);
    170         }
    171     }
    172 
    173     @SmallTest
    174     public void testMonthly0() throws Exception {
    175         verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3",
    176                 null /* rdate */, null /* exrule */, null /* exdate */,
    177                 "20060101T000000", "20080101T000000",
    178                 new String[]{
    179                         "20060205T100000",
    180                         "20060305T100000",
    181                         "20060405T100000"
    182                 });
    183     }
    184 
    185     @SmallTest
    186     public void testMonthly1() throws Exception {
    187         verifyRecurrence("20060205T100000", "FREQ=MONTHLY;INTERVAL=2;COUNT=3",
    188                 null /* rdate */, null /* exrule */, null /* exdate */,
    189                 "20060101T000000", "20080101T000000",
    190                 new String[]{
    191                         "20060205T100000",
    192                         "20060405T100000",
    193                         "20060605T100000"
    194                 });
    195     }
    196 
    197     @SmallTest
    198     public void testMonthly2() throws Exception {
    199         // this tests wrapping the year when the interval isn't divisible
    200         // by 12
    201         verifyRecurrence("20060205T100000", "FREQ=MONTHLY;INTERVAL=5;COUNT=5",
    202                 null /* rdate */, null /* exrule */, null /* exdate */,
    203                 "20060101T000000", "20080101T000000",
    204                 new String[]{
    205                         "20060205T100000",
    206                         "20060705T100000",
    207                         "20061205T100000",
    208                         "20070505T100000",
    209                         "20071005T100000"
    210                 });
    211     }
    212 
    213     @SmallTest
    214     public void testMonthly3() throws Exception {
    215         // with a simple BYDAY, spanning two months
    216         verifyRecurrence("20060104T123456",
    217                 "FREQ=MONTHLY;UNTIL=20060201T200000Z;BYDAY=TU,WE",
    218                 null /* rdate */, null /* exrule */, null /* exdate */,
    219                 "20060101T000000", "20080101T000000",
    220                 new String[]{
    221                         "20060104T123456",
    222                         "20060110T123456",
    223                         "20060111T123456",
    224                         "20060117T123456",
    225                         "20060118T123456",
    226                         "20060124T123456",
    227                         "20060125T123456",
    228                         "20060131T123456"
    229                 },
    230                 "20060201T120000");
    231     }
    232 
    233     @SmallTest
    234     public void testMonthly4() throws Exception {
    235         // with a BYDAY with +1 / etc., spanning two months and
    236         // one day which isn't in the result
    237         verifyRecurrence("20060101T123456",
    238                 "FREQ=MONTHLY;UNTIL=20060301T200000Z;BYDAY=+1SU,+2MO,+3TU,+4WE,+5MO,+5TU,+5WE,+6TH",
    239                 null /* rdate */, null /* exrule */, null /* exdate */,
    240                 "20060101T000000", "20080101T000000",
    241                 new String[]{
    242                         "20060101T123456",
    243                         "20060109T123456",
    244                         "20060117T123456",
    245                         "20060125T123456",
    246                         "20060130T123456",
    247                         "20060131T123456",
    248                         "20060205T123456",
    249                         "20060213T123456",
    250                         "20060221T123456",
    251                         "20060222T123456"
    252                 },
    253                 "20060301T120000");
    254     }
    255 
    256     @SmallTest
    257     public void testMonthly5() throws Exception {
    258         // with a BYDAY with -1 / etc.
    259         verifyRecurrence("20060201T123456",
    260                 "FREQ=MONTHLY;UNTIL=20060301T200000Z;BYDAY=-1SU,-2MO,-3TU,-4TU,-4WE,-5MO,-5TU,-5WE,-6TH",
    261                 null /* rdate */, null /* exrule */, null /* exdate */,
    262                 "20060101T000000", "20080101T000000",
    263                 new String[]{
    264                         "20060201T123456",
    265                         "20060207T123456",
    266                         "20060214T123456",
    267                         "20060220T123456",
    268                         "20060226T123456"
    269                 },
    270                 "20060301T120000");
    271     }
    272 
    273     @SmallTest
    274     public void testMonthly6() throws Exception {
    275         // With positive BYMONTHDAYs
    276         verifyRecurrence("20060201T123456",
    277                 "FREQ=MONTHLY;UNTIL=20060301T200000Z;BYMONTHDAY=1,2,5,28,31",
    278                 null /* rdate */, null /* exrule */, null /* exdate */,
    279                 "20060101T000000", "20080101T000000",
    280                 new String[]{
    281                         "20060201T123456",
    282                         "20060202T123456",
    283                         "20060205T123456",
    284                         "20060228T123456"
    285                 },
    286                 "20060301T120000");
    287     }
    288 
    289     @SmallTest
    290     public void testMonthly7() throws Exception {
    291         // With negative BYMONTHDAYs
    292         verifyRecurrence("20060201T123456",
    293                 "FREQ=MONTHLY;UNTIL=20060301T200000Z;BYMONTHDAY=-1,-5,-27,-28,-31",
    294                 null /* rdate */, null /* exrule */, null /* exdate */,
    295                 "20060101T000000", "20080101T000000",
    296                 new String[]{
    297                         "20060201T123456",
    298                         "20060202T123456",
    299                         "20060224T123456",
    300                         "20060228T123456"
    301                 },
    302                 "20060301T120000");
    303     }
    304 
    305     @SmallTest
    306     public void testMonthly8() throws Exception {
    307         verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3",
    308                 "America/Los_Angeles;20060207T140000,20060307T160000,20060407T180000",
    309                 null /* exrule */, null /* exdate */,
    310                 "20060101T000000", "20080101T000000",
    311                 new String[]{
    312                         "20060205T100000",
    313                         "20060207T140000",
    314                         "20060305T100000",
    315                         "20060307T160000",
    316                         "20060405T100000",
    317                         "20060407T180000",
    318                 });
    319     }
    320 
    321     @SmallTest
    322     public void testMonthly9() throws Exception {
    323         verifyRecurrence("20060205T100000", null /* rrule */,
    324                 "America/Los_Angeles;20060207T140000,20060307T160000,20060407T180000",
    325                 null /* exrule */, null /* exdate */,
    326                 "20060101T000000", "20080101T000000",
    327                 new String[]{
    328                         "20060207T140000",
    329                         "20060307T160000",
    330                         "20060407T180000",
    331                 });
    332     }
    333 
    334     @SmallTest
    335     public void testMonthly10() throws Exception {
    336         verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3\nFREQ=WEEKLY;COUNT=2",
    337                 "America/Los_Angeles;20060207T140000,20060307T160000,20060407T180000",
    338                 null /* exrule */, null /* exdate */,
    339                 "20060101T000000", "20080101T000000",
    340                 new String[]{
    341                         "20060205T100000",
    342                         "20060207T140000",
    343                         "20060212T100000",
    344                         "20060305T100000",
    345                         "20060307T160000",
    346                         "20060405T100000",
    347                         "20060407T180000",
    348                 });
    349     }
    350 
    351     @SmallTest
    352     public void testMonthly11() throws Exception {
    353         verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3\nFREQ=WEEKLY;COUNT=2",
    354                 null /* rdate */,
    355                 "FREQ=MONTHLY;COUNT=2", null /* exdate */,
    356                 "20060101T000000", "20080101T000000",
    357                 new String[]{
    358                         "20060212T100000",
    359                         "20060405T100000",
    360                 });
    361     }
    362 
    363     @SmallTest
    364     public void testMonthly12() throws Exception {
    365         verifyRecurrence("20060205T100000", "FREQ=MONTHLY;COUNT=3\nFREQ=WEEKLY;COUNT=2",
    366                 null /* rdate */, null /* exrule */,
    367                 "20060212T180000Z,20060405T170000Z" /* exdate */,
    368                 "20060101T000000", "20080101T000000",
    369                 new String[]{
    370                         "20060205T100000",
    371                         "20060305T100000",
    372                 });
    373     }
    374 
    375     @SmallTest
    376     public void testMonthly13() throws Exception {
    377         verifyRecurrence("20060101T100000", "FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13;COUNT=10",
    378                 null /* rdate */, null /* exrule */, null /* exdate */,
    379                 "20060101T000000", "20101231T000000",
    380                 new String[]{
    381                         "20060101T100000",
    382                         "20060113T100000",
    383                         "20061013T100000",
    384                         "20070413T100000",
    385                         "20070713T100000",
    386                         "20080613T100000",
    387                         "20090213T100000",
    388                         "20090313T100000",
    389                         "20091113T100000",
    390                         "20100813T100000",
    391                 });
    392     }
    393 
    394     @SmallTest
    395     public void testMonthly14() throws Exception {
    396         verifyRecurrence("20110103T100000", "FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1",
    397                 null /* rdate */, null /* exrule */, null /* exdate */,
    398                 "20110101T000000", "20110331T235959",
    399                 new String[]{
    400                 "20110103T100000",
    401                 "20110131T100000",
    402                 "20110201T100000",
    403                 "20110228T100000",
    404                 "20110301T100000",
    405                 "20110331T100000",
    406                 });
    407     }
    408 
    409     @SmallTest
    410     public void testMonthly15() throws Exception {
    411         verifyRecurrence("20110703T100000", "FREQ=MONTHLY;BYDAY=SA,SU;BYSETPOS=2,-2",
    412                 null /* rdate */, null /* exrule */, null /* exdate */,
    413                 "20110701T000000", "20110931T235959",
    414                 new String[]{
    415                 "20110703T100000",
    416                 "20110730T100000",
    417                 "20110807T100000",
    418                 "20110827T100000",
    419                 "20110904T100000",
    420                 "20110924T100000",
    421                 });
    422     }
    423 
    424     @SmallTest
    425     public void testWeekly0() throws Exception {
    426         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;COUNT=3",
    427                 null /* rdate */, null /* exrule */, null /* exdate */,
    428                 "20060101T000000", "20080101T000000",
    429                 new String[]{
    430                         "20060215T100000",
    431                         "20060222T100000",
    432                         "20060301T100000"
    433                 });
    434     }
    435 
    436     @SmallTest
    437     public void testWeekly1() throws Exception {
    438         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060301T100000Z",
    439                 null /* rdate */, null /* exrule */, null /* exdate */,
    440                 "20060101T000000", "20080101T000000",
    441                 new String[]{
    442                         "20060215T100000",
    443                         "20060222T100000"
    444                 }, "20060301T020000");
    445     }
    446 
    447     @SmallTest
    448     public void testWeekly2() throws Exception {
    449         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060301T100001Z",
    450                 null /* rdate */, null /* exrule */, null /* exdate */,
    451                 "20060101T000000", "20080101T000000",
    452                 new String[]{
    453                         "20060215T100000",
    454                         "20060222T100000"
    455                 }, "20060301T020001");
    456     }
    457 
    458     @SmallTest
    459     public void testWeekly3() throws Exception {
    460         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060301T090000Z",
    461                 null /* rdate */, null /* exrule */, null /* exdate */,
    462                 "20060101T000000", "20080101T000000",
    463                 new String[]{
    464                         "20060215T100000",
    465                         "20060222T100000"
    466                 }, "20060301T010000");
    467     }
    468 
    469     @SmallTest
    470     public void testWeekly4() throws Exception {
    471         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060311T100001Z;BYDAY=TU",
    472                 null /* rdate */, null /* exrule */, null /* exdate */,
    473                 "20060101T000000", "20080101T000000",
    474                 new String[]{
    475                         "20060215T100000",
    476                         "20060221T100000",
    477                         "20060228T100000",
    478                         "20060307T100000"
    479                 }, "20060311T020001");
    480     }
    481 
    482     // until without "Z"
    483     @SmallTest
    484     public void testWeekly4a() throws Exception {
    485         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060311T100001;BYDAY=TU",
    486                 null /* rdate */, null /* exrule */, null /* exdate */,
    487                 "20060101T000000", "20080101T000000",
    488                 new String[]{
    489                         "20060215T100000",
    490                         "20060221T100000",
    491                         "20060228T100000",
    492                         "20060307T100000"
    493                 }, "20060311T100001");
    494     }
    495 
    496     @SmallTest
    497     public void testWeekly5() throws Exception {
    498         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060311T100001Z;BYDAY=TH",
    499                 null /* rdate */, null /* exrule */, null /* exdate */,
    500                 "20060101T000000", "20080101T000000",
    501                 new String[]{
    502                         "20060215T100000",
    503                         "20060216T100000",
    504                         "20060223T100000",
    505                         "20060302T100000",
    506                         "20060309T100000"
    507                 }, "20060311T020001");
    508     }
    509 
    510     @SmallTest
    511     public void testWeekly6() throws Exception {
    512         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060309T100001Z;BYDAY=WE,TH",
    513                 null /* rdate */, null /* exrule */, null /* exdate */,
    514                 "20060101T000000", "20080101T000000",
    515                 new String[]{
    516                         "20060215T100000",
    517                         "20060216T100000",
    518                         "20060222T100000",
    519                         "20060223T100000",
    520                         "20060301T100000",
    521                         "20060302T100000",
    522                         "20060308T100000"
    523                 }, "20060309T020001");
    524     }
    525 
    526     @SmallTest
    527     public void testWeekly7() throws Exception {
    528         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060220T100001Z;BYDAY=SU",
    529                 null /* rdate */, null /* exrule */, null /* exdate */,
    530                 "20060101T000000", "20080101T000000",
    531                 new String[]{
    532                         "20060215T100000",
    533                         "20060219T100000"
    534                 }, "20060220T020001");
    535     }
    536 
    537     @SmallTest
    538     public void testWeekly8() throws Exception {
    539         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;COUNT=4;WKST=SU;BYDAY=TU,TH",
    540                 null /* rdate */, null /* exrule */, null /* exdate */,
    541                 "20060101T000000", "20080101T000000",
    542                 new String[]{
    543                         "20060215T100000",
    544                         "20060216T100000",
    545                         "20060221T100000",
    546                         "20060223T100000"
    547                 });
    548     }
    549 
    550     @SmallTest
    551     public void testWeekly9() throws Exception {
    552         verifyRecurrence("19970805T100000",
    553                 "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU",   // uses default WKST=MO
    554                 null /* rdate */, null /* exrule */, null /* exdate */,
    555                 "19970101T000000", "19980101T000000",
    556                 new String[]{
    557                         "19970805T100000",
    558                         "19970810T100000",
    559                         "19970819T100000",
    560                         "19970824T100000",
    561                 });
    562     }
    563 
    564     @SmallTest
    565     public void testWeekly10() throws Exception {
    566         verifyRecurrence("19970805T100000",
    567                 "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU",
    568                 null /* rdate */, null /* exrule */, null /* exdate */,
    569                 "19970101T000000", "19980101T000000",
    570                 new String[]{
    571                         "19970805T100000",
    572                         "19970817T100000",
    573                         "19970819T100000",
    574                         "19970831T100000",
    575                 });
    576     }
    577 
    578     // BUG 1658567: UNTIL=date
    579     @SmallTest
    580     public void testWeekly11() throws Exception {
    581         verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=20060220;BYDAY=SU",
    582                 null /* rdate */, null /* exrule */, null /* exdate */,
    583                 "20060101T000000", "20080101T000000",
    584                 new String[]{
    585                         "20060215T100000",
    586                         "20060219T100000"
    587                 }, "20060220T000000");
    588     }
    589 
    590     @SmallTest
    591     public void testWeekly12() throws Exception {
    592         try {
    593             verifyRecurrence("20060215T100000", "FREQ=WEEKLY;UNTIL=junk;BYDAY=SU",
    594                     null /* rdate */, null /* exrule */, null /* exdate */,
    595                     "20060101T000000", "20080101T000000",
    596                     new String[]{
    597                             "20060215T100000",
    598                             "20060219T100000"
    599                     }, "20060220T020001");
    600             fail("Bad UNTIL string failed to throw exception");
    601         } catch (TimeFormatException e) {
    602             // expected
    603         }
    604     }
    605 
    606     /**
    607      * Test repeating weekly event with dtstart and dtend (only one occurrence)
    608      * See bug #3267616
    609      * @throws Exception
    610      */
    611     @SmallTest
    612     public void testWeekly13() throws Exception {
    613         verifyRecurrence("20101117T150000",
    614                 "FREQ=WEEKLY;BYDAY=WE",
    615                 null /* rdate */, null /* exrule */, null /* exdate */,
    616                 "20101117T150000", "20101117T160000",
    617                 new String[]{ "20101117T150000" });
    618     }
    619 
    620     @SmallTest
    621     public void testWeekly14() throws Exception {
    622         verifyRecurrence("19970805T100000",
    623                 "FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=TH",
    624                 null /* rdate */, null /* exrule */, null /* exdate */,
    625                 "19970101T000000", "19980101T000000",
    626                 new String[]{
    627                         "19970805T100000",
    628                         "19970817T100000",
    629                         "19970819T100000",
    630                         "19970831T100000",
    631                 });
    632     }
    633 
    634     @SmallTest
    635     public void testDaily0() throws Exception {
    636         verifyRecurrence("20060215T100000", "FREQ=DAILY;COUNT=3",
    637                 null /* rdate */, null /* exrule */, null /* exdate */,
    638                 "20060101T000000", "20080101T000000",
    639                 new String[]{
    640                         "20060215T100000",
    641                         "20060216T100000",
    642                         "20060217T100000"
    643                 });
    644     }
    645 
    646     @SmallTest
    647     public void testDaily1() throws Exception {
    648         verifyRecurrence("20060215T100000", "FREQ=DAILY;UNTIL=20060302T100001Z",
    649                 null /* rdate */, null /* exrule */, null /* exdate */,
    650                 "20060101T000000", "20080101T000000",
    651                 new String[]{
    652                         "20060215T100000",
    653                         "20060216T100000",
    654                         "20060217T100000",
    655                         "20060218T100000",
    656                         "20060219T100000",
    657                         "20060220T100000",
    658                         "20060221T100000",
    659                         "20060222T100000",
    660                         "20060223T100000",
    661                         "20060224T100000",
    662                         "20060225T100000",
    663                         "20060226T100000",
    664                         "20060227T100000",
    665                         "20060228T100000",
    666                         "20060301T100000"
    667                 }, "20060302T100001Z");
    668     }
    669 
    670     @SmallTest
    671     public void testDaily2() throws Exception {
    672         verifyRecurrence("20060215T100000", "FREQ=DAILY;UNTIL=20060220T100001Z;BYDAY=SU",
    673                 null /* rdate */, null /* exrule */, null /* exdate */,
    674                 "20060101T000000", "20080101T000000",
    675                 new String[]{
    676                         "20060215T100000",
    677                         "20060219T100000"
    678                 }, "20060220T020001");
    679     }
    680 
    681     @SmallTest
    682     public void testDaily3() throws Exception {
    683         verifyRecurrence("20060219T100000",
    684                 "FREQ=DAILY;UNTIL=20060225T180304Z;BYDAY=SU,MO,SA;BYHOUR=5,10,22;BYMINUTE=3,59;BYSECOND=2,5",
    685                 null /* rdate */, null /* exrule */, null /* exdate */,
    686                 "20060101T000000", "20080101T000000",
    687                 new String[]{
    688                         "20060219T100000",
    689                         "20060219T100302",
    690                         "20060219T100305",
    691                         "20060219T105902",
    692                         "20060219T105905",
    693                         "20060219T220302",
    694                         "20060219T220305",
    695                         "20060219T225902",
    696                         "20060219T225905",
    697                         "20060220T050302",
    698                         "20060220T050305",
    699                         "20060220T055902",
    700                         "20060220T055905",
    701                         "20060220T100302",
    702                         "20060220T100305",
    703                         "20060220T105902",
    704                         "20060220T105905",
    705                         "20060220T220302",
    706                         "20060220T220305",
    707                         "20060220T225902",
    708                         "20060220T225905",
    709                         "20060225T050302",
    710                         "20060225T050305",
    711                         "20060225T055902",
    712                         "20060225T055905",
    713                         "20060225T100302"
    714                 }, "20060225T100304");
    715     }
    716 
    717     @MediumTest
    718     public void testFromGoogleCalendar0() throws Exception {
    719         // Tuesday, Thursday (10/2)
    720         verifyRecurrence("20061002T050000",
    721                 "FREQ=WEEKLY;UNTIL=20071031T200000Z;INTERVAL=1;BYDAY=TU,TH;WKST=SU",
    722                 null /* rdate */, null /* exrule */, null /* exdate */,
    723                 "20060101T000000", "20090101T000000",
    724                 new String[]{
    725                         "20061002T050000",
    726                         "20061003T050000",
    727                         "20061005T050000",
    728                         "20061010T050000",
    729                         "20061012T050000",
    730                         "20061017T050000",
    731                         "20061019T050000",
    732                         "20061024T050000",
    733                         "20061026T050000",
    734                         "20061031T050000",
    735                         "20061102T050000",
    736                         "20061107T050000",
    737                         "20061109T050000",
    738                         "20061114T050000",
    739                         "20061116T050000",
    740                         "20061121T050000",
    741                         "20061123T050000",
    742                         "20061128T050000",
    743                         "20061130T050000",
    744                         "20061205T050000",
    745                         "20061207T050000",
    746                         "20061212T050000",
    747                         "20061214T050000",
    748                         "20061219T050000",
    749                         "20061221T050000",
    750                         "20061226T050000",
    751                         "20061228T050000",
    752                         "20070102T050000",
    753                         "20070104T050000",
    754                         "20070109T050000",
    755                         "20070111T050000",
    756                         "20070116T050000",
    757                         "20070118T050000",
    758                         "20070123T050000",
    759                         "20070125T050000",
    760                         "20070130T050000",
    761                         "20070201T050000",
    762                         "20070206T050000",
    763                         "20070208T050000",
    764                         "20070213T050000",
    765                         "20070215T050000",
    766                         "20070220T050000",
    767                         "20070222T050000",
    768                         "20070227T050000",
    769                         "20070301T050000",
    770                         "20070306T050000",
    771                         "20070308T050000",
    772                         "20070313T050000",
    773                         "20070315T050000",
    774                         "20070320T050000",
    775                         "20070322T050000",
    776                         "20070327T050000",
    777                         "20070329T050000",
    778                         "20070403T050000",
    779                         "20070405T050000",
    780                         "20070410T050000",
    781                         "20070412T050000",
    782                         "20070417T050000",
    783                         "20070419T050000",
    784                         "20070424T050000",
    785                         "20070426T050000",
    786                         "20070501T050000",
    787                         "20070503T050000",
    788                         "20070508T050000",
    789                         "20070510T050000",
    790                         "20070515T050000",
    791                         "20070517T050000",
    792                         "20070522T050000",
    793                         "20070524T050000",
    794                         "20070529T050000",
    795                         "20070531T050000",
    796                         "20070605T050000",
    797                         "20070607T050000",
    798                         "20070612T050000",
    799                         "20070614T050000",
    800                         "20070619T050000",
    801                         "20070621T050000",
    802                         "20070626T050000",
    803                         "20070628T050000",
    804                         "20070703T050000",
    805                         "20070705T050000",
    806                         "20070710T050000",
    807                         "20070712T050000",
    808                         "20070717T050000",
    809                         "20070719T050000",
    810                         "20070724T050000",
    811                         "20070726T050000",
    812                         "20070731T050000",
    813                         "20070802T050000",
    814                         "20070807T050000",
    815                         "20070809T050000",
    816                         "20070814T050000",
    817                         "20070816T050000",
    818                         "20070821T050000",
    819                         "20070823T050000",
    820                         "20070828T050000",
    821                         "20070830T050000",
    822                         "20070904T050000",
    823                         "20070906T050000",
    824                         "20070911T050000",
    825                         "20070913T050000",
    826                         "20070918T050000",
    827                         "20070920T050000",
    828                         "20070925T050000",
    829                         "20070927T050000",
    830                         "20071002T050000",
    831                         "20071004T050000",
    832                         "20071009T050000",
    833                         "20071011T050000",
    834                         "20071016T050000",
    835                         "20071018T050000",
    836                         "20071023T050000",
    837                         "20071025T050000",
    838                         "20071030T050000",
    839                 }, "20071031T130000");
    840     }
    841 
    842     @MediumTest
    843     public void testFromGoogleCalendar1() throws Exception {
    844         // Mon Wed Fri
    845         verifyRecurrence("20061002T030000",
    846                 "FREQ=WEEKLY;UNTIL=20071025T180000Z;INTERVAL=1;BYDAY=MO,WE,FR;",
    847                 null /* rdate */, null /* exrule */, null /* exdate */,
    848                 "20060101T000000", "20090101T000000",
    849                 new String[]{
    850                         "20061002T030000",
    851                         "20061004T030000",
    852                         "20061006T030000",
    853                         "20061009T030000",
    854                         "20061011T030000",
    855                         "20061013T030000",
    856                         "20061016T030000",
    857                         "20061018T030000",
    858                         "20061020T030000",
    859                         "20061023T030000",
    860                         "20061025T030000",
    861                         "20061027T030000",
    862                         "20061030T030000",
    863                         "20061101T030000",
    864                         "20061103T030000",
    865                         "20061106T030000",
    866                         "20061108T030000",
    867                         "20061110T030000",
    868                         "20061113T030000",
    869                         "20061115T030000",
    870                         "20061117T030000",
    871                         "20061120T030000",
    872                         "20061122T030000",
    873                         "20061124T030000",
    874                         "20061127T030000",
    875                         "20061129T030000",
    876                         "20061201T030000",
    877                         "20061204T030000",
    878                         "20061206T030000",
    879                         "20061208T030000",
    880                         "20061211T030000",
    881                         "20061213T030000",
    882                         "20061215T030000",
    883                         "20061218T030000",
    884                         "20061220T030000",
    885                         "20061222T030000",
    886                         "20061225T030000",
    887                         "20061227T030000",
    888                         "20061229T030000",
    889                         "20070101T030000",
    890                         "20070103T030000",
    891                         "20070105T030000",
    892                         "20070108T030000",
    893                         "20070110T030000",
    894                         "20070112T030000",
    895                         "20070115T030000",
    896                         "20070117T030000",
    897                         "20070119T030000",
    898                         "20070122T030000",
    899                         "20070124T030000",
    900                         "20070126T030000",
    901                         "20070129T030000",
    902                         "20070131T030000",
    903                         "20070202T030000",
    904                         "20070205T030000",
    905                         "20070207T030000",
    906                         "20070209T030000",
    907                         "20070212T030000",
    908                         "20070214T030000",
    909                         "20070216T030000",
    910                         "20070219T030000",
    911                         "20070221T030000",
    912                         "20070223T030000",
    913                         "20070226T030000",
    914                         "20070228T030000",
    915                         "20070302T030000",
    916                         "20070305T030000",
    917                         "20070307T030000",
    918                         "20070309T030000",
    919                         "20070312T030000",
    920                         "20070314T030000",
    921                         "20070316T030000",
    922                         "20070319T030000",
    923                         "20070321T030000",
    924                         "20070323T030000",
    925                         "20070326T030000",
    926                         "20070328T030000",
    927                         "20070330T030000",
    928                         "20070402T030000",
    929                         "20070404T030000",
    930                         "20070406T030000",
    931                         "20070409T030000",
    932                         "20070411T030000",
    933                         "20070413T030000",
    934                         "20070416T030000",
    935                         "20070418T030000",
    936                         "20070420T030000",
    937                         "20070423T030000",
    938                         "20070425T030000",
    939                         "20070427T030000",
    940                         "20070430T030000",
    941                         "20070502T030000",
    942                         "20070504T030000",
    943                         "20070507T030000",
    944                         "20070509T030000",
    945                         "20070511T030000",
    946                         "20070514T030000",
    947                         "20070516T030000",
    948                         "20070518T030000",
    949                         "20070521T030000",
    950                         "20070523T030000",
    951                         "20070525T030000",
    952                         "20070528T030000",
    953                         "20070530T030000",
    954                         "20070601T030000",
    955                         "20070604T030000",
    956                         "20070606T030000",
    957                         "20070608T030000",
    958                         "20070611T030000",
    959                         "20070613T030000",
    960                         "20070615T030000",
    961                         "20070618T030000",
    962                         "20070620T030000",
    963                         "20070622T030000",
    964                         "20070625T030000",
    965                         "20070627T030000",
    966                         "20070629T030000",
    967                         "20070702T030000",
    968                         "20070704T030000",
    969                         "20070706T030000",
    970                         "20070709T030000",
    971                         "20070711T030000",
    972                         "20070713T030000",
    973                         "20070716T030000",
    974                         "20070718T030000",
    975                         "20070720T030000",
    976                         "20070723T030000",
    977                         "20070725T030000",
    978                         "20070727T030000",
    979                         "20070730T030000",
    980                         "20070801T030000",
    981                         "20070803T030000",
    982                         "20070806T030000",
    983                         "20070808T030000",
    984                         "20070810T030000",
    985                         "20070813T030000",
    986                         "20070815T030000",
    987                         "20070817T030000",
    988                         "20070820T030000",
    989                         "20070822T030000",
    990                         "20070824T030000",
    991                         "20070827T030000",
    992                         "20070829T030000",
    993                         "20070831T030000",
    994                         "20070903T030000",
    995                         "20070905T030000",
    996                         "20070907T030000",
    997                         "20070910T030000",
    998                         "20070912T030000",
    999                         "20070914T030000",
   1000                         "20070917T030000",
   1001                         "20070919T030000",
   1002                         "20070921T030000",
   1003                         "20070924T030000",
   1004                         "20070926T030000",
   1005                         "20070928T030000",
   1006                         "20071001T030000",
   1007                         "20071003T030000",
   1008                         "20071005T030000",
   1009                         "20071008T030000",
   1010                         "20071010T030000",
   1011                         "20071012T030000",
   1012                         "20071015T030000",
   1013                         "20071017T030000",
   1014                         "20071019T030000",
   1015                         "20071022T030000",
   1016                         "20071024T030000",
   1017                 }, "20071025T110000");
   1018     }
   1019 
   1020     @SmallTest
   1021     public void testFromGoogleCalendar2() throws Exception {
   1022         // Monthly on day 2
   1023         verifyRecurrence("20061002T070000",
   1024                 "FREQ=MONTHLY;INTERVAL=1;WKST=SU",
   1025                 null /* rdate */, null /* exrule */, null /* exdate */,
   1026                 "20060101T000000", "20090101T000000",
   1027                 new String[]{
   1028                         "20061002T070000",
   1029                         "20061102T070000",
   1030                         "20061202T070000",
   1031                         "20070102T070000",
   1032                         "20070202T070000",
   1033                         "20070302T070000",
   1034                         "20070402T070000",
   1035                         "20070502T070000",
   1036                         "20070602T070000",
   1037                         "20070702T070000",
   1038                         "20070802T070000",
   1039                         "20070902T070000",
   1040                         "20071002T070000",
   1041                         "20071102T070000",
   1042                         "20071202T070000",
   1043                         "20080102T070000",
   1044                         "20080202T070000",
   1045                         "20080302T070000",
   1046                         "20080402T070000",
   1047                         "20080502T070000",
   1048                         "20080602T070000",
   1049                         "20080702T070000",
   1050                         "20080802T070000",
   1051                         "20080902T070000",
   1052                         "20081002T070000",
   1053                         "20081102T070000",
   1054                         "20081202T070000",
   1055                 }, "20081202T070000");
   1056     }
   1057 
   1058     @MediumTest
   1059     public void testFromGoogleCalendar3() throws Exception {
   1060         // Every Weekday
   1061         verifyRecurrence("20061002T100000",
   1062                 "FREQ=WEEKLY;UNTIL=20070215T100000Z;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR;",
   1063                 null /* rdate */, null /* exrule */, null /* exdate */,
   1064                 "20060101T000000", "20090101T000000",
   1065                 new String[]{
   1066                         "20061002T100000",
   1067                         "20061003T100000",
   1068                         "20061004T100000",
   1069                         "20061005T100000",
   1070                         "20061006T100000",
   1071                         "20061009T100000",
   1072                         "20061010T100000",
   1073                         "20061011T100000",
   1074                         "20061012T100000",
   1075                         "20061013T100000",
   1076                         "20061016T100000",
   1077                         "20061017T100000",
   1078                         "20061018T100000",
   1079                         "20061019T100000",
   1080                         "20061020T100000",
   1081                         "20061023T100000",
   1082                         "20061024T100000",
   1083                         "20061025T100000",
   1084                         "20061026T100000",
   1085                         "20061027T100000",
   1086                         "20061030T100000",
   1087                         "20061031T100000",
   1088                         "20061101T100000",
   1089                         "20061102T100000",
   1090                         "20061103T100000",
   1091                         "20061106T100000",
   1092                         "20061107T100000",
   1093                         "20061108T100000",
   1094                         "20061109T100000",
   1095                         "20061110T100000",
   1096                         "20061113T100000",
   1097                         "20061114T100000",
   1098                         "20061115T100000",
   1099                         "20061116T100000",
   1100                         "20061117T100000",
   1101                         "20061120T100000",
   1102                         "20061121T100000",
   1103                         "20061122T100000",
   1104                         "20061123T100000",
   1105                         "20061124T100000",
   1106                         "20061127T100000",
   1107                         "20061128T100000",
   1108                         "20061129T100000",
   1109                         "20061130T100000",
   1110                         "20061201T100000",
   1111                         "20061204T100000",
   1112                         "20061205T100000",
   1113                         "20061206T100000",
   1114                         "20061207T100000",
   1115                         "20061208T100000",
   1116                         "20061211T100000",
   1117                         "20061212T100000",
   1118                         "20061213T100000",
   1119                         "20061214T100000",
   1120                         "20061215T100000",
   1121                         "20061218T100000",
   1122                         "20061219T100000",
   1123                         "20061220T100000",
   1124                         "20061221T100000",
   1125                         "20061222T100000",
   1126                         "20061225T100000",
   1127                         "20061226T100000",
   1128                         "20061227T100000",
   1129                         "20061228T100000",
   1130                         "20061229T100000",
   1131                         "20070101T100000",
   1132                         "20070102T100000",
   1133                         "20070103T100000",
   1134                         "20070104T100000",
   1135                         "20070105T100000",
   1136                         "20070108T100000",
   1137                         "20070109T100000",
   1138                         "20070110T100000",
   1139                         "20070111T100000",
   1140                         "20070112T100000",
   1141                         "20070115T100000",
   1142                         "20070116T100000",
   1143                         "20070117T100000",
   1144                         "20070118T100000",
   1145                         "20070119T100000",
   1146                         "20070122T100000",
   1147                         "20070123T100000",
   1148                         "20070124T100000",
   1149                         "20070125T100000",
   1150                         "20070126T100000",
   1151                         "20070129T100000",
   1152                         "20070130T100000",
   1153                         "20070131T100000",
   1154                         "20070201T100000",
   1155                         "20070202T100000",
   1156                         "20070205T100000",
   1157                         "20070206T100000",
   1158                         "20070207T100000",
   1159                         "20070208T100000",
   1160                         "20070209T100000",
   1161                         "20070212T100000",
   1162                         "20070213T100000",
   1163                         "20070214T100000",
   1164                 }, "20070215T020000");
   1165     }
   1166 
   1167     @SmallTest
   1168     public void testFromGoogleCalendar4() throws Exception {
   1169         // Every 5 months on day 2
   1170         verifyRecurrence("20061003T100000",
   1171                 "FREQ=MONTHLY;INTERVAL=5;WKST=SU",
   1172                 null /* rdate */, null /* exrule */, null /* exdate */,
   1173                 "20060101T000000", "20090101T000000",
   1174                 new String[]{
   1175                         "20061003T100000",
   1176                         "20070303T100000",
   1177                         "20070803T100000",
   1178                         "20080103T100000",
   1179                         "20080603T100000",
   1180                         "20081103T100000",
   1181                 }, "20081103T100000");
   1182     }
   1183 
   1184     @MediumTest
   1185     public void testFromGoogleCalendar5() throws Exception {
   1186         // Tuesday, Thursday (10/3)
   1187         verifyRecurrence("20061003T040000",
   1188                 "FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,TH;WKST=SU",
   1189                 null /* rdate */, null /* exrule */, null /* exdate */,
   1190                 "20060101T000000", "20090101T000000",
   1191                 new String[]{
   1192                         "20061003T040000",
   1193                         "20061005T040000",
   1194                         "20061010T040000",
   1195                         "20061012T040000",
   1196                         "20061017T040000",
   1197                         "20061019T040000",
   1198                         "20061024T040000",
   1199                         "20061026T040000",
   1200                         "20061031T040000",
   1201                         "20061102T040000",
   1202                         "20061107T040000",
   1203                         "20061109T040000",
   1204                         "20061114T040000",
   1205                         "20061116T040000",
   1206                         "20061121T040000",
   1207                         "20061123T040000",
   1208                         "20061128T040000",
   1209                         "20061130T040000",
   1210                         "20061205T040000",
   1211                         "20061207T040000",
   1212                         "20061212T040000",
   1213                         "20061214T040000",
   1214                         "20061219T040000",
   1215                         "20061221T040000",
   1216                         "20061226T040000",
   1217                         "20061228T040000",
   1218                         "20070102T040000",
   1219                         "20070104T040000",
   1220                         "20070109T040000",
   1221                         "20070111T040000",
   1222                         "20070116T040000",
   1223                         "20070118T040000",
   1224                         "20070123T040000",
   1225                         "20070125T040000",
   1226                         "20070130T040000",
   1227                         "20070201T040000",
   1228                         "20070206T040000",
   1229                         "20070208T040000",
   1230                         "20070213T040000",
   1231                         "20070215T040000",
   1232                         "20070220T040000",
   1233                         "20070222T040000",
   1234                         "20070227T040000",
   1235                         "20070301T040000",
   1236                         "20070306T040000",
   1237                         "20070308T040000",
   1238                         "20070313T040000",
   1239                         "20070315T040000",
   1240                         "20070320T040000",
   1241                         "20070322T040000",
   1242                         "20070327T040000",
   1243                         "20070329T040000",
   1244                         "20070403T040000",
   1245                         "20070405T040000",
   1246                         "20070410T040000",
   1247                         "20070412T040000",
   1248                         "20070417T040000",
   1249                         "20070419T040000",
   1250                         "20070424T040000",
   1251                         "20070426T040000",
   1252                         "20070501T040000",
   1253                         "20070503T040000",
   1254                         "20070508T040000",
   1255                         "20070510T040000",
   1256                         "20070515T040000",
   1257                         "20070517T040000",
   1258                         "20070522T040000",
   1259                         "20070524T040000",
   1260                         "20070529T040000",
   1261                         "20070531T040000",
   1262                         "20070605T040000",
   1263                         "20070607T040000",
   1264                         "20070612T040000",
   1265                         "20070614T040000",
   1266                         "20070619T040000",
   1267                         "20070621T040000",
   1268                         "20070626T040000",
   1269                         "20070628T040000",
   1270                         "20070703T040000",
   1271                         "20070705T040000",
   1272                         "20070710T040000",
   1273                         "20070712T040000",
   1274                         "20070717T040000",
   1275                         "20070719T040000",
   1276                         "20070724T040000",
   1277                         "20070726T040000",
   1278                         "20070731T040000",
   1279                         "20070802T040000",
   1280                         "20070807T040000",
   1281                         "20070809T040000",
   1282                         "20070814T040000",
   1283                         "20070816T040000",
   1284                         "20070821T040000",
   1285                         "20070823T040000",
   1286                         "20070828T040000",
   1287                         "20070830T040000",
   1288                         "20070904T040000",
   1289                         "20070906T040000",
   1290                         "20070911T040000",
   1291                         "20070913T040000",
   1292                         "20070918T040000",
   1293                         "20070920T040000",
   1294                         "20070925T040000",
   1295                         "20070927T040000",
   1296                         "20071002T040000",
   1297                         "20071004T040000",
   1298                         "20071009T040000",
   1299                         "20071011T040000",
   1300                         "20071016T040000",
   1301                         "20071018T040000",
   1302                         "20071023T040000",
   1303                         "20071025T040000",
   1304                         "20071030T040000",
   1305                         "20071101T040000",
   1306                         "20071106T040000",
   1307                         "20071108T040000",
   1308                         "20071113T040000",
   1309                         "20071115T040000",
   1310                         "20071120T040000",
   1311                         "20071122T040000",
   1312                         "20071127T040000",
   1313                         "20071129T040000",
   1314                         "20071204T040000",
   1315                         "20071206T040000",
   1316                         "20071211T040000",
   1317                         "20071213T040000",
   1318                         "20071218T040000",
   1319                         "20071220T040000",
   1320                         "20071225T040000",
   1321                         "20071227T040000",
   1322                         "20080101T040000",
   1323                         "20080103T040000",
   1324                         "20080108T040000",
   1325                         "20080110T040000",
   1326                         "20080115T040000",
   1327                         "20080117T040000",
   1328                         "20080122T040000",
   1329                         "20080124T040000",
   1330                         "20080129T040000",
   1331                         "20080131T040000",
   1332                         "20080205T040000",
   1333                         "20080207T040000",
   1334                         "20080212T040000",
   1335                         "20080214T040000",
   1336                         "20080219T040000",
   1337                         "20080221T040000",
   1338                         "20080226T040000",
   1339                         "20080228T040000",
   1340                         "20080304T040000",
   1341                         "20080306T040000",
   1342                         "20080311T040000",
   1343                         "20080313T040000",
   1344                         "20080318T040000",
   1345                         "20080320T040000",
   1346                         "20080325T040000",
   1347                         "20080327T040000",
   1348                         "20080401T040000",
   1349                         "20080403T040000",
   1350                         "20080408T040000",
   1351                         "20080410T040000",
   1352                         "20080415T040000",
   1353                         "20080417T040000",
   1354                         "20080422T040000",
   1355                         "20080424T040000",
   1356                         "20080429T040000",
   1357                         "20080501T040000",
   1358                         "20080506T040000",
   1359                         "20080508T040000",
   1360                         "20080513T040000",
   1361                         "20080515T040000",
   1362                         "20080520T040000",
   1363                         "20080522T040000",
   1364                         "20080527T040000",
   1365                         "20080529T040000",
   1366                         "20080603T040000",
   1367                         "20080605T040000",
   1368                         "20080610T040000",
   1369                         "20080612T040000",
   1370                         "20080617T040000",
   1371                         "20080619T040000",
   1372                         "20080624T040000",
   1373                         "20080626T040000",
   1374                         "20080701T040000",
   1375                         "20080703T040000",
   1376                         "20080708T040000",
   1377                         "20080710T040000",
   1378                         "20080715T040000",
   1379                         "20080717T040000",
   1380                         "20080722T040000",
   1381                         "20080724T040000",
   1382                         "20080729T040000",
   1383                         "20080731T040000",
   1384                         "20080805T040000",
   1385                         "20080807T040000",
   1386                         "20080812T040000",
   1387                         "20080814T040000",
   1388                         "20080819T040000",
   1389                         "20080821T040000",
   1390                         "20080826T040000",
   1391                         "20080828T040000",
   1392                         "20080902T040000",
   1393                         "20080904T040000",
   1394                         "20080909T040000",
   1395                         "20080911T040000",
   1396                         "20080916T040000",
   1397                         "20080918T040000",
   1398                         "20080923T040000",
   1399                         "20080925T040000",
   1400                         "20080930T040000",
   1401                         "20081002T040000",
   1402                         "20081007T040000",
   1403                         "20081009T040000",
   1404                         "20081014T040000",
   1405                         "20081016T040000",
   1406                         "20081021T040000",
   1407                         "20081023T040000",
   1408                         "20081028T040000",
   1409                         "20081030T040000",
   1410                         "20081104T040000",
   1411                         "20081106T040000",
   1412                         "20081111T040000",
   1413                         "20081113T040000",
   1414                         "20081118T040000",
   1415                         "20081120T040000",
   1416                         "20081125T040000",
   1417                         "20081127T040000",
   1418                         "20081202T040000",
   1419                         "20081204T040000",
   1420                         "20081209T040000",
   1421                         "20081211T040000",
   1422                         "20081216T040000",
   1423                         "20081218T040000",
   1424                         "20081223T040000",
   1425                         "20081225T040000",
   1426                         "20081230T040000",
   1427                 }, "20081230T040000");
   1428     }
   1429 
   1430     @MediumTest
   1431     public void testFromGoogleCalendar6() throws Exception {
   1432         // Weekly on all days
   1433         verifyRecurrence("20061003T060000",
   1434                 "FREQ=WEEKLY;INTERVAL=1;BYDAY=SU,MO,TU,WE,TH,FR,SA;WKST=SU",
   1435                 null /* rdate */, null /* exrule */, null /* exdate */,
   1436                 "20060101T000000", "20071003T060000",
   1437                 new String[]{
   1438                         "20061003T060000",
   1439                         "20061004T060000",
   1440                         "20061005T060000",
   1441                         "20061006T060000",
   1442                         "20061007T060000",
   1443                         "20061008T060000",
   1444                         "20061009T060000",
   1445                         "20061010T060000",
   1446                         "20061011T060000",
   1447                         "20061012T060000",
   1448                         "20061013T060000",
   1449                         "20061014T060000",
   1450                         "20061015T060000",
   1451                         "20061016T060000",
   1452                         "20061017T060000",
   1453                         "20061018T060000",
   1454                         "20061019T060000",
   1455                         "20061020T060000",
   1456                         "20061021T060000",
   1457                         "20061022T060000",
   1458                         "20061023T060000",
   1459                         "20061024T060000",
   1460                         "20061025T060000",
   1461                         "20061026T060000",
   1462                         "20061027T060000",
   1463                         "20061028T060000",
   1464                         "20061029T060000",
   1465                         "20061030T060000",
   1466                         "20061031T060000",
   1467                         "20061101T060000",
   1468                         "20061102T060000",
   1469                         "20061103T060000",
   1470                         "20061104T060000",
   1471                         "20061105T060000",
   1472                         "20061106T060000",
   1473                         "20061107T060000",
   1474                         "20061108T060000",
   1475                         "20061109T060000",
   1476                         "20061110T060000",
   1477                         "20061111T060000",
   1478                         "20061112T060000",
   1479                         "20061113T060000",
   1480                         "20061114T060000",
   1481                         "20061115T060000",
   1482                         "20061116T060000",
   1483                         "20061117T060000",
   1484                         "20061118T060000",
   1485                         "20061119T060000",
   1486                         "20061120T060000",
   1487                         "20061121T060000",
   1488                         "20061122T060000",
   1489                         "20061123T060000",
   1490                         "20061124T060000",
   1491                         "20061125T060000",
   1492                         "20061126T060000",
   1493                         "20061127T060000",
   1494                         "20061128T060000",
   1495                         "20061129T060000",
   1496                         "20061130T060000",
   1497                         "20061201T060000",
   1498                         "20061202T060000",
   1499                         "20061203T060000",
   1500                         "20061204T060000",
   1501                         "20061205T060000",
   1502                         "20061206T060000",
   1503                         "20061207T060000",
   1504                         "20061208T060000",
   1505                         "20061209T060000",
   1506                         "20061210T060000",
   1507                         "20061211T060000",
   1508                         "20061212T060000",
   1509                         "20061213T060000",
   1510                         "20061214T060000",
   1511                         "20061215T060000",
   1512                         "20061216T060000",
   1513                         "20061217T060000",
   1514                         "20061218T060000",
   1515                         "20061219T060000",
   1516                         "20061220T060000",
   1517                         "20061221T060000",
   1518                         "20061222T060000",
   1519                         "20061223T060000",
   1520                         "20061224T060000",
   1521                         "20061225T060000",
   1522                         "20061226T060000",
   1523                         "20061227T060000",
   1524                         "20061228T060000",
   1525                         "20061229T060000",
   1526                         "20061230T060000",
   1527                         "20061231T060000",
   1528                         "20070101T060000",
   1529                         "20070102T060000",
   1530                         "20070103T060000",
   1531                         "20070104T060000",
   1532                         "20070105T060000",
   1533                         "20070106T060000",
   1534                         "20070107T060000",
   1535                         "20070108T060000",
   1536                         "20070109T060000",
   1537                         "20070110T060000",
   1538                         "20070111T060000",
   1539                         "20070112T060000",
   1540                         "20070113T060000",
   1541                         "20070114T060000",
   1542                         "20070115T060000",
   1543                         "20070116T060000",
   1544                         "20070117T060000",
   1545                         "20070118T060000",
   1546                         "20070119T060000",
   1547                         "20070120T060000",
   1548                         "20070121T060000",
   1549                         "20070122T060000",
   1550                         "20070123T060000",
   1551                         "20070124T060000",
   1552                         "20070125T060000",
   1553                         "20070126T060000",
   1554                         "20070127T060000",
   1555                         "20070128T060000",
   1556                         "20070129T060000",
   1557                         "20070130T060000",
   1558                         "20070131T060000",
   1559                         "20070201T060000",
   1560                         "20070202T060000",
   1561                         "20070203T060000",
   1562                         "20070204T060000",
   1563                         "20070205T060000",
   1564                         "20070206T060000",
   1565                         "20070207T060000",
   1566                         "20070208T060000",
   1567                         "20070209T060000",
   1568                         "20070210T060000",
   1569                         "20070211T060000",
   1570                         "20070212T060000",
   1571                         "20070213T060000",
   1572                         "20070214T060000",
   1573                         "20070215T060000",
   1574                         "20070216T060000",
   1575                         "20070217T060000",
   1576                         "20070218T060000",
   1577                         "20070219T060000",
   1578                         "20070220T060000",
   1579                         "20070221T060000",
   1580                         "20070222T060000",
   1581                         "20070223T060000",
   1582                         "20070224T060000",
   1583                         "20070225T060000",
   1584                         "20070226T060000",
   1585                         "20070227T060000",
   1586                         "20070228T060000",
   1587                         "20070301T060000",
   1588                         "20070302T060000",
   1589                         "20070303T060000",
   1590                         "20070304T060000",
   1591                         "20070305T060000",
   1592                         "20070306T060000",
   1593                         "20070307T060000",
   1594                         "20070308T060000",
   1595                         "20070309T060000",
   1596                         "20070310T060000",
   1597                         "20070311T060000",
   1598                         "20070312T060000",
   1599                         "20070313T060000",
   1600                         "20070314T060000",
   1601                         "20070315T060000",
   1602                         "20070316T060000",
   1603                         "20070317T060000",
   1604                         "20070318T060000",
   1605                         "20070319T060000",
   1606                         "20070320T060000",
   1607                         "20070321T060000",
   1608                         "20070322T060000",
   1609                         "20070323T060000",
   1610                         "20070324T060000",
   1611                         "20070325T060000",
   1612                         "20070326T060000",
   1613                         "20070327T060000",
   1614                         "20070328T060000",
   1615                         "20070329T060000",
   1616                         "20070330T060000",
   1617                         "20070331T060000",
   1618                         "20070401T060000",
   1619                         "20070402T060000",
   1620                         "20070403T060000",
   1621                         "20070404T060000",
   1622                         "20070405T060000",
   1623                         "20070406T060000",
   1624                         "20070407T060000",
   1625                         "20070408T060000",
   1626                         "20070409T060000",
   1627                         "20070410T060000",
   1628                         "20070411T060000",
   1629                         "20070412T060000",
   1630                         "20070413T060000",
   1631                         "20070414T060000",
   1632                         "20070415T060000",
   1633                         "20070416T060000",
   1634                         "20070417T060000",
   1635                         "20070418T060000",
   1636                         "20070419T060000",
   1637                         "20070420T060000",
   1638                         "20070421T060000",
   1639                         "20070422T060000",
   1640                         "20070423T060000",
   1641                         "20070424T060000",
   1642                         "20070425T060000",
   1643                         "20070426T060000",
   1644                         "20070427T060000",
   1645                         "20070428T060000",
   1646                         "20070429T060000",
   1647                         "20070430T060000",
   1648                         "20070501T060000",
   1649                         "20070502T060000",
   1650                         "20070503T060000",
   1651                         "20070504T060000",
   1652                         "20070505T060000",
   1653                         "20070506T060000",
   1654                         "20070507T060000",
   1655                         "20070508T060000",
   1656                         "20070509T060000",
   1657                         "20070510T060000",
   1658                         "20070511T060000",
   1659                         "20070512T060000",
   1660                         "20070513T060000",
   1661                         "20070514T060000",
   1662                         "20070515T060000",
   1663                         "20070516T060000",
   1664                         "20070517T060000",
   1665                         "20070518T060000",
   1666                         "20070519T060000",
   1667                         "20070520T060000",
   1668                         "20070521T060000",
   1669                         "20070522T060000",
   1670                         "20070523T060000",
   1671                         "20070524T060000",
   1672                         "20070525T060000",
   1673                         "20070526T060000",
   1674                         "20070527T060000",
   1675                         "20070528T060000",
   1676                         "20070529T060000",
   1677                         "20070530T060000",
   1678                         "20070531T060000",
   1679                         "20070601T060000",
   1680                         "20070602T060000",
   1681                         "20070603T060000",
   1682                         "20070604T060000",
   1683                         "20070605T060000",
   1684                         "20070606T060000",
   1685                         "20070607T060000",
   1686                         "20070608T060000",
   1687                         "20070609T060000",
   1688                         "20070610T060000",
   1689                         "20070611T060000",
   1690                         "20070612T060000",
   1691                         "20070613T060000",
   1692                         "20070614T060000",
   1693                         "20070615T060000",
   1694                         "20070616T060000",
   1695                         "20070617T060000",
   1696                         "20070618T060000",
   1697                         "20070619T060000",
   1698                         "20070620T060000",
   1699                         "20070621T060000",
   1700                         "20070622T060000",
   1701                         "20070623T060000",
   1702                         "20070624T060000",
   1703                         "20070625T060000",
   1704                         "20070626T060000",
   1705                         "20070627T060000",
   1706                         "20070628T060000",
   1707                         "20070629T060000",
   1708                         "20070630T060000",
   1709                         "20070701T060000",
   1710                         "20070702T060000",
   1711                         "20070703T060000",
   1712                         "20070704T060000",
   1713                         "20070705T060000",
   1714                         "20070706T060000",
   1715                         "20070707T060000",
   1716                         "20070708T060000",
   1717                         "20070709T060000",
   1718                         "20070710T060000",
   1719                         "20070711T060000",
   1720                         "20070712T060000",
   1721                         "20070713T060000",
   1722                         "20070714T060000",
   1723                         "20070715T060000",
   1724                         "20070716T060000",
   1725                         "20070717T060000",
   1726                         "20070718T060000",
   1727                         "20070719T060000",
   1728                         "20070720T060000",
   1729                         "20070721T060000",
   1730                         "20070722T060000",
   1731                         "20070723T060000",
   1732                         "20070724T060000",
   1733                         "20070725T060000",
   1734                         "20070726T060000",
   1735                         "20070727T060000",
   1736                         "20070728T060000",
   1737                         "20070729T060000",
   1738                         "20070730T060000",
   1739                         "20070731T060000",
   1740                         "20070801T060000",
   1741                         "20070802T060000",
   1742                         "20070803T060000",
   1743                         "20070804T060000",
   1744                         "20070805T060000",
   1745                         "20070806T060000",
   1746                         "20070807T060000",
   1747                         "20070808T060000",
   1748                         "20070809T060000",
   1749                         "20070810T060000",
   1750                         "20070811T060000",
   1751                         "20070812T060000",
   1752                         "20070813T060000",
   1753                         "20070814T060000",
   1754                         "20070815T060000",
   1755                         "20070816T060000",
   1756                         "20070817T060000",
   1757                         "20070818T060000",
   1758                         "20070819T060000",
   1759                         "20070820T060000",
   1760                         "20070821T060000",
   1761                         "20070822T060000",
   1762                         "20070823T060000",
   1763                         "20070824T060000",
   1764                         "20070825T060000",
   1765                         "20070826T060000",
   1766                         "20070827T060000",
   1767                         "20070828T060000",
   1768                         "20070829T060000",
   1769                         "20070830T060000",
   1770                         "20070831T060000",
   1771                         "20070901T060000",
   1772                         "20070902T060000",
   1773                         "20070903T060000",
   1774                         "20070904T060000",
   1775                         "20070905T060000",
   1776                         "20070906T060000",
   1777                         "20070907T060000",
   1778                         "20070908T060000",
   1779                         "20070909T060000",
   1780                         "20070910T060000",
   1781                         "20070911T060000",
   1782                         "20070912T060000",
   1783                         "20070913T060000",
   1784                         "20070914T060000",
   1785                         "20070915T060000",
   1786                         "20070916T060000",
   1787                         "20070917T060000",
   1788                         "20070918T060000",
   1789                         "20070919T060000",
   1790                         "20070920T060000",
   1791                         "20070921T060000",
   1792                         "20070922T060000",
   1793                         "20070923T060000",
   1794                         "20070924T060000",
   1795                         "20070925T060000",
   1796                         "20070926T060000",
   1797                         "20070927T060000",
   1798                         "20070928T060000",
   1799                         "20070929T060000",
   1800                         "20070930T060000",
   1801                         "20071001T060000",
   1802                         "20071002T060000",
   1803                 }, "20071002T060000");
   1804     }
   1805 
   1806     @MediumTest
   1807     public void testFromGoogleCalendar7() throws Exception {
   1808         // Every 3 days
   1809         verifyRecurrence("20061003T080000",
   1810                 "FREQ=DAILY;INTERVAL=3;WKST=SU",
   1811                 null /* rdate */, null /* exrule */, null /* exdate */,
   1812                 "20060101T000000", "20090101T000000",
   1813                 new String[]{
   1814                         "20061003T080000",
   1815                         "20061006T080000",
   1816                         "20061009T080000",
   1817                         "20061012T080000",
   1818                         "20061015T080000",
   1819                         "20061018T080000",
   1820                         "20061021T080000",
   1821                         "20061024T080000",
   1822                         "20061027T080000",
   1823                         "20061030T080000",
   1824                         "20061102T080000",
   1825                         "20061105T080000",
   1826                         "20061108T080000",
   1827                         "20061111T080000",
   1828                         "20061114T080000",
   1829                         "20061117T080000",
   1830                         "20061120T080000",
   1831                         "20061123T080000",
   1832                         "20061126T080000",
   1833                         "20061129T080000",
   1834                         "20061202T080000",
   1835                         "20061205T080000",
   1836                         "20061208T080000",
   1837                         "20061211T080000",
   1838                         "20061214T080000",
   1839                         "20061217T080000",
   1840                         "20061220T080000",
   1841                         "20061223T080000",
   1842                         "20061226T080000",
   1843                         "20061229T080000",
   1844                         "20070101T080000",
   1845                         "20070104T080000",
   1846                         "20070107T080000",
   1847                         "20070110T080000",
   1848                         "20070113T080000",
   1849                         "20070116T080000",
   1850                         "20070119T080000",
   1851                         "20070122T080000",
   1852                         "20070125T080000",
   1853                         "20070128T080000",
   1854                         "20070131T080000",
   1855                         "20070203T080000",
   1856                         "20070206T080000",
   1857                         "20070209T080000",
   1858                         "20070212T080000",
   1859                         "20070215T080000",
   1860                         "20070218T080000",
   1861                         "20070221T080000",
   1862                         "20070224T080000",
   1863                         "20070227T080000",
   1864                         "20070302T080000",
   1865                         "20070305T080000",
   1866                         "20070308T080000",
   1867                         "20070311T080000",
   1868                         "20070314T080000",
   1869                         "20070317T080000",
   1870                         "20070320T080000",
   1871                         "20070323T080000",
   1872                         "20070326T080000",
   1873                         "20070329T080000",
   1874                         "20070401T080000",
   1875                         "20070404T080000",
   1876                         "20070407T080000",
   1877                         "20070410T080000",
   1878                         "20070413T080000",
   1879                         "20070416T080000",
   1880                         "20070419T080000",
   1881                         "20070422T080000",
   1882                         "20070425T080000",
   1883                         "20070428T080000",
   1884                         "20070501T080000",
   1885                         "20070504T080000",
   1886                         "20070507T080000",
   1887                         "20070510T080000",
   1888                         "20070513T080000",
   1889                         "20070516T080000",
   1890                         "20070519T080000",
   1891                         "20070522T080000",
   1892                         "20070525T080000",
   1893                         "20070528T080000",
   1894                         "20070531T080000",
   1895                         "20070603T080000",
   1896                         "20070606T080000",
   1897                         "20070609T080000",
   1898                         "20070612T080000",
   1899                         "20070615T080000",
   1900                         "20070618T080000",
   1901                         "20070621T080000",
   1902                         "20070624T080000",
   1903                         "20070627T080000",
   1904                         "20070630T080000",
   1905                         "20070703T080000",
   1906                         "20070706T080000",
   1907                         "20070709T080000",
   1908                         "20070712T080000",
   1909                         "20070715T080000",
   1910                         "20070718T080000",
   1911                         "20070721T080000",
   1912                         "20070724T080000",
   1913                         "20070727T080000",
   1914                         "20070730T080000",
   1915                         "20070802T080000",
   1916                         "20070805T080000",
   1917                         "20070808T080000",
   1918                         "20070811T080000",
   1919                         "20070814T080000",
   1920                         "20070817T080000",
   1921                         "20070820T080000",
   1922                         "20070823T080000",
   1923                         "20070826T080000",
   1924                         "20070829T080000",
   1925                         "20070901T080000",
   1926                         "20070904T080000",
   1927                         "20070907T080000",
   1928                         "20070910T080000",
   1929                         "20070913T080000",
   1930                         "20070916T080000",
   1931                         "20070919T080000",
   1932                         "20070922T080000",
   1933                         "20070925T080000",
   1934                         "20070928T080000",
   1935                         "20071001T080000",
   1936                         "20071004T080000",
   1937                         "20071007T080000",
   1938                         "20071010T080000",
   1939                         "20071013T080000",
   1940                         "20071016T080000",
   1941                         "20071019T080000",
   1942                         "20071022T080000",
   1943                         "20071025T080000",
   1944                         "20071028T080000",
   1945                         "20071031T080000",
   1946                         "20071103T080000",
   1947                         "20071106T080000",
   1948                         "20071109T080000",
   1949                         "20071112T080000",
   1950                         "20071115T080000",
   1951                         "20071118T080000",
   1952                         "20071121T080000",
   1953                         "20071124T080000",
   1954                         "20071127T080000",
   1955                         "20071130T080000",
   1956                         "20071203T080000",
   1957                         "20071206T080000",
   1958                         "20071209T080000",
   1959                         "20071212T080000",
   1960                         "20071215T080000",
   1961                         "20071218T080000",
   1962                         "20071221T080000",
   1963                         "20071224T080000",
   1964                         "20071227T080000",
   1965                         "20071230T080000",
   1966                         "20080102T080000",
   1967                         "20080105T080000",
   1968                         "20080108T080000",
   1969                         "20080111T080000",
   1970                         "20080114T080000",
   1971                         "20080117T080000",
   1972                         "20080120T080000",
   1973                         "20080123T080000",
   1974                         "20080126T080000",
   1975                         "20080129T080000",
   1976                         "20080201T080000",
   1977                         "20080204T080000",
   1978                         "20080207T080000",
   1979                         "20080210T080000",
   1980                         "20080213T080000",
   1981                         "20080216T080000",
   1982                         "20080219T080000",
   1983                         "20080222T080000",
   1984                         "20080225T080000",
   1985                         "20080228T080000",
   1986                         "20080302T080000",
   1987                         "20080305T080000",
   1988                         "20080308T080000",
   1989                         "20080311T080000",
   1990                         "20080314T080000",
   1991                         "20080317T080000",
   1992                         "20080320T080000",
   1993                         "20080323T080000",
   1994                         "20080326T080000",
   1995                         "20080329T080000",
   1996                         "20080401T080000",
   1997                         "20080404T080000",
   1998                         "20080407T080000",
   1999                         "20080410T080000",
   2000                         "20080413T080000",
   2001                         "20080416T080000",
   2002                         "20080419T080000",
   2003                         "20080422T080000",
   2004                         "20080425T080000",
   2005                         "20080428T080000",
   2006                         "20080501T080000",
   2007                         "20080504T080000",
   2008                         "20080507T080000",
   2009                         "20080510T080000",
   2010                         "20080513T080000",
   2011                         "20080516T080000",
   2012                         "20080519T080000",
   2013                         "20080522T080000",
   2014                         "20080525T080000",
   2015                         "20080528T080000",
   2016                         "20080531T080000",
   2017                         "20080603T080000",
   2018                         "20080606T080000",
   2019                         "20080609T080000",
   2020                         "20080612T080000",
   2021                         "20080615T080000",
   2022                         "20080618T080000",
   2023                         "20080621T080000",
   2024                         "20080624T080000",
   2025                         "20080627T080000",
   2026                         "20080630T080000",
   2027                         "20080703T080000",
   2028                         "20080706T080000",
   2029                         "20080709T080000",
   2030                         "20080712T080000",
   2031                         "20080715T080000",
   2032                         "20080718T080000",
   2033                         "20080721T080000",
   2034                         "20080724T080000",
   2035                         "20080727T080000",
   2036                         "20080730T080000",
   2037                         "20080802T080000",
   2038                         "20080805T080000",
   2039                         "20080808T080000",
   2040                         "20080811T080000",
   2041                         "20080814T080000",
   2042                         "20080817T080000",
   2043                         "20080820T080000",
   2044                         "20080823T080000",
   2045                         "20080826T080000",
   2046                         "20080829T080000",
   2047                         "20080901T080000",
   2048                         "20080904T080000",
   2049                         "20080907T080000",
   2050                         "20080910T080000",
   2051                         "20080913T080000",
   2052                         "20080916T080000",
   2053                         "20080919T080000",
   2054                         "20080922T080000",
   2055                         "20080925T080000",
   2056                         "20080928T080000",
   2057                         "20081001T080000",
   2058                         "20081004T080000",
   2059                         "20081007T080000",
   2060                         "20081010T080000",
   2061                         "20081013T080000",
   2062                         "20081016T080000",
   2063                         "20081019T080000",
   2064                         "20081022T080000",
   2065                         "20081025T080000",
   2066                         "20081028T080000",
   2067                         "20081031T080000",
   2068                         "20081103T080000",
   2069                         "20081106T080000",
   2070                         "20081109T080000",
   2071                         "20081112T080000",
   2072                         "20081115T080000",
   2073                         "20081118T080000",
   2074                         "20081121T080000",
   2075                         "20081124T080000",
   2076                         "20081127T080000",
   2077                         "20081130T080000",
   2078                         "20081203T080000",
   2079                         "20081206T080000",
   2080                         "20081209T080000",
   2081                         "20081212T080000",
   2082                         "20081215T080000",
   2083                         "20081218T080000",
   2084                         "20081221T080000",
   2085                         "20081224T080000",
   2086                         "20081227T080000",
   2087                         "20081230T080000",
   2088                 }, "20081230T080000");
   2089     }
   2090 
   2091     @SmallTest
   2092     public void testFromGoogleCalendar8() throws Exception {
   2093         // Annually on October 4
   2094         verifyRecurrence("20061004T130000",
   2095                 "FREQ=YEARLY;INTERVAL=1;WKST=SU",
   2096                 null /* rdate */, null /* exrule */, null /* exdate */,
   2097                 "20060101T000000", "20090101T000000",
   2098                 new String[]{
   2099                         "20061004T130000",
   2100                         "20071004T130000",
   2101                         "20081004T130000",
   2102                 }, "20081004T130000");
   2103     }
   2104 
   2105     @MediumTest
   2106     public void testFromGoogleCalendar9() throws Exception {
   2107         // Monthly on the last Monday
   2108         verifyRecurrence("20061030T170000",
   2109                 "FREQ=MONTHLY;INTERVAL=1;BYDAY=-1MO;WKST=SU",
   2110                 null /* rdate */, null /* exrule */, null /* exdate */,
   2111                 "20060101T000000", "20090101T000000",
   2112                 new String[]{
   2113                         "20061030T170000",
   2114                         "20061127T170000",
   2115                         "20061225T170000",
   2116                         "20070129T170000",
   2117                         "20070226T170000",
   2118                         "20070326T170000",
   2119                         "20070430T170000",
   2120                         "20070528T170000",
   2121                         "20070625T170000",
   2122                         "20070730T170000",
   2123                         "20070827T170000",
   2124                         "20070924T170000",
   2125                         "20071029T170000",
   2126                         "20071126T170000",
   2127                         "20071231T170000",
   2128                         "20080128T170000",
   2129                         "20080225T170000",
   2130                         "20080331T170000",
   2131                         "20080428T170000",
   2132                         "20080526T170000",
   2133                         "20080630T170000",
   2134                         "20080728T170000",
   2135                         "20080825T170000",
   2136                         "20080929T170000",
   2137                         "20081027T170000",
   2138                         "20081124T170000",
   2139                         "20081229T170000",
   2140                 }, "20081229T170000");
   2141     }
   2142 
   2143     @SmallTest
   2144     public void testFromGoogleCalendar10() throws Exception {
   2145         // Every 7 weeks on Tuesday, Wednesday
   2146         verifyRecurrence("20061004T090000",
   2147                 "FREQ=WEEKLY;UNTIL=20070223T010000Z;INTERVAL=7;BYDAY=TU,WE;WKST=SU",
   2148                 null /* rdate */, null /* exrule */, null /* exdate */,
   2149                 "20060101T000000", "20090101T000000",
   2150                 new String[]{
   2151                         "20061004T090000",
   2152                         "20061121T090000",
   2153                         "20061122T090000",
   2154                         "20070109T090000",
   2155                         "20070110T090000",
   2156                 }, "20070222T170000");
   2157     }
   2158 
   2159     @SmallTest
   2160     public void testFromGoogleCalendar11() throws Exception {
   2161         // Monthly on day 31
   2162         verifyRecurrence("20061031T160000",
   2163                 "FREQ=MONTHLY;INTERVAL=1;WKST=SU",
   2164                 null /* rdate */, null /* exrule */, null /* exdate */,
   2165                 "20060101T000000", "20090101T000000",
   2166                 new String[]{
   2167                         "20061031T160000",
   2168                         "20061231T160000",
   2169                         "20070131T160000",
   2170                         "20070331T160000",
   2171                         "20070531T160000",
   2172                         "20070731T160000",
   2173                         "20070831T160000",
   2174                         "20071031T160000",
   2175                         "20071231T160000",
   2176                         "20080131T160000",
   2177                         "20080331T160000",
   2178                         "20080531T160000",
   2179                         "20080731T160000",
   2180                         "20080831T160000",
   2181                         "20081031T160000",
   2182                         "20081231T160000",
   2183                 },
   2184                 "20081231T160000");
   2185     }
   2186 
   2187     @SmallTest
   2188     public void testFromGoogleCalendar12() throws Exception {
   2189         // Every 2 months on the first Tuesday
   2190         verifyRecurrence("20061004T110000",
   2191                 "FREQ=MONTHLY;INTERVAL=2;BYDAY=1TU;WKST=SU",
   2192                 null /* rdate */, null /* exrule */, null /* exdate */,
   2193                 "20060101T000000", "20090101T000000",
   2194                 new String[]{
   2195                         "20061004T110000",
   2196                         "20061205T110000",
   2197                         "20070206T110000",
   2198                         "20070403T110000",
   2199                         "20070605T110000",
   2200                         "20070807T110000",
   2201                         "20071002T110000",
   2202                         "20071204T110000",
   2203                         "20080205T110000",
   2204                         "20080401T110000",
   2205                         "20080603T110000",
   2206                         "20080805T110000",
   2207                         "20081007T110000",
   2208                         "20081202T110000",
   2209                 },
   2210                 "20081202T110000");
   2211     }
   2212 
   2213     @SmallTest
   2214     public void testYearly0() throws Exception {
   2215         verifyRecurrence("20080101T100000",
   2216                 "FREQ=YEARLY;UNTIL=20090131T090000Z;BYMONTH=1;BYDAY=SU,MO",
   2217                 null /* rdate */, null /* exrule */, null /* exdate */,
   2218                 "20080101T000000", "20090130T000000",
   2219                 new String[]{
   2220                     "20080101T100000",
   2221                     "20080106T100000",
   2222                     "20080107T100000",
   2223                     "20080113T100000",
   2224                     "20080114T100000",
   2225                     "20080120T100000",
   2226                     "20080121T100000",
   2227                     "20080127T100000",
   2228                     "20080128T100000",
   2229                     "20090104T100000",
   2230                     "20090105T100000",
   2231                     "20090111T100000",
   2232                     "20090112T100000",
   2233                     "20090118T100000",
   2234                     "20090119T100000",
   2235                     "20090125T100000",
   2236                     "20090126T100000",
   2237                 }, "20090131T010000");
   2238     }
   2239 
   2240     /**
   2241      * This test fails because of a bug in RecurrenceProcessor.expand(). We
   2242      * don't have time to fix the bug yet but we don't want to lose track of
   2243      * this test either. The "failing" prefix on the method name prevents this
   2244      * test from being run. Remove the "failing" prefix when the bug is fixed.
   2245      *
   2246      * @throws Exception
   2247      */
   2248     @SmallTest
   2249     public void failingTestYearly1() throws Exception {
   2250         verifyRecurrence("20060101T100000",
   2251                 "FREQ=YEARLY;COUNT=10;BYYEARDAY=1,100,200",
   2252                 null /* rdate */, null /* exrule */, null /* exdate */,
   2253                 "20060101T000000", "20090131T000000",
   2254                 new String[]{
   2255                 "20060101T100000",
   2256                 "20060409T100000",
   2257                 "20060718T100000",
   2258                 "20070101T100000",
   2259                 "20070409T100000",
   2260                 "20070718T100000",
   2261                 "20080101T100000",
   2262                 "20080410T100000",
   2263                 "20080719T100000",
   2264                 "20090101T100000",
   2265                 });
   2266     }
   2267 
   2268     /**
   2269      * This test fails because of a bug in RecurrenceProcessor.expand(). We
   2270      * don't have time to fix the bug yet but we don't want to lose track of
   2271      * this test either. The "failing" prefix on the method name prevents this
   2272      * test from being run. Remove the "failing" prefix when the bug is fixed.
   2273      *
   2274      * @throws Exception
   2275      */
   2276     @SmallTest
   2277     public void failingTestYearly2() throws Exception {
   2278         verifyRecurrence("20060101T100000",
   2279                 "FREQ=YEARLY;COUNT=5;BYWEEKNO=6;BYDAY=MO;WKST=MO",
   2280                 null /* rdate */, null /* exrule */, null /* exdate */,
   2281                 "20060101T000000", "20090131T000000",
   2282                 new String[]{
   2283                 "20060101T100000",
   2284                 "20060206T100000",
   2285                 "20070205T100000",
   2286                 "20080204T100000",
   2287                 "20090209T100000",
   2288                 });
   2289     }
   2290 
   2291     /**
   2292      * This test fails because of a bug in RecurrenceProcessor.expand(). We
   2293      * don't have time to fix the bug yet but we don't want to lose track of
   2294      * this test either. The "failing" prefix on the method name prevents this
   2295      * test from being run. Remove the "failing" prefix when the bug is fixed.
   2296      *
   2297      * @throws Exception
   2298      */
   2299     @SmallTest
   2300     public void failingTestYearly3() throws Exception {
   2301         verifyRecurrence("20060101T100000",
   2302                 "FREQ=YEARLY;BYMONTH=3;BYDAY=TH",
   2303                 null /* rdate */, null /* exrule */, null /* exdate */,
   2304                 "20060101T000000", "20090131T000000",
   2305                 new String[]{
   2306                 "20060101T100000",
   2307                 "20060302T100000",
   2308                 "20060309T100000",
   2309                 "20060316T100000",
   2310                 "20060323T100000",
   2311                 "20060330T100000",
   2312                 "20070301T100000",
   2313                 "20070308T100000",
   2314                 "20070315T100000",
   2315                 "20070322T100000",
   2316                 "20070329T100000",
   2317                 "20080306T100000",
   2318                 "20080313T100000",
   2319                 "20080320T100000",
   2320                 "20080327T100000",
   2321                 });
   2322     }
   2323 
   2324     /**
   2325      * This test fails because of a bug in RecurrenceProcessor.expand(). We
   2326      * don't have time to fix the bug yet but we don't want to lose track of
   2327      * this test either. The "failing" prefix on the method name prevents this
   2328      * test from being run. Remove the "failing" prefix when the bug is fixed.
   2329      *
   2330      * @throws Exception
   2331      */
   2332     @SmallTest
   2333     public void failingTestYearly4() throws Exception {
   2334         verifyRecurrence("19920101T100000",
   2335                 "FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8",
   2336                 null /* rdate */, null /* exrule */, null /* exdate */,
   2337                 "19920101T000000", "20121231T000000",
   2338                 new String[]{
   2339                 "19920101T100000",
   2340                 "19921103T100000",
   2341                 "19961105T100000",
   2342                 "20001107T100000",
   2343                 "20041102T100000",
   2344                 "20081104T100000",
   2345                 "20121106T100000",
   2346                 });
   2347     }
   2348 
   2349     /**
   2350      * Test repeating event from Exchange with count field.
   2351      * Time range covers the whole repetition.
   2352      *
   2353      * @throws Exception
   2354      */
   2355     public void testCount1() throws Exception {
   2356         verifyRecurrence("20100324T153000",
   2357                 "FREQ=WEEKLY;INTERVAL=1;COUNT=10;BYDAY=WE",
   2358                 null /* rdate */, null /* exrule */, null /* exdate */,
   2359                 "20100301T000000", "20100630T000000",
   2360                 new String[]{
   2361                         "20100324T153000",
   2362                         "20100331T153000",
   2363                         "20100407T153000",
   2364                         "20100414T153000",
   2365                         "20100421T153000",
   2366                         "20100428T153000",
   2367                         "20100505T153000",
   2368                         "20100512T153000",
   2369                         "20100519T153000",
   2370                         "20100526T153000",
   2371                 });
   2372     }
   2373 
   2374     /**
   2375      * Test repeating event from Exchange with count field.
   2376      * Time range covers the first part of the repetition.
   2377      * @throws Exception
   2378      */
   2379     public void testCount2() throws Exception {
   2380         verifyRecurrence("20100324T153000",
   2381                 "FREQ=WEEKLY;INTERVAL=1;COUNT=10;BYDAY=WE",
   2382                 null /* rdate */, null /* exrule */, null /* exdate */,
   2383                 "20100501T000000", "20100630T000000",
   2384                 new String[]{
   2385                         "20100505T153000",
   2386                         "20100512T153000",
   2387                         "20100519T153000",
   2388                         "20100526T153000",
   2389                 });
   2390     }
   2391 
   2392     /**
   2393      * Test repeating event from Exchange with count field.
   2394      * Time range is beyond the repetition.
   2395      * @throws Exception
   2396      */
   2397     public void testCount3() throws Exception {
   2398         verifyRecurrence("20100324T153000",
   2399                 "FREQ=WEEKLY;INTERVAL=1;COUNT=10;BYDAY=WE",
   2400                 null /* rdate */, null /* exrule */, null /* exdate */,
   2401                 "20100601T000000", "20100630T000000",
   2402                 new String[]{},
   2403                 "20100526T153000" /* last */);
   2404     }
   2405 
   2406     /**
   2407      * Test repeating event from Exchange with count field.
   2408      * Time range is before the repetition
   2409      * @throws Exception
   2410      */
   2411     public void testCount4() throws Exception {
   2412         verifyRecurrence("20100324T153000",
   2413                 "FREQ=WEEKLY;INTERVAL=1;COUNT=10;BYDAY=WE",
   2414                 null /* rdate */, null /* exrule */, null /* exdate */,
   2415                 "20100101T000000", "20100301T000000",
   2416                 new String[]{},
   2417                 null /* last */);
   2418     }
   2419 
   2420 
   2421     // These recurrence rules are used in the loop that measures the performance
   2422     // of recurrence expansion.
   2423     private static final String[] performanceRrules = new String[] {
   2424         "FREQ=DAILY;COUNT=100",
   2425         "FREQ=DAILY;INTERVAL=2;UNTIL=20080101T000000Z",
   2426         "FREQ=YEARLY;UNTIL=20090131T090000Z;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA",
   2427         "FREQ=WEEKLY;INTERVAL=2;WKST=SU",
   2428         "FREQ=WEEKLY;COUNT=100;WKST=SU;BYDAY=MO,TU,WE,TH,FR",
   2429         "FREQ=MONTHLY;COUNT=100;BYDAY=1FR",
   2430         "FREQ=MONTHLY;INTERVAL=2;COUNT=100;BYDAY=1SU,-1SU",
   2431         "FREQ=MONTHLY;BYMONTHDAY=1,15",
   2432         "FREQ=MONTHLY;INTERVAL=3;COUNT=100;BYMONTHDAY=10,11,12,13,14",
   2433         "FREQ=YEARLY;COUNT=100;BYMONTH=6,7,8",
   2434         "FREQ=YEARLY;INTERVAL=2;BYMONTH=1,2,3,6,7,8",
   2435         "FREQ=YEARLY;COUNT=100;BYYEARDAY=1,100,200",
   2436         "FREQ=YEARLY;BYDAY=2MO",
   2437         "FREQ=YEARLY;BYWEEKNO=2,3,4;BYDAY=MO",
   2438         "FREQ=YEARLY;BYMONTH=3,4,5;BYDAY=TH",
   2439         "FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13",
   2440         "FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13",
   2441         "FREQ=YEARLY;INTERVAL=2;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8",
   2442         "FREQ=WEEKLY;INTERVAL=2;COUNT=100;BYDAY=TU,SU;WKST=MO",
   2443         "FREQ=WEEKLY;INTERVAL=2;COUNT=100;BYDAY=TU,SU;WKST=SU",
   2444     };
   2445 
   2446     /**
   2447      * This test never fails.  It just runs for a while (about 10 seconds)
   2448      * in order to measure the performance of recurrence expansion.
   2449      *
   2450      * @throws Exception
   2451      */
   2452     @LargeTest
   2453     public void performanceTextExpand() throws Exception {
   2454         String tz = "America/Los_Angeles";
   2455         Time dtstart = new Time(tz);
   2456         Time rangeStart = new Time(tz);
   2457         Time rangeEnd = new Time(tz);
   2458         TreeSet<Long> out = new TreeSet<Long>();
   2459 
   2460         dtstart.parse("20010101T000000");
   2461         rangeStart.parse("20010101T000000");
   2462         rangeEnd.parse("20090101T000000");
   2463         long rangeStartMillis = rangeStart.toMillis(false /* use isDst */);
   2464         long rangeEndMillis = rangeEnd.toMillis(false /* use isDst */);
   2465 
   2466         long startTime = System.currentTimeMillis();
   2467         for (int iterations = 0; iterations < 5; iterations++) {
   2468             RecurrenceProcessor rp = new RecurrenceProcessor();
   2469 
   2470             int len = performanceRrules.length;
   2471             for (int i = 0; i < len; i++) {
   2472                 String rrule = performanceRrules[i];
   2473                 //Log.i(TAG, "expanding rule: " + rrule);
   2474                 RecurrenceSet recur = new RecurrenceSet(rrule, null, null, null);
   2475 
   2476                 long [] dates = rp.expand(dtstart, recur, rangeStartMillis, rangeEndMillis);
   2477                 //Log.i(TAG, "num instances: " + out.size());
   2478 
   2479                 // Also include the time to iterate through the expanded values
   2480                 for (long date : dates) {
   2481                     // Use the date so that this loop is not optimized away.
   2482                     if (date == -1) {
   2483                         Log.e(TAG, "unexpected date");
   2484                         break;
   2485                     }
   2486                 }
   2487                 out.clear();
   2488             }
   2489         }
   2490 
   2491         long endTime = System.currentTimeMillis();
   2492         long elapsed = endTime - startTime;
   2493         Log.i(TAG, "testPerformanceExpand() expand() elapsed millis: " + elapsed);
   2494     }
   2495 
   2496     @LargeTest
   2497     public void performanceTestNormalize() throws Exception {
   2498         final int ITERATIONS = 50000;
   2499 
   2500         String tz = "America/Los_Angeles";
   2501         Time date = new Time(tz);
   2502         date.parse("20090404T100000");
   2503 
   2504         long startTime = System.currentTimeMillis();
   2505 
   2506         for (int i = 0; i < ITERATIONS; i++) {
   2507             date.month += 1;
   2508             date.monthDay += 100;
   2509             date.normalize(true);
   2510             date.month -= 1;
   2511             date.monthDay -= 100;
   2512             date.normalize(true);
   2513         }
   2514 
   2515         long endTime = System.currentTimeMillis();
   2516         long elapsed = endTime - startTime;
   2517         Log.i(TAG, "date: " + date.format2445());
   2518         Log.i(TAG, "testPerformanceNormalize() normalize() elapsed millis: " + elapsed);
   2519 
   2520         // Time the unsafe version
   2521         date.parse("20090404T100000");
   2522         startTime = System.currentTimeMillis();
   2523         for (int i = 0; i < ITERATIONS; i++) {
   2524             date.month += 1;
   2525             date.monthDay += 100;
   2526             RecurrenceProcessor.unsafeNormalize(date);
   2527             date.month -= 1;
   2528             date.monthDay -= 100;
   2529             RecurrenceProcessor.unsafeNormalize(date);
   2530         }
   2531 
   2532         endTime = System.currentTimeMillis();
   2533         elapsed = endTime - startTime;
   2534         Log.i(TAG, "date: " + date.format2445());
   2535         Log.i(TAG, "testPerformanceNormalize() unsafeNormalize() elapsed millis: " + elapsed);
   2536     }
   2537  }
   2538