home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / test / intltest / calregts.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-19  |  59.5 KB  |  1,656 lines

  1. /*
  2. ********************************************************************
  3. * COPYRIGHT: 
  4. * (C) Copyright International Business Machines Corporation, 1998
  5. * Licensed Material - Program-Property of IBM - All Rights Reserved. 
  6. * US Government Users Restricted Rights - Use, duplication, or disclosure 
  7. * restricted by GSA ADP Schedule Contract with IBM Corp. 
  8. *
  9. ********************************************************************
  10. */
  11.  
  12. #include "calregts.h"
  13.  
  14. #include "gregocal.h"
  15. #include "simpletz.h"
  16. #include "smpdtfmt.h"
  17.  
  18. #include <float.h>
  19. #include <limits.h> // LONG_{MIN,MAX}
  20.  
  21. // *****************************************************************************
  22. // class CalendarRegressionTest
  23. // *****************************************************************************
  24.  
  25. // these numbers correspond to using LONG_MIN and LONG_MAX in Java
  26. // this is 2^52 - 1, the largest allowable mantissa with a 0 exponent in a 64-bit double
  27. const UDate CalendarRegressionTest::EARLIEST_SUPPORTED_MILLIS = - 4503599627370495.0;
  28. const UDate CalendarRegressionTest::LATEST_SUPPORTED_MILLIS    =   4503599627370495.0;
  29.  
  30. #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break;
  31.  
  32. void 
  33. CalendarRegressionTest::runIndexedTest( int32_t index, bool_t exec, char* &name, char* par )
  34. {
  35.     // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
  36.     switch (index) {
  37.         CASE(0,test4100311)
  38.         CASE(1,test4074758)
  39.         CASE(2,test4028518)
  40.         CASE(3,test4031502)
  41.         CASE(4,test4035301) 
  42.         CASE(5,test4040996) 
  43.         CASE(6,test4051765) 
  44.         CASE(7,test4061476) 
  45.         CASE(8,test4070502) 
  46.         CASE(9,test4071197) 
  47.         CASE(10,test4071385) 
  48.         CASE(11,test4073929) 
  49.         CASE(12,test4083167) 
  50.         CASE(13,test4086724) 
  51.         CASE(14,test4095407) 
  52.         CASE(15,test4096231) 
  53.         CASE(16,test4096539) 
  54.         CASE(17,test41003112) 
  55.         CASE(18,test4103271) 
  56.         CASE(19,test4106136) 
  57.         CASE(20,test4108764) 
  58.         CASE(21,test4114578) 
  59.         CASE(22,test4118384) 
  60.         CASE(23,test4125881) 
  61.         CASE(24,test4125892) 
  62.         CASE(25,test4141665) 
  63.         CASE(26,test4142933) 
  64.         CASE(27,test4145158) 
  65.         CASE(28,test4145983) 
  66.         CASE(29,test4147269) 
  67.         
  68.         CASE(30,Test4149677) 
  69.         CASE(31,Test4162587) 
  70.         CASE(32,Test4165343) 
  71.         CASE(33,Test4166109) 
  72.         CASE(34,Test4167060) 
  73.         CASE(35,Test4197699)
  74.  
  75.     default: name = ""; break;
  76.     }
  77. }
  78.  
  79. bool_t 
  80. CalendarRegressionTest::failure(UErrorCode status, const char* msg)
  81. {
  82.     if(U_FAILURE(status)) {
  83.         errln(UnicodeString("FAIL: ") + msg + " failed, error " + errorName(status));
  84.         return TRUE;
  85.     }
  86.  
  87.     return FALSE;
  88. }
  89.  
  90. /*
  91.  * bug 4100311
  92.  */
  93. void 
  94. CalendarRegressionTest::test4100311()
  95. {
  96.     UErrorCode status = U_ZERO_ERROR;
  97.     GregorianCalendar *cal = (GregorianCalendar*)Calendar::createInstance(status);
  98.     failure(status, "Calendar::createInstance(status)");
  99.     cal->set(Calendar::YEAR, 1997);
  100.     cal->set(Calendar::DAY_OF_YEAR, 1);
  101.     UDate d = cal->getTime(status);             // Should be Jan 1
  102.     failure(status, "cal->getTime");
  103.     logln(UnicodeString("") + d);
  104.     delete cal;
  105. }
  106.  
  107.  
  108. /**
  109.  * @bug 4074758
  110.  */
  111. void
  112. CalendarRegressionTest::test4074758()
  113. {       //Set system time to between 12-1 (am or pm) and then run
  114.     UErrorCode status = U_ZERO_ERROR;
  115.     GregorianCalendar *cal = new GregorianCalendar(status);
  116.     failure(status, "new GregorianCalendar");
  117.     for (int32_t h=0; h<25; ++h) {
  118.         cal->set(97, Calendar::JANUARY, 1, h, 34);
  119.         //System.out.print(d);
  120.         logln(UnicodeString("HOUR=") + cal->get(Calendar::HOUR, status)); //prints 0
  121.         failure(status, "cal->get");
  122.         logln(UnicodeString("HOUR_OF_DAY=") + cal->get(Calendar::HOUR_OF_DAY, status));
  123.         failure(status, "cal->get");
  124.     }
  125.  
  126.     delete cal;
  127. }
  128.  
  129. void
  130. CalendarRegressionTest::test4028518()
  131. {
  132.     UErrorCode status = U_ZERO_ERROR;
  133.     GregorianCalendar *cal1 = new GregorianCalendar(status) ;
  134.     failure(status, "new GregorianCalendar");
  135.     GregorianCalendar *cal2 = (GregorianCalendar*) cal1->clone() ;
  136.  
  137.     printdate(cal1, "cal1: ") ;
  138.     printdate(cal2, "cal2 - cloned(): ") ;
  139.     cal1->add(GregorianCalendar::DATE, 1, status) ;
  140.     failure(status, "cal1->add");
  141.     printdate(cal1, "cal1 after adding 1 day:") ;
  142.     printdate(cal2, "cal2 should be unmodified:") ;
  143. }
  144.  
  145. void 
  146. CalendarRegressionTest::printdate(GregorianCalendar *cal, char *string)
  147. {
  148.     UErrorCode status = U_ZERO_ERROR;
  149.     logln(UnicodeString(string));
  150.     log(UnicodeString("") + cal->get(GregorianCalendar::MONTH, status)) ;
  151.     failure(status, "cal->get");
  152.     int32_t date = cal->get(GregorianCalendar::DATE, status) + 1 ;
  153.     failure(status, "cal->get");
  154.     log(UnicodeString("/") + date) ;
  155.     logln(UnicodeString("/") + cal->get(GregorianCalendar::YEAR, status)) ;
  156.     failure(status, "cal->get");
  157. }
  158.  
  159. /**
  160.  * @bug 4031502
  161.  */
  162. void 
  163. CalendarRegressionTest::test4031502() 
  164. {
  165.     // This bug actually occurs on Windows NT as well, and doesn't
  166.     // require the host zone to be set; it can be set in Java.
  167.     UErrorCode status = U_ZERO_ERROR;
  168.     int32_t count = 0;
  169.     const UnicodeString **ids = TimeZone::createAvailableIDs(count);
  170.     bool_t bad = FALSE;
  171.     for (int32_t i=0; i<count; ++i) {
  172.         TimeZone *zone = TimeZone::createTimeZone(*ids[i]);
  173.         GregorianCalendar *cal = new GregorianCalendar(zone, status);
  174.         failure(status, "new GregorianCalendar");
  175.         cal->clear();
  176.         cal->set(1900, 15, 5, 5, 8, 13);
  177.         if (cal->get(Calendar::HOUR, status) != 5 || U_FAILURE(status)) {
  178.             UnicodeString temp;
  179.             logln(zone->getID(temp) + " " +
  180.                                //zone.useDaylightTime() + " " +
  181.                                cal->get(Calendar::DST_OFFSET,status) / (60*60*1000) + " " +
  182.                                zone->getRawOffset() / (60*60*1000) +
  183.                                ": HOUR = " + cal->get(Calendar::HOUR,status));
  184.             bad = TRUE;
  185.         }
  186.         delete cal;
  187.     }
  188.     if (bad) 
  189.         errln("TimeZone problems with GC");
  190.     delete [] ids;
  191. }
  192.  
  193.     /**
  194.      * @bug 4035301
  195.      */
  196.     void CalendarRegressionTest::test4035301() 
  197.     {
  198.         UErrorCode status = U_ZERO_ERROR;
  199.         GregorianCalendar *c = new GregorianCalendar(98, 8, 7,status);
  200.         GregorianCalendar *d = new GregorianCalendar(98, 8, 7,status);
  201.         if (c->after(*d,status) ||
  202.             c->after(*c,status) ||
  203.             c->before(*d,status) ||
  204.             c->before(*c,status) ||
  205.             *c != *c ||
  206.             *c != *d)
  207.             errln("Fail");
  208.         delete c;
  209.         delete d;
  210.     }
  211.  
  212.     /**
  213.      * @bug 4040996
  214.      */
  215.     void CalendarRegressionTest::test4040996() 
  216.     {
  217.         int32_t count = 0;
  218.         const UnicodeString **ids = TimeZone::createAvailableIDs(-8 * 60 * 60 * 1000, count);
  219.         SimpleTimeZone *pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, *ids[0]);
  220.         UErrorCode status = U_ZERO_ERROR;
  221.         pdt->setStartRule(Calendar::APRIL, 1, Calendar::SUNDAY, 2 * 60 * 60 * 1000, status);
  222.         pdt->setEndRule(Calendar::OCTOBER, -1, Calendar::SUNDAY, 2 * 60 * 60 * 1000, status);
  223.         Calendar *calendar = new GregorianCalendar(pdt, status);
  224.  
  225.         calendar->set(Calendar::MONTH,3);
  226.         calendar->set(Calendar::DAY_OF_MONTH,18);
  227.         calendar->set(Calendar::SECOND, 30);
  228.  
  229.         logln(UnicodeString("MONTH: ") + calendar->get(Calendar::MONTH, status));
  230.         logln(UnicodeString("DAY_OF_MONTH: ") + 
  231.                            calendar->get(Calendar::DAY_OF_MONTH, status));
  232.         logln(UnicodeString("MINUTE: ") + calendar->get(Calendar::MINUTE, status));
  233.         logln(UnicodeString("SECOND: ") + calendar->get(Calendar::SECOND, status));
  234.  
  235.         calendar->add(Calendar::SECOND,6, status);
  236.         //This will print out todays date for MONTH and DAY_OF_MONTH
  237.         //instead of the date it was set to.
  238.         //This happens when adding MILLISECOND or MINUTE also
  239.         logln(UnicodeString("MONTH: ") + calendar->get(Calendar::MONTH, status));
  240.         logln(UnicodeString("DAY_OF_MONTH: ") + 
  241.                            calendar->get(Calendar::DAY_OF_MONTH, status));
  242.         logln(UnicodeString("MINUTE: ") + calendar->get(Calendar::MINUTE, status));
  243.         logln(UnicodeString("SECOND: ") + calendar->get(Calendar::SECOND, status));
  244.         if (calendar->get(Calendar::MONTH, status) != 3 ||
  245.             calendar->get(Calendar::DAY_OF_MONTH, status) != 18 ||
  246.             calendar->get(Calendar::SECOND, status) != 36)
  247.             errln(UnicodeString("Fail: Calendar::add misbehaves"));
  248.     
  249.         delete calendar;
  250.     }
  251.  
  252.     /**
  253.      * @bug 4051765
  254.      */
  255.     void CalendarRegressionTest::test4051765() 
  256.     {
  257.         UErrorCode status = U_ZERO_ERROR;
  258.         Calendar *cal = Calendar::createInstance(status);
  259.         cal->setLenient(FALSE);
  260.         cal->set(Calendar::DAY_OF_WEEK, 0);
  261.         //try {
  262.             cal->getTime(status);
  263.             if( ! U_FAILURE(status))
  264.                 errln("Fail: DAY_OF_WEEK 0 should be disallowed");
  265.         /*}
  266.         catch (IllegalArgumentException e) {
  267.             return;
  268.         }*/
  269.     
  270.         delete cal;
  271.     }
  272.     
  273.     /* User error - no bug here
  274.     void CalendarRegressionTest::test4059524() {
  275.         // Create calendar for April 10, 1997
  276.         GregorianCalendar calendar  = new GregorianCalendar(status);
  277.         // print out a bunch of interesting things
  278.         logln("ERA: " + Calendar::get(Calendar::ERA));
  279.         logln("YEAR: " + Calendar::get(Calendar::YEAR));
  280.         logln("MONTH: " + Calendar::get(Calendar::MONTH));
  281.         logln("WEEK_OF_YEAR: " + 
  282.                            Calendar::get(Calendar::WEEK_OF_YEAR));
  283.         logln("WEEK_OF_MONTH: " + 
  284.                            Calendar::get(Calendar::WEEK_OF_MONTH));
  285.         logln("DATE: " + Calendar::get(Calendar::DATE));
  286.         logln("DAY_OF_MONTH: " + 
  287.                            Calendar::get(Calendar::DAY_OF_MONTH));
  288.         logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
  289.         logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
  290.         logln("DAY_OF_WEEK_IN_MONTH: " +
  291.                            Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
  292.         logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
  293.         logln("HOUR: " + Calendar::get(Calendar::HOUR));
  294.         logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
  295.         logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
  296.         logln("SECOND: " + Calendar::get(Calendar::SECOND));
  297.         logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
  298.         logln("ZONE_OFFSET: "
  299.                            + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000)));
  300.         logln("DST_OFFSET: "
  301.                            + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000)));
  302.         calendar  = new GregorianCalendar(1997,3,10); 
  303.         Calendar::getTime();                        
  304.         logln("April 10, 1997");
  305.         logln("ERA: " + Calendar::get(Calendar::ERA));
  306.         logln("YEAR: " + Calendar::get(Calendar::YEAR));
  307.         logln("MONTH: " + Calendar::get(Calendar::MONTH));
  308.         logln("WEEK_OF_YEAR: " + 
  309.                            Calendar::get(Calendar::WEEK_OF_YEAR));
  310.         logln("WEEK_OF_MONTH: " + 
  311.                            Calendar::get(Calendar::WEEK_OF_MONTH));
  312.         logln("DATE: " + Calendar::get(Calendar::DATE));
  313.         logln("DAY_OF_MONTH: " + 
  314.                            Calendar::get(Calendar::DAY_OF_MONTH));
  315.         logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
  316.         logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
  317.         logln("DAY_OF_WEEK_IN_MONTH: " + Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
  318.         logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
  319.         logln("HOUR: " + Calendar::get(Calendar::HOUR));
  320.         logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
  321.         logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
  322.         logln("SECOND: " + Calendar::get(Calendar::SECOND));
  323.         logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
  324.         logln("ZONE_OFFSET: "
  325.                            + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000))); // in hours
  326.         logln("DST_OFFSET: "
  327.                            + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); // in hours
  328.     }
  329.     */
  330.  
  331.     /**
  332.      * @bug 4059654
  333.      */
  334.     void CalendarRegressionTest::test4059654() {
  335.         UErrorCode status = U_ZERO_ERROR;
  336.         GregorianCalendar *gc = new GregorianCalendar(status);
  337.         
  338.         gc->set(1997, 3, 1, 15, 16, 17); // April 1, 1997
  339.  
  340.         gc->set(Calendar::HOUR, 0);
  341.         gc->set(Calendar::AM_PM, Calendar::AM);
  342.         gc->set(Calendar::MINUTE, 0);
  343.         gc->set(Calendar::SECOND, 0);
  344.         gc->set(Calendar::MILLISECOND, 0);
  345.  
  346.         UDate cd = gc->getTime(status);
  347.         GregorianCalendar *exp = new GregorianCalendar(97, 3, 1, 0, 0, 0, status);
  348.         if (cd != exp->getTime(status))
  349.             errln(UnicodeString("Fail: Calendar::set broken. Got ") + cd + " Want " + exp->getTime(status));
  350.     
  351.         delete gc;
  352.         delete exp;
  353.     }
  354.  
  355.     /**
  356.      * @bug 4061476
  357.      */
  358.     void CalendarRegressionTest::test4061476() 
  359.     {
  360.         UErrorCode status = U_ZERO_ERROR;
  361.         SimpleDateFormat *fmt = new SimpleDateFormat("ddMMMyy", Locale::UK,status);
  362.         Calendar *cal = Calendar::createInstance(TimeZone::createTimeZone("GMT"), 
  363.                                         Locale::UK,status);
  364.         fmt->adoptCalendar(cal);
  365.         // try {
  366.                 UDate date = fmt->parse("29MAY97", status);
  367.                 failure(status, "fmt->parse");
  368.                 cal->setTime(date, status);
  369.                 failure(status, "cal->setTime");
  370.          //   }
  371.         //catch (Exception e) {;}
  372.         cal->set(Calendar::HOUR_OF_DAY, 13);
  373.         logln(UnicodeString("Hour: ")+cal->get(Calendar::HOUR_OF_DAY, status));
  374.         cal->add(Calendar::HOUR_OF_DAY, 6,status);
  375.         logln(UnicodeString("Hour: ")+cal->get(Calendar::HOUR_OF_DAY, status));
  376.         if (cal->get(Calendar::HOUR_OF_DAY, status) != 19)
  377.             errln(UnicodeString("Fail: Want 19 Got ") + cal->get(Calendar::HOUR_OF_DAY, status));
  378.     
  379.         delete fmt;
  380.     }
  381.  
  382.     /**
  383.      * @bug 4070502
  384.      */
  385.     void CalendarRegressionTest::test4070502() 
  386.     {
  387.         UErrorCode status = U_ZERO_ERROR;
  388.         UDate d = getAssociatedDate(makeDate(1998,0,30), status);
  389.         Calendar *cal = new GregorianCalendar(status);
  390.         cal->setTime(d,status);
  391.         if (cal->get(Calendar::DAY_OF_WEEK,status) == Calendar::SATURDAY ||
  392.             cal->get(Calendar::DAY_OF_WEEK,status) == Calendar::SUNDAY)
  393.             errln(UnicodeString("Fail: Want weekday Got ") + d);
  394.     
  395.         delete cal;
  396.     }
  397.  
  398.     /**
  399.      * Get the associated date starting from a specified date
  400.      * NOTE: the unnecessary "getTime()'s" below are a work-around for a
  401.      * bug in jdk 1.1.3 (and probably earlier versions also)
  402.      * <p>
  403.      * @param date The date to start from
  404.      */
  405.     UDate 
  406.     CalendarRegressionTest::getAssociatedDate(UDate d, UErrorCode& status) 
  407.     {
  408.         GregorianCalendar *cal = new GregorianCalendar(status);
  409.         cal->setTime(d,status);
  410.         //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH 
  411.         // cal.getTime();  // <--- REMOVE THIS TO SEE BUG
  412.         while (TRUE) {
  413.             int32_t wd = cal->get(Calendar::DAY_OF_WEEK, status);
  414.             if (wd == Calendar::SATURDAY || wd == Calendar::SUNDAY) {
  415.                 cal->add(Calendar::DATE, 1, status);
  416.                 // cal.getTime();
  417.             }
  418.             else
  419.                 break;
  420.         }
  421.         
  422.         UDate dd = cal->getTime(status);
  423.         delete cal;
  424.         return dd;
  425.     }
  426.  
  427.     /**
  428.      * @bug 4071197
  429.      */
  430.     void CalendarRegressionTest::test4071197() 
  431.     {
  432.         dowTest(FALSE);
  433.         dowTest(TRUE);
  434.     }
  435.  
  436.     void CalendarRegressionTest::dowTest(bool_t lenient) 
  437.     {
  438.         UErrorCode status = U_ZERO_ERROR;
  439.         GregorianCalendar *cal = new GregorianCalendar(status);
  440.         cal->set(1997, Calendar::AUGUST, 12); // Wednesday
  441.         // cal.getTime(); // Force update
  442.         cal->setLenient(lenient);
  443.         cal->set(1996, Calendar::DECEMBER, 1); // Set the date to be December 1, 1996
  444.         int32_t dow = cal->get(Calendar::DAY_OF_WEEK, status);
  445.         int32_t min = cal->getMinimum(Calendar::DAY_OF_WEEK);
  446.         int32_t max = cal->getMaximum(Calendar::DAY_OF_WEEK);
  447.         //logln(cal.getTime().toString());
  448.         if (min != Calendar::SUNDAY || max != Calendar::SATURDAY)
  449.             errln("FAIL: Min/max bad");
  450.         if (dow < min || dow > max) 
  451.             errln(UnicodeString("FAIL: Day of week ") + dow + " out of range");
  452.         if (dow != Calendar::SUNDAY) 
  453.             errln("FAIL: Day of week should be SUNDAY Got " + dow);
  454.     
  455.         delete cal;
  456.     }
  457.  
  458.     /**
  459.      * @bug 4071385
  460.      */
  461.     void CalendarRegressionTest::test4071385() 
  462.     {
  463.         UErrorCode status = U_ZERO_ERROR;
  464.         Calendar *cal = Calendar::createInstance(status);
  465.         cal->setTime(makeDate(1998, Calendar::JUNE, 24),status);
  466.         cal->set(Calendar::MONTH, Calendar::NOVEMBER); // change a field
  467.         //logln(cal.getTime().toString());
  468.         if (cal->getTime(status) != makeDate(1998, Calendar::NOVEMBER, 24))
  469.             errln("Fail");
  470.     
  471.         delete cal;
  472.     }
  473.  
  474.     /**
  475.      * @bug 4073929
  476.      */
  477.     void CalendarRegressionTest::test4073929() 
  478.     {
  479.         UErrorCode status = U_ZERO_ERROR;
  480.         GregorianCalendar *foo1 = new GregorianCalendar(1997, 8, 27,status);
  481.         foo1->add(Calendar::DAY_OF_MONTH, + 1, status);
  482.         int32_t testyear = foo1->get(Calendar::YEAR, status);
  483.         int32_t testmonth = foo1->get(Calendar::MONTH, status);
  484.         int32_t testday = foo1->get(Calendar::DAY_OF_MONTH, status);
  485.         if (testyear != 1997 ||
  486.             testmonth != 8 ||
  487.             testday != 28)
  488.             errln("Fail: Calendar not initialized");
  489.     
  490.         delete foo1;
  491.     }
  492.  
  493.     /**
  494.      * @bug 4083167
  495.      */
  496.     void CalendarRegressionTest::test4083167() 
  497.     {
  498.         UErrorCode status = U_ZERO_ERROR;
  499.         TimeZone *saveZone = TimeZone::createDefault();
  500.         //try {
  501.         TimeZone *newZone = TimeZone::createTimeZone("UTC");
  502.         TimeZone::setDefault(*newZone);
  503.         UDate firstDate = Calendar::getNow();
  504.             Calendar *cal = new GregorianCalendar(status);
  505.             cal->setTime(firstDate,status);
  506.             int32_t hr        = cal->get(Calendar::HOUR_OF_DAY, status);
  507.             int32_t min        = cal->get(Calendar::MINUTE, status);
  508.             int32_t sec        = cal->get(Calendar::SECOND, status);
  509.             int32_t msec    = cal->get(Calendar::MILLISECOND, status);
  510.             double firstMillisInDay = hr * 3600000 + min * 60000 + sec * 1000 + msec;
  511.             
  512.             //logln("Current time: " + firstDate.toString());
  513.  
  514.             for (int32_t validity=0; validity<30; validity++) {
  515.                 UDate lastDate = firstDate + validity*1000*24*60*60.0;
  516.                 cal->setTime(lastDate, status);
  517.                 hr        = cal->get(Calendar::HOUR_OF_DAY, status);
  518.                 min        = cal->get(Calendar::MINUTE, status);
  519.                 sec        = cal->get(Calendar::SECOND, status);
  520.                 msec    = cal->get(Calendar::MILLISECOND, status);
  521.                 double millisInDay = hr * 3600000.0 + min * 60000.0 + sec * 1000.0 + msec;
  522.                 if (firstMillisInDay != millisInDay) 
  523.                     errln(UnicodeString("Day has shifted ") + lastDate);
  524.             }
  525.         //}
  526.         //finally {
  527.             TimeZone::setDefault(*saveZone);
  528.         //}
  529.     
  530.         delete saveZone;
  531.         delete newZone;
  532.     }
  533.  
  534.     /**
  535.      * @bug 4086724
  536.      */
  537.     void CalendarRegressionTest::test4086724() 
  538.     {
  539.         UErrorCode status = U_ZERO_ERROR;
  540.         SimpleDateFormat *date;
  541.         TimeZone *saveZone = TimeZone::createDefault();
  542.         Locale saveLocale = Locale::getDefault();
  543.         //try {
  544.         Locale::setDefault(Locale::UK,status); 
  545.         TimeZone *newZone = TimeZone::createTimeZone("GMT");
  546.         TimeZone::setDefault(*newZone);
  547.             date = new SimpleDateFormat("dd MMM yyy (zzzz) 'is in week' ww",status); 
  548.             Calendar *cal = Calendar::createInstance(status); 
  549.             cal->set(1997,Calendar::SEPTEMBER,30); 
  550.             UDate now = cal->getTime(status); 
  551.             UnicodeString temp;
  552.             FieldPosition pos(FieldPosition::DONT_CARE);
  553.             logln(date->format(now, temp, pos)); 
  554.             cal->set(1997,Calendar::JANUARY,1); 
  555.             now=cal->getTime(status); 
  556.             logln(date->format(now,temp, pos)); 
  557.             cal->set(1997,Calendar::JANUARY,8); 
  558.             now=cal->getTime(status); 
  559.             logln(date->format(now,temp, pos)); 
  560.             cal->set(1996,Calendar::DECEMBER,31); 
  561.             now=cal->getTime(status); 
  562.             logln(date->format(now,temp, pos)); 
  563.         //}
  564.         //finally {
  565.             Locale::setDefault(saveLocale,status);
  566.             TimeZone::setDefault(*saveZone);
  567.         //}
  568.         logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
  569.     
  570.     delete newZone;
  571. }
  572.  
  573.     /**
  574.      * @bug 4092362
  575.      */
  576.     void CalendarRegressionTest::test4092362() {
  577.         UErrorCode status = U_ZERO_ERROR;
  578.         GregorianCalendar *cal1 = new GregorianCalendar(1997, 10, 11, 10, 20, 40,status); 
  579.         /*cal1.set( Calendar::YEAR, 1997 ); 
  580.         cal1.set( Calendar::MONTH, 10 ); 
  581.         cal1.set( Calendar::DATE, 11 ); 
  582.         cal1.set( Calendar::HOUR, 10 ); 
  583.         cal1.set( Calendar::MINUTE, 20 ); 
  584.         cal1.set( Calendar::SECOND, 40 ); */
  585.  
  586.         logln( UnicodeString(" Cal1 = ") + cal1->getTime(status) ); 
  587.         logln( UnicodeString(" Cal1 time in ms = ") + cal1->get(Calendar::MILLISECOND,status) ); 
  588.         for( int32_t k = 0; k < 100 ; k++ ); 
  589.  
  590.         GregorianCalendar *cal2 = new GregorianCalendar(1997, 10, 11, 10, 20, 40,status); 
  591.         /*cal2.set( Calendar::YEAR, 1997 ); 
  592.         cal2.set( Calendar::MONTH, 10 ); 
  593.         cal2.set( Calendar::DATE, 11 ); 
  594.         cal2.set( Calendar::HOUR, 10 ); 
  595.         cal2.set( Calendar::MINUTE, 20 ); 
  596.         cal2.set( Calendar::SECOND, 40 ); */
  597.  
  598.         logln( UnicodeString(" Cal2 = ") + cal2->getTime(status) ); 
  599.         logln( UnicodeString(" Cal2 time in ms = ") + cal2->get(Calendar::MILLISECOND,status) ); 
  600.         if( *cal1 != *cal2 ) 
  601.             errln("Fail: Milliseconds randomized");
  602.     
  603.         delete cal1;
  604.         delete cal2;
  605.     }
  606.  
  607.     /**
  608.      * @bug 4095407
  609.      */
  610.     void CalendarRegressionTest::test4095407() 
  611.     {
  612.         UErrorCode status = U_ZERO_ERROR;
  613.         GregorianCalendar *a = new GregorianCalendar(1997,Calendar::NOVEMBER, 13,status);
  614.         int32_t dow = a->get(Calendar::DAY_OF_WEEK, status);
  615.         if (dow != Calendar::THURSDAY)
  616.             errln("Fail: Want THURSDAY Got " + dow);
  617.     
  618.         delete a;
  619.     }
  620.  
  621.     /**
  622.      * @bug 4096231
  623.      */
  624.     void CalendarRegressionTest::test4096231() 
  625.     {
  626.         UErrorCode status = U_ZERO_ERROR;
  627.         TimeZone *GMT = TimeZone::createTimeZone("GMT");
  628.         TimeZone *PST = TimeZone::createTimeZone("PST");
  629.         int32_t sec = 0, min = 0, hr = 0, day = 1, month = 10, year = 1997;
  630.                             
  631.         Calendar *cal1 = new GregorianCalendar(*PST,status);
  632.         cal1->setTime(880698639000.0,status);
  633.         // Issue 1: Changing the timezone doesn't change the
  634.         //          represented time.  The old API, pre 1.2.2a requires 
  635.         // setTime to be called in order to update the time fields after the time
  636.         // zone has been set.
  637.         int32_t h1,h2;
  638.         logln(UnicodeString("PST 1 is: ") + (h1=cal1->get(Calendar::HOUR_OF_DAY, status)));
  639.         cal1->setTimeZone(*GMT);
  640.         logln(UnicodeString("GMT 2 is: ") + (h2=cal1->get(Calendar::HOUR_OF_DAY, status)));
  641.         if ((*GMT != *PST) && (h1 == h2))
  642.             errln("Fail: Hour same in different zones");
  643.  
  644.         Calendar *cal2 = new GregorianCalendar(*GMT,status);
  645.         Calendar *cal3 = new GregorianCalendar(*PST,status);
  646.  
  647.         cal2->set(cal1->get(Calendar::YEAR,status),
  648.                  cal1->get(Calendar::MONTH,status),
  649.                  cal1->get(Calendar::DAY_OF_MONTH,status),
  650.                  cal1->get(Calendar::HOUR_OF_DAY,status),
  651.                  cal1->get(Calendar::MINUTE,status),
  652.                  cal1->get(Calendar::SECOND,status));
  653.  
  654.         double t1,t2,t3,t4;
  655.         logln(UnicodeString("RGMT 1 is: ") + (t1=cal2->getTime(status)));
  656.         cal3->set(year, month, day, hr, min, sec);
  657.         logln(UnicodeString("RPST 1 is: ") + (t2=cal3->getTime(status)));
  658.         cal3->setTimeZone(*GMT);
  659.         logln(UnicodeString("RGMT 2 is: ") + (t3=cal3->getTime(status)));
  660.         cal3->set(cal1->get(Calendar::YEAR,status),
  661.                  cal1->get(Calendar::MONTH,status),
  662.                  cal1->get(Calendar::DAY_OF_MONTH,status),
  663.                  cal1->get(Calendar::HOUR_OF_DAY,status),
  664.                  cal1->get(Calendar::MINUTE,status),
  665.                  cal1->get(Calendar::SECOND,status));
  666.         // Issue 2: Calendar continues to use the timezone in its
  667.         //          constructor for set() conversions, regardless
  668.         //          of calls to setTimeZone()
  669.         logln(UnicodeString("RGMT 3 is: ") + (t4=cal3->getTime(status)));
  670.         if (t1 == t2 ||
  671.             t1 != t4 ||
  672.             t2 != t3)
  673.             errln("Fail: Calendar zone behavior faulty");
  674.     
  675.         delete cal1;
  676.         delete cal2;
  677.         delete cal3;
  678.         delete GMT;
  679.         delete PST;
  680.     }
  681.  
  682.     /**
  683.      * @bug 4096539
  684.      */
  685.     void CalendarRegressionTest::test4096539() 
  686.     {
  687.         UErrorCode status = U_ZERO_ERROR;
  688.         int32_t y [] = {31,28,31,30,31,30,31,31,30,31,30,31};
  689.  
  690.         for (int32_t x=0;x<12;x++) {
  691.             GregorianCalendar *gc = new 
  692.                 GregorianCalendar(1997,x,y[x], status);
  693.             int32_t m1,m2;
  694.             log(UnicodeString("") + (m1=gc->get(Calendar::MONTH,status)+1)+UnicodeString("/")+
  695.                              gc->get(Calendar::DATE,status)+"/"+gc->get(Calendar::YEAR,status)+
  696.                              " + 1mo = ");
  697.  
  698.             gc->add(Calendar::MONTH, 1,status);
  699.             logln(UnicodeString("") + (m2=gc->get(Calendar::MONTH,status)+1)+UnicodeString("/")+
  700.                                gc->get(Calendar::DATE,status)+"/"+gc->get(Calendar::YEAR,status)
  701.                                );
  702.             int32_t m = (m1 % 12) + 1;
  703.             if (m2 != m)
  704.                 errln(UnicodeString("Fail: Want ") + m + " Got " + m2);
  705.             delete gc;
  706.         }
  707.         
  708.     }
  709.  
  710.     /**
  711.      * @bug 4100311
  712.      */
  713.     void CalendarRegressionTest::test41003112() 
  714.     {
  715.         UErrorCode status = U_ZERO_ERROR;
  716.         GregorianCalendar *cal = (GregorianCalendar*)Calendar::createInstance(status);
  717.         cal->set(Calendar::YEAR, 1997);
  718.         cal->set(Calendar::DAY_OF_YEAR, 1);
  719.         UDate d = cal->getTime(status);             // Should be Jan 1
  720.         //logln(d.toString());
  721.         if (cal->get(Calendar::DAY_OF_YEAR, status) != 1)
  722.             errln("Fail: DAY_OF_YEAR not set");
  723.         delete cal;
  724.     }
  725.  
  726.     /**
  727.      * @bug 4103271
  728.      */
  729.     void CalendarRegressionTest::test4103271() 
  730.     {
  731.         UErrorCode status = U_ZERO_ERROR;
  732.         SimpleDateFormat *sdf = new SimpleDateFormat(status); 
  733.         int32_t numYears=40, startYear=1997, numDays=15; 
  734.         UnicodeString output, testDesc; 
  735.         GregorianCalendar *testCal = (GregorianCalendar*)Calendar::createInstance(status); 
  736.         testCal->clear();
  737.         sdf->adoptCalendar(testCal); 
  738.         sdf->applyPattern("d MMM yyyy"); 
  739.         bool_t fail = FALSE;
  740.         for (int32_t firstDay=1; firstDay<=2; firstDay++) { 
  741.             for (int32_t minDays=1; minDays<=7; minDays++) { 
  742.                 testCal->setMinimalDaysInFirstWeek((uint8_t)minDays); 
  743.                 testCal->setFirstDayOfWeek((Calendar::EDaysOfWeek)firstDay); 
  744.                 testDesc = (UnicodeString("Test") + firstDay + minDays); 
  745.                 logln(testDesc + " => 1st day of week=" +
  746.                                    firstDay +
  747.                                    ", minimum days in first week=" +
  748.                                    minDays); 
  749.                 for (int32_t j=startYear; j<=startYear+numYears; j++) { 
  750.                     testCal->set(j,11,25); 
  751.                     for(int32_t i=0; i<numDays; i++) { 
  752.                         testCal->add(Calendar::DATE,1,status); 
  753.                         UnicodeString calWOY; 
  754.                         int32_t actWOY = testCal->get(Calendar::WEEK_OF_YEAR,status);
  755.                         if (actWOY < 1 || actWOY > 53) {
  756.                             UDate d = testCal->getTime(status); 
  757.                             //calWOY = String.valueOf(actWOY);
  758.                             UnicodeString temp;
  759.                             FieldPosition pos(FieldPosition::DONT_CARE);
  760.                             output = testDesc + " - " + sdf->format(d,temp,pos) + "\t"; 
  761.                             output = output + "\t" + actWOY; 
  762.                             logln(output); 
  763.                             fail = TRUE;
  764.                         }
  765.                     } 
  766.                 } 
  767.             } 
  768.         } 
  769.  
  770.         int32_t DATA [] = {
  771.             3, 52, 52, 52, 52, 52, 52, 52,
  772.                 1,  1,  1,  1,  1,  1,  1,
  773.                 2,  2,  2,  2,  2,  2,  2,
  774.             4, 52, 52, 52, 52, 52, 52, 52,
  775.                53, 53, 53, 53, 53, 53, 53,
  776.                 1,  1,  1,  1,  1,  1,  1,
  777.         };
  778.         testCal->setFirstDayOfWeek(Calendar::SUNDAY);
  779.         for (int32_t j=0; j<44; j+=22) {
  780.             logln(UnicodeString("Minimal days in first week = ") + DATA[j] +
  781.                                "  Week starts on Sunday");
  782.             testCal->setMinimalDaysInFirstWeek((uint8_t)DATA[j]);
  783.             testCal->set(1997, Calendar::DECEMBER, 21);
  784.             for (int32_t i=0; i<21; ++i) {
  785.                 int32_t woy = testCal->get(Calendar::WEEK_OF_YEAR,status);
  786.                 log(UnicodeString("") + testCal->getTime(status) + UnicodeString(" ") + woy);
  787.                 if (woy != DATA[j + 1 + i]) {
  788.                     log(" ERROR");
  789.                     fail = TRUE;
  790.                 }
  791.                 logln("");
  792.                 
  793.                 // Now compute the time from the fields, and make sure we
  794.                 // get the same answer back.  This is a round-trip test.
  795.                 UDate save = testCal->getTime(status);
  796.                 testCal->clear();
  797.                 testCal->set(Calendar::YEAR, DATA[j+1+i] < 25 ? 1998 : 1997);
  798.                 testCal->set(Calendar::WEEK_OF_YEAR, DATA[j+1+i]);
  799.                 testCal->set(Calendar::DAY_OF_WEEK, (i%7) + Calendar::SUNDAY);
  800.                 if (testCal->getTime(status) != save) {
  801.                     logln(UnicodeString("  Parse failed: ") + testCal->getTime(status));
  802.                     fail= TRUE;
  803.                 }
  804.  
  805.                 testCal->setTime(save,status);
  806.                 testCal->add(Calendar::DAY_OF_MONTH, 1,status);
  807.             }
  808.         }
  809.  
  810.         // Test field disambiguation with a few special hard-coded cases.
  811.         // This shouldn't fail if the above cases aren't failing.
  812.         int32_t DISAM_int [] = {
  813.             1998, 1, Calendar::SUNDAY,
  814.             (1998), (2), (Calendar::SATURDAY),
  815.             (1998), (53), (Calendar::THURSDAY),
  816.             (1998), (53), (Calendar::FRIDAY)
  817.         };
  818.  
  819.         UDate DISAM_date [] = {
  820.                 makeDate(1997, Calendar::DECEMBER, 28),
  821.                 makeDate(1998, Calendar::JANUARY, 10),
  822.                 makeDate(1998, Calendar::DECEMBER, 31),
  823.                 makeDate(1999, Calendar::JANUARY, 1)
  824.         };
  825.         
  826.         testCal->setMinimalDaysInFirstWeek(3);
  827.         testCal->setFirstDayOfWeek(Calendar::SUNDAY);
  828.         int32_t i = 0;
  829.         for (i=0; i < 12; i += 3) {
  830.             int32_t y = DISAM_int[i];
  831.             int32_t woy = DISAM_int[i+1];
  832.             int32_t dow = DISAM_int[i+2];
  833.             UDate exp = DISAM_date[i/3];
  834.             testCal->clear();
  835.             testCal->set(Calendar::YEAR, y);
  836.             testCal->set(Calendar::WEEK_OF_YEAR, woy);
  837.             testCal->set(Calendar::DAY_OF_WEEK, dow);
  838.             UDate got = testCal->getTime(status);
  839.             log(UnicodeString("") + y + "-W" + woy +
  840.                              "-DOW" + dow + " expect:" + exp +
  841.                              " got:" + got);
  842.             if (got != exp) {
  843.                 log("  FAIL");
  844.                 fail = TRUE;
  845.             }
  846.             logln("");
  847.         }
  848.  
  849.         // Now try adding and rolling
  850.         UDate ADDROLL_date [] = {
  851.             makeDate(1998, Calendar::DECEMBER, 25), makeDate(1999, Calendar::JANUARY, 1),
  852.             makeDate(1997, Calendar::DECEMBER, 28), makeDate(1998, Calendar::JANUARY, 4),
  853.             makeDate(1998, Calendar::DECEMBER, 27), makeDate(1997, Calendar::DECEMBER, 28),
  854.             makeDate(1999, Calendar::JANUARY, 2), makeDate(1998, Calendar::JANUARY, 3),
  855.         };
  856.  
  857.         int32_t ADDROLL_int []= {
  858.             (1),
  859.             (1),
  860.             (1),
  861.             (1)
  862.         };
  863.  
  864.  
  865.         bool_t ADDROLL_bool [] = {
  866.             TRUE,//ADD,
  867.             TRUE,
  868.             FALSE,
  869.             FALSE
  870.         };
  871.  
  872.         testCal->setMinimalDaysInFirstWeek(3);
  873.         testCal->setFirstDayOfWeek(Calendar::SUNDAY);
  874.         for (i=0; i<8; i += 2) {
  875.             int32_t amount = ADDROLL_int[i/2];
  876.             UDate before = ADDROLL_date[i];
  877.             UDate after = ADDROLL_date[i+1];
  878.  
  879.             testCal->setTime(before,status);
  880.             if (ADDROLL_bool[i/2]) 
  881.                 testCal->add(Calendar::WEEK_OF_YEAR, amount,status);
  882.             else 
  883.                 testCal->roll(Calendar::WEEK_OF_YEAR, amount,status);
  884.             UDate got = testCal->getTime(status);
  885.             log((ADDROLL_bool[i]? UnicodeString("add(WOY,"):UnicodeString("roll(WOY,")) +
  886.                              amount + ") " + before + " => " +
  887.                              got);
  888.             if (after != got) {
  889.                 logln(UnicodeString("  exp:") + after + "  FAIL");
  890.                 fail = TRUE;
  891.             }
  892.             else logln(" ok");
  893.  
  894.             testCal->setTime(after,status);
  895.             if (ADDROLL_bool[i/2]) 
  896.                 testCal->add(Calendar::WEEK_OF_YEAR, -amount,status);
  897.             else 
  898.                 testCal->roll(Calendar::WEEK_OF_YEAR, -amount,status);
  899.             got = testCal->getTime(status);
  900.             log((ADDROLL_bool[i]?UnicodeString("add(WOY,"):UnicodeString("roll(WOY,")) +
  901.                              (-amount) + ") " + after + " => " +
  902.                              got);
  903.             if (before != got) {
  904.                 logln(UnicodeString("  exp:") + before + "  FAIL");
  905.                 fail = TRUE;
  906.             }
  907.             else logln(" ok");
  908.         }
  909.  
  910.         if (fail) 
  911.             errln("Fail: Week of year misbehaving");
  912.  
  913.     delete sdf;
  914.     } 
  915.  
  916.     /**
  917.      * @bug 4106136
  918.      */
  919.     void CalendarRegressionTest::test4106136() 
  920.     {
  921.         UErrorCode status = U_ZERO_ERROR;
  922.         Locale saveLocale = Locale::getDefault();
  923.         //try {
  924.         Locale locales [] = { Locale::CHINESE, Locale::CHINA };
  925.             for (int32_t i=0; i<2; ++i) {
  926.                 Locale::setDefault(locales[i], status);
  927.                 failure(status, "Locale::setDefault");
  928.                 int32_t count1, count2, count3;
  929.                 Calendar::getAvailableLocales(count1);
  930.                 DateFormat::getAvailableLocales(count2);
  931.                 NumberFormat::getAvailableLocales(count3);
  932.                 int32_t n [] = {
  933.                     count1, count2, count3
  934.                 };
  935.                 for (int32_t j=0; j<3; ++j) {
  936.                     UnicodeString temp;
  937.                     if (n[j] == 0)
  938.                         errln(UnicodeString("Fail: No locales for ") + locales[i].getName(temp));
  939.                 }
  940.             }
  941.         //}
  942.         //finally {
  943.             Locale::setDefault(saveLocale,status);
  944.         //}
  945.     }
  946.  
  947.     /**
  948.      * @bug 4108764
  949.      */
  950.     void CalendarRegressionTest::test4108764() 
  951.     {
  952.         UErrorCode status = U_ZERO_ERROR;
  953.         UDate d00 = makeDate(1997, Calendar::MARCH, 15, 12, 00, 00);
  954.         UDate d01 = makeDate(1997, Calendar::MARCH, 15, 12, 00, 56);
  955.         UDate d10 = makeDate(1997, Calendar::MARCH, 15, 12, 34, 00);
  956.         UDate d11 = makeDate(1997, Calendar::MARCH, 15, 12, 34, 56);
  957.         UDate epoch = makeDate(1970, Calendar::JANUARY, 1);
  958.  
  959.         Calendar *cal = Calendar::createInstance(status); 
  960.         cal->setTime(d11,status);
  961.  
  962.         cal->clear( Calendar::MINUTE ); 
  963.         logln(UnicodeString("") + cal->getTime(status)); 
  964.         if (cal->getTime(status)  != d01)
  965.             errln("Fail: clear(MINUTE) broken");
  966.  
  967.         cal->set( Calendar::SECOND, 0 ); 
  968.         logln(UnicodeString("") + cal->getTime(status)); 
  969.         if (cal->getTime(status)  != d00)
  970.             errln("Fail: set(SECOND, 0) broken");
  971.  
  972.         cal->setTime(d11,status);
  973.         cal->set( Calendar::SECOND, 0 ); 
  974.         logln(UnicodeString("") + cal->getTime(status)); 
  975.         if (cal->getTime(status)  != d10)
  976.             errln("Fail: set(SECOND, 0) broken #2");
  977.  
  978.         cal->clear( Calendar::MINUTE ); 
  979.         logln(UnicodeString("") + cal->getTime(status)); 
  980.         if (cal->getTime(status)  != d00)
  981.             errln("Fail: clear(MINUTE) broken #2");
  982.  
  983.         cal->clear();
  984.         logln(UnicodeString("") + cal->getTime(status)); 
  985.         if (cal->getTime(status)  != epoch)
  986.             errln(UnicodeString("Fail: clear() broken Want ") + epoch);
  987.     
  988.         delete cal;
  989.     }
  990.  
  991.     /**
  992.      * @bug 4114578
  993.      */
  994.     void CalendarRegressionTest::test4114578() 
  995.     {
  996.         UErrorCode status = U_ZERO_ERROR;
  997.         int32_t ONE_HOUR = 60*60*1000;
  998.         Calendar *cal = Calendar::createInstance(status);
  999.         cal->adoptTimeZone(TimeZone::createTimeZone("PST"));
  1000.         UDate onset = makeDate(1998, Calendar::APRIL, 5, 1, 0) + ONE_HOUR;
  1001.         UDate cease = makeDate(1998, Calendar::OCTOBER, 25, 0, 0) + 2*ONE_HOUR;
  1002.  
  1003.         bool_t fail = FALSE;
  1004.         
  1005.         const int32_t ADD = 1;
  1006.         const int32_t ROLL = 2;
  1007.  
  1008.         double DATA []= {
  1009.             // Start            Action   Amt    Expected_change
  1010.             onset - ONE_HOUR,   ADD,      1,     ONE_HOUR,
  1011.             onset,              ADD,     -1,    -ONE_HOUR,
  1012.             onset - ONE_HOUR,   ROLL,     1,     ONE_HOUR,
  1013.             onset,              ROLL,    -1,    -ONE_HOUR,
  1014.             cease - ONE_HOUR,   ADD,      1,     ONE_HOUR,
  1015.             cease,              ADD,     -1,    -ONE_HOUR,
  1016.             cease - ONE_HOUR,   ROLL,     1,     ONE_HOUR,
  1017.             cease,              ROLL,    -1,    -ONE_HOUR,
  1018.         };
  1019.  
  1020.         for (int32_t i=0; i<32; i+=4) {
  1021.             UDate date = DATA[i];
  1022.             int32_t amt = (int32_t) DATA[i+2];
  1023.             double expectedChange = DATA[i+3];
  1024.             
  1025.             log(UnicodeString("") + date);
  1026.             cal->setTime(date,status);
  1027.  
  1028.             switch ((int32_t) DATA[i+1]) {
  1029.             case ADD:
  1030.                 log(UnicodeString(" add (HOUR,") + (amt<0?"":"+")+amt + ")= ");
  1031.                 cal->add(Calendar::HOUR, amt,status);
  1032.                 break;
  1033.             case ROLL:
  1034.                 log(UnicodeString(" roll(HOUR,") + (amt<0?"":"+")+amt + ")= ");
  1035.                 cal->roll(Calendar::HOUR, amt,status);
  1036.                 break;
  1037.             }
  1038.  
  1039.             log(UnicodeString("") + cal->getTime(status));
  1040.  
  1041.             double change = cal->getTime(status) - date;
  1042.             if (change != expectedChange) {
  1043.                 fail = TRUE;
  1044.                 logln(" FAIL");
  1045.             }
  1046.             else logln(" OK");
  1047.         }
  1048.  
  1049.         if (fail) errln("Fail: roll/add misbehaves around DST onset/cease");
  1050.     
  1051.         delete cal;
  1052.     }
  1053.  
  1054.     /**
  1055.      * @bug 4118384
  1056.      * Make sure maximum for HOUR field is 11, not 12.
  1057.      */
  1058.     void CalendarRegressionTest::test4118384() 
  1059.     {
  1060.         UErrorCode status = U_ZERO_ERROR;
  1061.         Calendar *cal = Calendar::createInstance(status);
  1062.         if (cal->getMaximum(Calendar::HOUR) != 11 ||
  1063.             cal->getLeastMaximum(Calendar::HOUR) != 11 ||
  1064.             cal->getActualMaximum(Calendar::HOUR,status) != 11)
  1065.             errln("Fail: maximum of HOUR field should be 11");
  1066.     
  1067.         delete cal;
  1068.     }
  1069.  
  1070.     /**
  1071.      * @bug 4125881
  1072.      * Check isLeapYear for BC years.
  1073.      */
  1074.     void CalendarRegressionTest::test4125881() 
  1075.     {
  1076.         UErrorCode status = U_ZERO_ERROR;
  1077.         GregorianCalendar *cal = (GregorianCalendar*) Calendar::createInstance(status);
  1078.         DateFormat *fmt = new SimpleDateFormat("MMMM d, yyyy G",status);
  1079.         cal->clear();
  1080.         for (int32_t y=-20; y<=10; ++y) {
  1081.             cal->set(Calendar::ERA, y < 1 ? GregorianCalendar::BC : GregorianCalendar::AD);
  1082.             cal->set(Calendar::YEAR, y < 1 ? 1 - y : y);
  1083.             UnicodeString temp;
  1084.             logln(UnicodeString("") + y + UnicodeString(" = ") + fmt->format(cal->getTime(status), temp) + " " +
  1085.                                cal->isLeapYear(y));
  1086.             if (cal->isLeapYear(y) != ((y+40)%4 == 0))
  1087.                 errln("Leap years broken");
  1088.         }
  1089.     
  1090.         delete cal;
  1091.         delete fmt;
  1092.     }
  1093.  
  1094.     /**
  1095.      * @bug 4125892
  1096.      * Prove that GregorianCalendar is proleptic (it used to cut off
  1097.      * at 45 BC, and not have leap years before then).
  1098.      */
  1099.     void CalendarRegressionTest::test4125892() {
  1100.         UErrorCode status = U_ZERO_ERROR;
  1101.         GregorianCalendar *cal = (GregorianCalendar*) Calendar::createInstance(status);
  1102.         DateFormat *fmt = new SimpleDateFormat("MMMM d, yyyy G",status);
  1103.         cal->clear();
  1104.         cal->set(Calendar::ERA, GregorianCalendar::BC);
  1105.         cal->set(Calendar::YEAR, 81); // 81 BC is a leap year (proleptically)
  1106.         cal->set(Calendar::MONTH, Calendar::FEBRUARY);
  1107.         cal->set(Calendar::DATE, 28);
  1108.         cal->add(Calendar::DATE, 1,status);
  1109.         if(U_FAILURE(status))
  1110.             errln("add(DATE,1) failed");
  1111.         if (cal->get(Calendar::DATE,status) != 29 ||
  1112.             !cal->isLeapYear(-80)) // -80 == 81 BC
  1113.             errln("Calendar not proleptic");
  1114.     
  1115.         delete cal;
  1116.     }
  1117.  
  1118.     /**
  1119.      * @bug 4141665
  1120.      * GregorianCalendar::equals() ignores cutover date
  1121.      */
  1122.     void CalendarRegressionTest::test4141665() 
  1123.     {
  1124.         UErrorCode status = U_ZERO_ERROR;
  1125.         GregorianCalendar *cal = new GregorianCalendar(status);
  1126.         GregorianCalendar *cal2 = (GregorianCalendar*)cal->clone();
  1127.         UDate cut = cal->getGregorianChange();
  1128.         UDate cut2 = cut + 100*24*60*60*1000.0; // 100 days later
  1129.         if (*cal != *cal2) {
  1130.             errln("Cloned GregorianCalendars not equal");
  1131.         }
  1132.         cal2->setGregorianChange(cut2,status);
  1133.         if ( *cal == *cal2) {
  1134.             errln("GregorianCalendar::equals() ignores cutover");
  1135.         }
  1136.     
  1137.         delete cal;
  1138.         delete cal2;
  1139.     }
  1140.     
  1141.     /**
  1142.      * @bug 4142933
  1143.      * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar::roll()
  1144.      * when IllegalArgumentException should be.
  1145.      */
  1146.     void CalendarRegressionTest::test4142933() 
  1147.     {
  1148.         UErrorCode status = U_ZERO_ERROR;
  1149.         GregorianCalendar *calendar = new GregorianCalendar(status);
  1150.         //try {
  1151.         calendar->roll((Calendar::EDateFields)-1, TRUE, status);
  1152.             if(U_SUCCESS(status))
  1153.                 errln("Test failed, no exception thrown");
  1154.         //}
  1155.         //catch (IllegalArgumentException e) {
  1156.             // OK: Do nothing
  1157.             // logln("Test passed");
  1158.         //}
  1159.         //catch (Exception e) {
  1160.             //errln("Test failed. Unexpected exception is thrown: " + e);
  1161.             //e.printStackTrace();
  1162.         //} 
  1163.     
  1164.         delete calendar;
  1165.     }
  1166.  
  1167.     /**
  1168.      * @bug 4145158
  1169.      * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is
  1170.      * confusing; unless the time zone has a raw offset of zero, one or the
  1171.      * other of these will wrap.  We've modified the test given in the bug
  1172.      * report to therefore only check the behavior of a calendar with a zero raw
  1173.      * offset zone.
  1174.      */
  1175.     void CalendarRegressionTest::test4145158() 
  1176.     {
  1177.         UErrorCode status = U_ZERO_ERROR;
  1178.         GregorianCalendar *calendar = new GregorianCalendar(status);
  1179.  
  1180.         calendar->adoptTimeZone(TimeZone::createTimeZone("GMT"));
  1181.  
  1182.         calendar->setTime(makeDate(LONG_MIN),status);
  1183.         int32_t year1 = calendar->get(Calendar::YEAR,status);
  1184.         int32_t era1 = calendar->get(Calendar::ERA,status);
  1185.         
  1186.         calendar->setTime(makeDate(LONG_MAX),status);
  1187.         int32_t year2 = calendar->get(Calendar::YEAR,status);
  1188.         int32_t era2 = calendar->get(Calendar::ERA,status);
  1189.         
  1190.         if (year1 == year2 && era1 == era2) {
  1191.             errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");
  1192.         }
  1193.     
  1194.         delete calendar;
  1195.     }
  1196.  
  1197.     /**
  1198.      * @bug 4145983
  1199.      * Maximum value for YEAR field wrong.
  1200.      */
  1201.     // {sfb} this is not directly applicable in C++, since all
  1202.     // possible doubles are not representable by our Calendar.
  1203.     // In Java, all longs are representable.  
  1204.     // We can determine limits programmatically
  1205.     // Using DBL_MAX is a bit of a hack, since for large doubles
  1206.     // Calendar gets squirrely and doesn't behave in any sort
  1207.     // of linear fashion (ie years jump around, up/down, etc) for a
  1208.     // small change in millis.
  1209.     void CalendarRegressionTest::test4145983() 
  1210.     {
  1211.         UErrorCode status = U_ZERO_ERROR;
  1212.         GregorianCalendar *calendar = new GregorianCalendar(status);
  1213.         calendar->adoptTimeZone(TimeZone::createTimeZone("GMT"));
  1214.         UDate DATES [] = { LATEST_SUPPORTED_MILLIS, EARLIEST_SUPPORTED_MILLIS };
  1215.         for (int32_t i=0; i<2; ++i) {
  1216.             calendar->setTime(DATES[i], status);
  1217.             int32_t year = calendar->get(Calendar::YEAR,status);
  1218.             int32_t maxYear = calendar->getMaximum(Calendar::YEAR);
  1219.             if (year > maxYear) {
  1220.                 errln(UnicodeString("Failed for ")+DATES[i]+" ms: year=" +
  1221.                       year + ", maxYear=" + maxYear);
  1222.             }
  1223.         }
  1224.     
  1225.         delete calendar;
  1226.     }
  1227.  
  1228.     /**
  1229.      * @bug 4147269
  1230.      * This is a bug in the validation code of GregorianCalendar::  As reported,
  1231.      * the bug seems worse than it really is, due to a bug in the way the bug
  1232.      * report test was written.  In reality the bug is restricted to the DAY_OF_YEAR
  1233.      * field. - liu 6/29/98
  1234.      */
  1235.     void CalendarRegressionTest::test4147269() 
  1236.     {
  1237.         const char* fieldName [] = {
  1238.             "ERA", 
  1239.             "YEAR", 
  1240.             "MONTH", 
  1241.             "WEEK_OF_YEAR", 
  1242.             "WEEK_OF_MONTH", 
  1243.             "DAY_OF_MONTH", 
  1244.             "DAY_OF_YEAR", 
  1245.             "DAY_OF_WEEK", 
  1246.             "DAY_OF_WEEK_IN_MONTH", 
  1247.             "AM_PM", 
  1248.             "HOUR", 
  1249.             "HOUR_OF_DAY", 
  1250.             "MINUTE", 
  1251.             "SECOND", 
  1252.             "MILLISECOND", 
  1253.             "ZONE_OFFSET", 
  1254.             "DST_OFFSET"
  1255.         };
  1256.         UErrorCode status = U_ZERO_ERROR;
  1257.         GregorianCalendar *calendar = new GregorianCalendar(status);
  1258.         calendar->setLenient(FALSE);
  1259.         UDate date = makeDate(1996, Calendar::JANUARY, 3); // Arbitrary date
  1260.         for (int32_t field = 0; field < Calendar::FIELD_COUNT; field++) {
  1261.             calendar->setTime(date,status);
  1262.             // Note: In the bug report, getActualMaximum() was called instead
  1263.             // of getMaximum() -- this was an error.  The validation code doesn't
  1264.             // use getActualMaximum(), since that's too costly.
  1265.             int32_t max = calendar->getMaximum((Calendar::EDateFields)field);
  1266.             int32_t value = max+1;
  1267.             calendar->set((Calendar::EDateFields)field, value); 
  1268.             //try {
  1269.                 calendar->getTime(status); // Force time computation
  1270.                 // We expect an exception to be thrown. If we fall through
  1271.                 // to the next line, then we have a bug.
  1272.                 if(U_SUCCESS(status))
  1273.                 errln(UnicodeString("Test failed with field ") + fieldName[field] +
  1274.                       ", date before: " + date +
  1275.                       ", date after: " + calendar->getTime(status) +
  1276.                       ", value: " + value + " (max = " + max +")");
  1277.             //} catch (IllegalArgumentException e) {} 
  1278.         }
  1279.     
  1280.         delete calendar;
  1281.     }
  1282.  
  1283. /**
  1284.  * @bug 4149677
  1285.  * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)
  1286.  * doesn't behave as a pure Julian calendar.
  1287.  * CANNOT REPRODUCE THIS BUG
  1288.  */
  1289. void 
  1290. CalendarRegressionTest::Test4149677() 
  1291. {
  1292.     UErrorCode status = U_ZERO_ERROR;
  1293.  
  1294.     TimeZone *zones [] = { 
  1295.         TimeZone::createTimeZone("GMT"),
  1296.         TimeZone::createTimeZone("PST"),
  1297.         TimeZone::createTimeZone("EAT") 
  1298.     };
  1299.     if(U_FAILURE(status)) {
  1300.         errln("Couldn't create zones");
  1301.         return;
  1302.         // could leak memory
  1303.     }
  1304.  
  1305.     for (int32_t i=0; i < 3; ++i) {
  1306.         GregorianCalendar *calendar = new GregorianCalendar(zones[i], status);
  1307.         if(U_FAILURE(status)) {
  1308.             errln("Couldnt' create calendar.");
  1309.             return;
  1310.         }
  1311.  
  1312.         // Make sure extreme values don't wrap around
  1313.         calendar->setTime(EARLIEST_SUPPORTED_MILLIS, status);
  1314.         if(U_FAILURE(status))
  1315.             errln("setTime failed");
  1316.         if (calendar->get(Calendar::ERA, status) != GregorianCalendar::BC || U_FAILURE(status)) {
  1317.             errln("Fail: Date(EARLIEST_SUPPORTED_MILLIS) has an AD year");
  1318.         }
  1319.         calendar->setTime(LATEST_SUPPORTED_MILLIS, status);
  1320.         if(U_FAILURE(status))
  1321.             errln("setTime failed");
  1322.         if (calendar->get(Calendar::ERA, status) != GregorianCalendar::AD || U_FAILURE(status)) {
  1323.             errln("Fail: Date(LATEST_SUPPORTED_MILLIS) has a BC year");
  1324.         }
  1325.  
  1326.         calendar->setGregorianChange(LATEST_SUPPORTED_MILLIS, status);
  1327.         if(U_FAILURE(status))
  1328.             errln("setGregorianChange failed");
  1329.         // to obtain a pure Julian calendar
  1330.         
  1331.         bool_t is100Leap = calendar->isLeapYear(100);
  1332.         if (!is100Leap) {
  1333.             UnicodeString temp;
  1334.             errln("test failed with zone " + zones[i]->getID(temp));
  1335.             errln(" cutover date is Date(Long.MAX_VALUE)");
  1336.             errln(" isLeapYear(100) returns: " + is100Leap);
  1337.         }
  1338.         delete calendar;
  1339.     }
  1340.     
  1341.     // no need for cleanup- zones were adopted
  1342. }
  1343.  
  1344. /**
  1345.  * @bug 4162587
  1346.  * Calendar and Date HOUR broken.  If HOUR is out-of-range, Calendar
  1347.  * and Date classes will misbehave.
  1348.  */
  1349. void 
  1350. CalendarRegressionTest::Test4162587() 
  1351. {
  1352.     UErrorCode status = U_ZERO_ERROR;
  1353.     TimeZone *tz = TimeZone::createTimeZone("PST");
  1354.     TimeZone::adoptDefault(tz);
  1355.     
  1356.     GregorianCalendar *cal = new GregorianCalendar(tz, status);
  1357.     if(U_FAILURE(status)) {
  1358.         errln("Couldn't create calendar");
  1359.         return;
  1360.     }
  1361.     UDate d0, dPlus, dMinus;
  1362.     
  1363.     for(int32_t i=0; i<5; ++i) {
  1364.         if (i>0) logln("---");
  1365.  
  1366.         cal->clear();
  1367.         cal->set(1998, Calendar::APRIL, 5, i, 0);
  1368.         d0 = cal->getTime(status);
  1369.         if(U_FAILURE(status))
  1370.             errln("Coudln't get time (1)");
  1371.         //String s0 = d.toString();
  1372.         logln(UnicodeString("0 ") + i + ": " + d0/*s0*/);
  1373.  
  1374.         cal->clear();
  1375.         cal->set(1998, Calendar::APRIL, 4, i+24, 0);
  1376.         dPlus = cal->getTime(status);
  1377.         if(U_FAILURE(status))
  1378.             errln("Coudln't get time (2)");
  1379.         //String sPlus = d.toString();
  1380.         logln(UnicodeString("+ ") + i + ": " + dPlus/*sPlus*/);
  1381.  
  1382.         cal->clear();
  1383.         cal->set(1998, Calendar::APRIL, 6, i-24, 0);
  1384.         dMinus = cal->getTime(status);
  1385.         if(U_FAILURE(status))
  1386.             errln("Coudln't get time (3)");
  1387.         //String sMinus = d.toString();
  1388.         logln(UnicodeString("- ") + i + ": " + dMinus/*sMinus*/);
  1389.  
  1390.         if (d0 != dPlus || d0 != dMinus) {
  1391.             errln("Fail: All three lines must match");
  1392.         }
  1393.     }
  1394. }
  1395.  
  1396. /**
  1397.  * @bug 4165343
  1398.  * Adding 12 months behaves differently from adding 1 year
  1399.  */
  1400. void 
  1401. CalendarRegressionTest::Test4165343() 
  1402. {
  1403.     UErrorCode status = U_ZERO_ERROR;
  1404.     GregorianCalendar *calendar = new GregorianCalendar(1996, Calendar::FEBRUARY, 29, status);
  1405.     if(U_FAILURE(status)) {
  1406.         errln("Couldn't create calendar");
  1407.         return;
  1408.     }
  1409.     UDate start = calendar->getTime(status);
  1410.     if(U_FAILURE(status))
  1411.         errln("Couldn't getTime (1)");
  1412.     logln(UnicodeString("init date: ") + start);
  1413.     calendar->add(Calendar::MONTH, 12, status); 
  1414.     if(U_FAILURE(status))
  1415.         errln("Couldn't add(MONTH, 12)");
  1416.     UDate date1 = calendar->getTime(status);
  1417.     if(U_FAILURE(status))
  1418.         errln("Couldn't getTime (2)");
  1419.     logln(UnicodeString("after adding 12 months: ") + date1);
  1420.     calendar->setTime(start, status);
  1421.     if(U_FAILURE(status))
  1422.         errln("Couldn't setTime");
  1423.     calendar->add(Calendar::YEAR, 1, status);
  1424.     if(U_FAILURE(status))
  1425.         errln("Couldn't add(YEAR, 1)");
  1426.     UDate date2 = calendar->getTime(status);
  1427.     if(U_FAILURE(status))
  1428.         errln("Couldn't getTime (3)");
  1429.     logln(UnicodeString("after adding one year : ") + date2);
  1430.     if (date1 == date2) {
  1431.         logln("Test passed");
  1432.     } else {
  1433.         errln("Test failed");
  1434.     }
  1435.     delete calendar;
  1436. }
  1437.  
  1438. /**
  1439.  * @bug 4166109
  1440.  * GregorianCalendar.getActualMaximum() does not account for first day of week.
  1441.  */
  1442. void 
  1443. CalendarRegressionTest::Test4166109() 
  1444. {
  1445.     /* Test month:
  1446.      *
  1447.      *      March 1998
  1448.      * Su Mo Tu We Th Fr Sa
  1449.      *  1  2  3  4  5  6  7
  1450.      *  8  9 10 11 12 13 14
  1451.      * 15 16 17 18 19 20 21
  1452.      * 22 23 24 25 26 27 28
  1453.      * 29 30 31
  1454.      */
  1455.     bool_t passed = TRUE;
  1456.     UErrorCode status = U_ZERO_ERROR;
  1457.     Calendar::EDateFields field = Calendar::WEEK_OF_MONTH;
  1458.  
  1459.     GregorianCalendar *calendar = new GregorianCalendar(Locale::US, status);
  1460.     if(U_FAILURE(status)) {
  1461.         errln("Couldn't create calendar");
  1462.         return;
  1463.     }
  1464.     calendar->set(1998, Calendar::MARCH, 1);
  1465.     calendar->setMinimalDaysInFirstWeek(1);
  1466.     logln(UnicodeString("Date:  ") + calendar->getTime(status));
  1467.  
  1468.     int32_t firstInMonth = calendar->get(Calendar::DAY_OF_MONTH, status);
  1469.     if(U_FAILURE(status))
  1470.         errln("get(D_O_M) failed");
  1471.  
  1472.     for(int32_t firstInWeek = Calendar::SUNDAY; firstInWeek <= Calendar::SATURDAY; firstInWeek++) {
  1473.         calendar->setFirstDayOfWeek((Calendar::EDaysOfWeek)firstInWeek);
  1474.         int32_t returned = calendar->getActualMaximum(field);
  1475.         int32_t expected = (31 + ((firstInMonth - firstInWeek + 7)% 7) + 6) / 7;
  1476.  
  1477.         logln(UnicodeString("First day of week = ") + firstInWeek +
  1478.               "  getActualMaximum(WEEK_OF_MONTH) = " + returned +
  1479.               "  expected = " + expected +
  1480.               ((returned == expected) ? "  ok" : "  FAIL"));
  1481.  
  1482.         if (returned != expected) {
  1483.             passed = FALSE;
  1484.         }
  1485.     }
  1486.     if (!passed) {
  1487.         errln("Test failed");
  1488.     }
  1489.  
  1490.     delete calendar;
  1491. }
  1492.  
  1493. /**
  1494.  * @bug 4167060
  1495.  * Calendar.getActualMaximum(YEAR) works wrong.
  1496.  */
  1497. void 
  1498. CalendarRegressionTest::Test4167060() 
  1499. {
  1500.     UErrorCode status = U_ZERO_ERROR;
  1501.     Calendar::EDateFields field = Calendar::YEAR;
  1502.     DateFormat *format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy G",
  1503.         Locale::US, status);
  1504.     if(U_FAILURE(status)) {
  1505.         errln("Couldn't create SimpleDateFormat");
  1506.         return;
  1507.     }
  1508.  
  1509.     GregorianCalendar *calendars [] = {
  1510.         new GregorianCalendar(100, Calendar::NOVEMBER, 1, status),
  1511.         new GregorianCalendar(-99 /*100BC*/, Calendar::JANUARY, 1, status),
  1512.         new GregorianCalendar(1996, Calendar::FEBRUARY, 29, status),
  1513.     };
  1514.     if(U_FAILURE(status)) {
  1515.         errln("Couldn't create GregorianCalendars");
  1516.         return;
  1517.         // could leak
  1518.     }
  1519.  
  1520.     UnicodeString id [] = { "Hybrid", "Gregorian", "Julian" };
  1521.  
  1522.     for (int32_t k=0; k<3; ++k) {
  1523.         logln("--- " + id[k] + " ---");
  1524.  
  1525.         for (int32_t j=0; j < 3; ++j) {
  1526.             GregorianCalendar *calendar = calendars[j];
  1527.             if (k == 1) {
  1528.                 calendar->setGregorianChange(EARLIEST_SUPPORTED_MILLIS, status);
  1529.             } 
  1530.             else if (k == 2) {
  1531.                 calendar->setGregorianChange(LATEST_SUPPORTED_MILLIS, status);
  1532.             }
  1533.  
  1534.             if(U_FAILURE(status))
  1535.                 errln("setGregorianChange() failed");
  1536.             format->adoptCalendar((Calendar*)calendar->clone());
  1537.  
  1538.             UDate dateBefore = calendar->getTime(status);
  1539.             if(U_FAILURE(status))
  1540.                 errln("getTime() failed");
  1541.  
  1542.             int32_t maxYear = calendar->getActualMaximum(field);
  1543.             UnicodeString temp;
  1544.             logln(UnicodeString("maxYear: ") + maxYear + " for " + format->format(calendar->getTime(status), temp));
  1545.             temp.remove();
  1546.             logln("date before: " + format->format(dateBefore, temp));
  1547.  
  1548.             int32_t years[] = {2000, maxYear-1, maxYear, maxYear+1};
  1549.  
  1550.             for (int32_t i = 0; i < 4; i++) {
  1551.                 bool_t valid = years[i] <= maxYear;
  1552.                 calendar->set(field, years[i]);
  1553.                 UDate dateAfter = calendar->getTime(status);
  1554.                 if(U_FAILURE(status))
  1555.                     errln("getTime() failed");
  1556.                 int32_t newYear = calendar->get(field, status);
  1557.                 if(U_FAILURE(status))
  1558.                     errln(UnicodeString("get(") + (int32_t)field + ") failed");
  1559.                 calendar->setTime(dateBefore, status); // restore calendar for next use
  1560.                 if(U_FAILURE(status))
  1561.                     errln("setTime() failed");
  1562.  
  1563.                 temp.remove();
  1564.                 logln(UnicodeString(" Year ") + years[i] + (valid? " ok " : " bad") +
  1565.                       " => " + format->format(dateAfter, temp));
  1566.                 if (valid && newYear != years[i]) {
  1567.                     errln(UnicodeString("  FAIL: ") + newYear + " should be valid; date, month and time shouldn't change");
  1568.                 } 
  1569.                 // {sfb} this next line is a hack, but it should work since if a
  1570.                 // double has an exponent, adding 1 should not yield the same double
  1571.                 else if (!valid && /*newYear == years[i]*/ dateAfter + 1.0 == dateAfter)  {
  1572.                     errln(UnicodeString("  FAIL: ") + newYear + " should be invalid");
  1573.                 }
  1574.             }
  1575.         }
  1576.     }
  1577.  
  1578.     delete format;
  1579.     delete calendars[0];
  1580.     delete calendars[1];
  1581.     delete calendars[2];
  1582. }
  1583.  
  1584. /**
  1585.  * Week of year is wrong at the start and end of the year.
  1586.  */
  1587. void CalendarRegressionTest::Test4197699() {
  1588.     UErrorCode status = U_ZERO_ERROR;
  1589.     GregorianCalendar cal(status);
  1590.     cal.setFirstDayOfWeek(Calendar::MONDAY);
  1591.     cal.setMinimalDaysInFirstWeek(4);
  1592.     SimpleDateFormat fmt("E dd MMM yyyy  'DOY='D 'WOY='w",
  1593.                          Locale::US, status);
  1594.     fmt.setCalendar(cal);
  1595.     if (U_FAILURE(status)) {
  1596.         errln("Couldn't initialize test");
  1597.         return;
  1598.     }
  1599.  
  1600.     int32_t DATA[] = {
  1601.         2000,  Calendar::JANUARY,   1,   52,
  1602.         2001,  Calendar::DECEMBER,  31,  1,
  1603.     };
  1604.     int32_t DATA_length = sizeof(DATA) / sizeof(DATA[0]);
  1605.  
  1606.     UnicodeString str;
  1607.     DateFormat& dfmt = *(DateFormat*)&fmt;
  1608.     for (int32_t i=0; i<DATA_length; ) {
  1609.         cal.clear();
  1610.         cal.set(DATA[i], DATA[i+1], DATA[i+2]);
  1611.         i += 3;
  1612.         int32_t expWOY = DATA[i++];
  1613.         int32_t actWOY = cal.get(Calendar::WEEK_OF_YEAR, status);
  1614.         if (expWOY == actWOY) {
  1615.             logln(UnicodeString("Ok: ") + dfmt.format(cal.getTime(status), str.remove()));
  1616.         } else {
  1617.             errln(UnicodeString("FAIL: ") + dfmt.format(cal.getTime(status), str.remove())
  1618.                   + ", expected WOY=" + expWOY);
  1619.             cal.add(Calendar::DATE, -8, status);
  1620.             for (int j=0; j<14; ++j) {
  1621.                 cal.add(Calendar::DATE, 1, status);
  1622.                 logln(dfmt.format(cal.getTime(status), str.remove()));
  1623.             }
  1624.         }
  1625.         if (U_FAILURE(status)) {
  1626.             errln("FAIL: Unexpected error from Calendar");
  1627.             return;
  1628.         }
  1629.     }
  1630. }
  1631.  
  1632. UDate
  1633. CalendarRegressionTest::makeDate(int32_t y, int32_t m, int32_t d,
  1634.                                     int32_t hr, int32_t min, int32_t sec)
  1635. {
  1636.     UDate result;
  1637.  
  1638.     UErrorCode status = U_ZERO_ERROR;
  1639.     Calendar *cal = Calendar::createInstance(status);
  1640.     cal->clear();
  1641.  
  1642.     cal->set(Calendar::YEAR, y);
  1643.     
  1644.     if(m != 0)        cal->set(Calendar::MONTH, m);
  1645.     if(d != 0)        cal->set(Calendar::DATE, d);
  1646.     if(hr != 0)        cal->set(Calendar::HOUR, hr);
  1647.     if(min != 0)    cal->set(Calendar::MINUTE, min);
  1648.     if(sec != 0)    cal->set(Calendar::SECOND, sec);
  1649.  
  1650.     result = cal->getTime(status);
  1651.  
  1652.     delete cal;
  1653.  
  1654.     return result;
  1655. }
  1656.