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

  1.  
  2. /*
  3. ********************************************************************
  4. * COPYRIGHT: 
  5. * (C) Copyright Taligent, Inc., 1997
  6. * (C) Copyright International Business Machines Corporation, 1997 - 1998
  7. * Licensed Material - Program-Property of IBM - All Rights Reserved. 
  8. * US Government Users Restricted Rights - Use, duplication, or disclosure 
  9. * restricted by GSA ADP Schedule Contract with IBM Corp. 
  10. *
  11. ********************************************************************
  12. */
  13.  
  14. #include "dtfmttst.h"
  15. #include "timezone.h"
  16. #include "gregocal.h"
  17. #include "smpdtfmt.h"
  18. #include "datefmt.h"
  19. #include "simpletz.h"
  20.  
  21. // *****************************************************************************
  22. // class DateFormatTest
  23. // *****************************************************************************
  24.  
  25. #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break;
  26.  
  27. void DateFormatTest::runIndexedTest( int32_t index, bool_t exec, char* &name, char* par )
  28. {
  29.     // if (exec) logln((UnicodeString)"TestSuite DateFormatTest");
  30.     switch (index) {
  31.         CASE(0,TestEquals)
  32.         CASE(1,TestTwoDigitYearDSTParse)
  33.         CASE(2,TestFieldPosition)
  34.         CASE(3,TestPartialParse994)
  35.         CASE(4,TestRunTogetherPattern985)
  36.         CASE(5,TestRunTogetherPattern917)
  37.         CASE(6,TestCzechMonths459)
  38.         CASE(7,TestLetterDPattern212)
  39.         CASE(8,TestDayOfYearPattern195)
  40.         CASE(9,TestQuotePattern161)
  41.         CASE(10,TestBadInput135)
  42.         CASE(11,TestBadInput135a)
  43.         CASE(12,TestTwoDigitYear)
  44.         CASE(13,TestDateFormatZone061)
  45.         CASE(14,TestDateFormatZone146)
  46.         CASE(15,TestLocaleDateFormat)
  47.         CASE(16,TestWallyWedel)
  48.         default: name = ""; break;
  49.     }
  50. }
  51.  
  52. // Test written by Wally Wedel and emailed to me.
  53. void DateFormatTest::TestWallyWedel()
  54. {
  55.     UErrorCode status = U_ZERO_ERROR;
  56.     /*
  57.      * Instantiate a TimeZone so we can get the ids.
  58.      */
  59.     TimeZone *tz = new SimpleTimeZone(7,"");
  60.     /*
  61.      * Computational variables.
  62.      */
  63.     int32_t offset, hours, minutes;
  64.     /*
  65.      * Instantiate a SimpleDateFormat set up to produce a full time
  66.      zone name.
  67.      */
  68.     SimpleDateFormat *sdf = new SimpleDateFormat("zzzz", status);
  69.     /*
  70.      * A String array for the time zone ids.
  71.      */
  72.     int32_t ids_length;
  73.     const UnicodeString **ids = TimeZone::createAvailableIDs(ids_length);
  74.     /*
  75.      * How many ids do we have?
  76.      */
  77.     logln("Time Zone IDs size: " + ids_length);
  78.     /*
  79.      * Column headings (sort of)
  80.      */
  81.     logln("Ordinal ID offset(h:m) name");
  82.     /*
  83.      * Loop through the tzs.
  84.      */
  85.     UDate today = Calendar::getNow();
  86.     Calendar *cal = Calendar::createInstance(status);
  87.     for (int32_t i = 0; i < ids_length; i++) {
  88.         // logln(i + " " + ids[i]);
  89.         TimeZone *ttz = TimeZone::createTimeZone(*ids[i]);
  90.         // offset = ttz.getRawOffset();
  91.         cal->setTimeZone(*ttz);
  92.         cal->setTime(today, status);
  93.         offset = cal->get(Calendar::ZONE_OFFSET, status) + cal->get(Calendar::DST_OFFSET, status);
  94.         // logln(i + " " + ids[i] + " offset " + offset);
  95.         char* sign = "+";
  96.         if (offset < 0) { sign = "-"; offset = -offset; }
  97.         hours = offset/3600000;
  98.         minutes = (offset%3600000)/60000;
  99.         UnicodeString dstOffset = (UnicodeString)"" + sign + (hours < 10 ? "0" : "") +
  100.             (int32_t)hours + ":" + (minutes < 10 ? "0" : "") + (int32_t)minutes;
  101.         /*
  102.          * Instantiate a date so we can display the time zone name.
  103.          */
  104.         sdf->setTimeZone(*ttz);
  105.         /*
  106.          * Format the output.
  107.          */
  108.         UnicodeString fmtOffset;
  109.         FieldPosition pos(0);
  110.         sdf->format(today,fmtOffset, pos);
  111.         // UnicodeString fmtOffset = tzS.toString();
  112.         UnicodeString *fmtDstOffset = 0;
  113.         if (fmtOffset.startsWith("GMT"))
  114.         {
  115.             //fmtDstOffset = fmtOffset->substring(3);
  116.             fmtDstOffset = new UnicodeString();
  117.             fmtOffset.extract(3, fmtOffset.size(), *fmtDstOffset);
  118.         }
  119.         /*
  120.          * Show our result.
  121.          */
  122.         bool_t ok = fmtDstOffset == 0 || *fmtDstOffset == dstOffset;
  123.         if (ok)
  124.         {
  125.             logln(UnicodeString() + i + " " + *ids[i] + " " + dstOffset +
  126.                   " " + fmtOffset +
  127.                   (fmtDstOffset != 0 ? " ok" : " ?"));
  128.         }
  129.         else
  130.         {
  131.             errln(UnicodeString() + i + " " + *ids[i] + " " + dstOffset +
  132.                   " " + fmtOffset + " *** FAIL ***");
  133.         }
  134.         delete ttz;
  135.         delete fmtDstOffset;
  136.     }
  137.     delete cal;
  138.     delete ids;
  139.     delete sdf;
  140.     delete tz;
  141. }
  142.  
  143. // -------------------------------------
  144.  
  145. /**
  146.  * Test operator==
  147.  */
  148. void
  149. DateFormatTest::TestEquals()
  150. {
  151.     DateFormat* fmtA = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
  152.     DateFormat* fmtB = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL);
  153.     if (!(*fmtA == *fmtB)) errln((UnicodeString)"FAIL");
  154.     delete fmtA;
  155.     delete fmtB;
  156. }
  157.  
  158. // -------------------------------------
  159.  
  160. /**
  161.  * Test the parsing of 2-digit years.
  162.  */
  163. void
  164. DateFormatTest::TestTwoDigitYearDSTParse()
  165. {
  166.     UErrorCode status = U_ZERO_ERROR;
  167.     SimpleDateFormat* fullFmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss.SSS zzz yyyy G", status);
  168.     SimpleDateFormat *fmt = new SimpleDateFormat("dd-MMM-yy h:mm:ss 'o''clock' a z", Locale::ENGLISH, status);
  169.     //DateFormat* fmt = DateFormat::createDateTimeInstance(DateFormat::MEDIUM, DateFormat::FULL, Locale::ENGLISH);
  170.     UnicodeString* s = new UnicodeString("03-Apr-04 2:20:47 o'clock AM PST");
  171.     int32_t hour = 2;
  172.  
  173.     UnicodeString str;
  174.     UDate d = fmt->parse(*s, status);
  175.     logln(*s + " P> " + ((DateFormat*)fullFmt)->format(d, str));
  176.     int32_t y, m, day, hr, min, sec;
  177.     dateToFields(d, y, m, day, hr, min, sec);
  178.     if (hr != hour) errln((UnicodeString)"FAIL: Should parse to hour " + hour);
  179.  
  180.     if (U_FAILURE(status))
  181.         errln((UnicodeString)"FAIL: " + (int32_t)status);
  182.  
  183.     delete s;
  184.     delete fmt;
  185.     delete fullFmt;
  186. }
  187.  
  188. // -------------------------------------
  189.  
  190. char toHexString(int32_t i) { return i + (i < 10 ? '0' : ('A' - 10)); }
  191.  
  192. UnicodeString&
  193. DateFormatTest::escape(UnicodeString& s)
  194. {
  195.     UnicodeString buf;
  196.     for (int32_t i=0; i<s.size(); ++i)
  197.     {
  198.         UChar c = s[(UTextOffset)i];
  199.         if (c <= (UChar)0x7F) buf += c;
  200.         else {
  201.             buf += '\\'; buf += 'U';
  202.             buf += toHexString((c & 0xF000) >> 12);
  203.             buf += toHexString((c & 0x0F00) >> 8);
  204.             buf += toHexString((c & 0x00F0) >> 4);
  205.             buf += toHexString(c & 0x000F);
  206.         }
  207.     }
  208.     return (s = buf);
  209. }
  210.  
  211. char* DateFormatTest::fieldNames[] = {
  212.     "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET", "DST_OFFSET"
  213. };
  214.  
  215. // -------------------------------------
  216.  
  217. // Map Calendar field number to to DateFormat field number
  218. const DateFormat::EField
  219. DateFormatTest::fgCalendarToDateFormatField[] = {
  220.     DateFormat::kEraField, 
  221.     DateFormat::kYearField, 
  222.     DateFormat::kMonthField,
  223.     DateFormat::kWeekOfYearField, 
  224.     DateFormat::kWeekOfMonthField,
  225.     DateFormat::kDateField, 
  226.     DateFormat::kDayOfYearField, 
  227.     DateFormat::kDayOfWeekField,     
  228.     DateFormat::kDayOfWeekInMonthField, 
  229.     DateFormat::kAmPmField,
  230.     DateFormat::kHour1Field, 
  231.     DateFormat::kHourOfDay0Field, 
  232.     DateFormat::kMinuteField, 
  233.     DateFormat::kSecondField, 
  234.     DateFormat::kMillisecondField,
  235.     DateFormat::kTimezoneField, 
  236.     (DateFormat::EField) -1
  237. };
  238.  
  239. /**
  240.  * Verify that returned field position indices are correct.
  241.  */
  242. void
  243. DateFormatTest::TestFieldPosition(void)
  244. {
  245.     UErrorCode status = U_ZERO_ERROR;
  246.     DateFormat* dateFormats[4];
  247.     int32_t dateFormats_length = sizeof(dateFormats) / sizeof(dateFormats[0]);
  248.  
  249.     /* {sfb} This test was coded incorrectly.
  250.     / FieldPosition uses the fields in the class you are formatting with
  251.     / So, for example, to get the DATE field from a DateFormat use
  252.     / DateFormat::DATE_FIELD, __not__ Calendar::DATE
  253.     / The ordering of the expected values used previously was wrong.
  254.     / instead of re-ordering this mess of strings, just transform the index values */
  255.  
  256.     /* field values, in Calendar order */
  257.  
  258.     const char* expected[] = {
  259.         "", "1997", "August", "", "", "13", "", "Wednesday", "", "PM", "2", "", 
  260.         "34", "12", "", "PDT", "", "", "1997", "ao\373t",/* 373 = 0xFB */  "", 
  261.         "", "13", "", "mercredi", "", "", "", "14", "34", "", "", "GMT-07:00", 
  262.         "", "AD", "97", "8", "33", "3", "13", "225", "Wed", "2", "PM", "2", 
  263.         "14", "34", "12", "5", "PDT", "", "AD", "1997", "August", "0033", 
  264.         "0003", "0013", "0225", "Wednesday", "0002", "PM", "0002", "0014", 
  265.         "0034", "0012", "513", "Pacific Daylight Time", "" 
  266.     };
  267.  
  268.     UDate someDate = 871508052513.0;
  269.     int32_t j, exp;
  270.  
  271.     dateFormats[0] = DateFormat::createDateTimeInstance(DateFormat::FULL, DateFormat::FULL, Locale::US);
  272.     dateFormats[1] = DateFormat::createDateTimeInstance(DateFormat::FULL, DateFormat::FULL, Locale::FRANCE);
  273.     dateFormats[2] = new SimpleDateFormat("G, y, M, d, k, H, m, s, S, E, D, F, w, W, a, h, K, z", status);
  274.     dateFormats[3] = new SimpleDateFormat("GGGG, yyyy, MMMM, dddd, kkkk, HHHH, mmmm, ssss, SSSS, EEEE, DDDD, FFFF, wwww, WWWW, aaaa, hhhh, KKKK, zzzz", status);
  275.     for (j = 0, exp = 0; j < dateFormats_length;++j) {
  276.         UnicodeString str;
  277.         DateFormat* df = dateFormats[j];
  278.         logln((UnicodeString)" Pattern = " + ((SimpleDateFormat*)df)->toPattern(str));
  279.         str.truncate(0);
  280.         logln((UnicodeString)"  Result = " + df->format(someDate, str));
  281.         for (int32_t i = 0; i < Calendar::FIELD_COUNT;++i) {
  282.             UnicodeString field;
  283.             getFieldText(df, i, someDate, field);
  284.             UnicodeString expStr(expected[exp]);
  285.             if (!(field == expStr)) errln(UnicodeString("FAIL: field #") + i + " " +
  286.                 fieldNames[i] + " = \"" + escape(field) + "\", expected \"" + escape(expStr) + "\"");
  287.             ++exp;
  288.         }
  289.     }
  290.     for (j=0; j<dateFormats_length; ++j) delete dateFormats[j];
  291.     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status); 
  292. }
  293.  
  294. // -------------------------------------
  295.  
  296. void
  297. DateFormatTest::getFieldText(DateFormat* df, int32_t field, UDate date, UnicodeString& str)
  298. {
  299.     UnicodeString formatResult;
  300.     // {sfb} added to convert Calendar Fields to DateFormat fields
  301.     FieldPosition pos(fgCalendarToDateFormatField[field]);
  302.     df->format(date, formatResult, pos);
  303.     //formatResult.extract(pos.getBeginIndex(), pos.getEndIndex(), str);
  304.     formatResult.extractBetween(pos.getBeginIndex(), pos.getEndIndex(), str);
  305. }
  306.  
  307. // -------------------------------------
  308.  
  309. /**
  310.  * Verify that strings which contain incomplete specifications are parsed
  311.  * correctly.  In some instances, this means not being parsed at all, and
  312.  * returning an appropriate error.
  313.  */
  314. void
  315. DateFormatTest::TestPartialParse994()
  316. {
  317.     UErrorCode status = U_ZERO_ERROR;
  318.     SimpleDateFormat* f = new SimpleDateFormat(status);
  319.     UDate null = 0;
  320.     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:11:42", date(97, 1 - 1, 17, 10, 11, 42));
  321.     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10:", null);
  322.     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 10", null);
  323.     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17 ", null);
  324.     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/17", null);
  325.     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
  326.     delete f;
  327. }
  328.  
  329. // -------------------------------------
  330.  
  331. void
  332. DateFormatTest::tryPat994(SimpleDateFormat* format, const char* pat, const char* str, UDate expected)
  333. {
  334.     UErrorCode status = U_ZERO_ERROR;
  335.     UDate null = 0;
  336.     logln(UnicodeString("Pattern \"") + pat + "\"   String \"" + str + "\"");
  337.     //try {
  338.         format->applyPattern(pat);
  339.         UDate date = format->parse(str, status);
  340.         if (U_FAILURE(status) || date == null)
  341.         {
  342.             logln((UnicodeString)"ParseException: " + (int32_t)status);
  343.             if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
  344.         }
  345.         else
  346.         {
  347.             UnicodeString f;
  348.             ((DateFormat*)format)->format(date, f);
  349.             logln(UnicodeString(" parse(") + str + ") -> " + dateToString(date));
  350.             logln((UnicodeString)" format -> " + f);
  351.             if (expected == null ||
  352.                 !(date == expected)) errln((UnicodeString)"FAIL: Expected null");//" + expected);
  353.             if (!(f == str)) errln(UnicodeString("FAIL: Expected ") + str);
  354.         }
  355.     //}
  356.     //catch(ParseException e) {
  357.     //    logln((UnicodeString)"ParseException: " + e.getMessage());
  358.     //    if (expected != null) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
  359.     //}
  360.     //catch(Exception e) {
  361.     //    errln((UnicodeString)"*** Exception:");
  362.     //    e.printStackTrace();
  363.     //}
  364. }
  365.  
  366. // -------------------------------------
  367.  
  368. /**
  369.  * Verify the behavior of patterns in which digits for different fields run together
  370.  * without intervening separators.
  371.  */
  372. void
  373. DateFormatTest::TestRunTogetherPattern985()
  374. {
  375.     UErrorCode status = U_ZERO_ERROR;
  376.     UnicodeString format("yyyyMMddHHmmssSSS");
  377.     UnicodeString now, then;
  378.     //bool_t flag;
  379.     SimpleDateFormat *formatter = new SimpleDateFormat(format, status);
  380.     UDate date1 = Calendar::getNow();
  381.     ((DateFormat*)formatter)->format(date1, now);
  382.     logln(now);
  383.     ParsePosition pos(0);
  384.     UDate date2 = formatter->parse(now, pos);
  385.     if (date2 == 0) then = "Parse stopped at " + pos.getIndex();
  386.     else ((DateFormat*)formatter)->format(date2, then);
  387.     logln(then);
  388.     if (!(date2 == date1)) errln((UnicodeString)"FAIL");
  389.     delete formatter;
  390.     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
  391. }
  392.  
  393. // -------------------------------------
  394.  
  395. /**
  396.  * Verify the behavior of patterns in which digits for different fields run together
  397.  * without intervening separators.
  398.  */
  399. void
  400. DateFormatTest::TestRunTogetherPattern917()
  401. {
  402.     UErrorCode status = U_ZERO_ERROR;
  403.     SimpleDateFormat* fmt;
  404.     UnicodeString myDate;
  405.     fmt = new SimpleDateFormat("yyyy/MM/dd", status);
  406.     myDate = "1997/02/03";
  407.     testIt917(fmt, myDate, date(97, 2 - 1, 3));
  408.     delete fmt;
  409.     fmt = new SimpleDateFormat("yyyyMMdd", status);
  410.     myDate = "19970304";
  411.     testIt917(fmt, myDate, date(97, 3 - 1, 4));
  412.     delete fmt;
  413.     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
  414. }
  415.  
  416. // -------------------------------------
  417.  
  418. void
  419. DateFormatTest::testIt917(SimpleDateFormat* fmt, UnicodeString& str, UDate expected)
  420. {
  421.     UErrorCode status = U_ZERO_ERROR;
  422.     UnicodeString pattern;
  423.     logln((UnicodeString)"pattern=" + fmt->toPattern(pattern) + "   string=" + str);
  424.     Formattable o;
  425.     //try {
  426.         ((Format*)fmt)->parseObject(str, o, status);
  427.     //}
  428.     if (U_FAILURE(status)) return;
  429.     //catch(ParseException e) {
  430.     //    e.printStackTrace();
  431.     //    return;
  432.     //}
  433.     logln((UnicodeString)"Parsed object: " + dateToString(o.getDate()));
  434.     if (!(o.getDate() == expected)) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
  435.     UnicodeString formatted; ((Format*)fmt)->format(o, formatted, status);
  436.     logln((UnicodeString)"Formatted string: " + formatted);
  437.     if (!(formatted == str)) errln((UnicodeString)"FAIL: Expected " + str);
  438.     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
  439. }
  440.  
  441. // -------------------------------------
  442.  
  443. /**
  444.  * Verify the handling of Czech June and July, which have the unique attribute that
  445.  * one is a proper prefix substring of the other.
  446.  */
  447. void
  448. DateFormatTest::TestCzechMonths459()
  449. {
  450.     UErrorCode status = U_ZERO_ERROR;
  451.     DateFormat* fmt = DateFormat::createDateInstance(DateFormat::FULL, Locale("cs", "", ""));
  452.     UnicodeString pattern;
  453.     logln((UnicodeString)"Pattern " + ((SimpleDateFormat*) fmt)->toPattern(pattern));
  454.     UDate june = date(97, Calendar::JUNE, 15);
  455.     UDate july = date(97, Calendar::JULY, 15);
  456.     UnicodeString juneStr; fmt->format(june, juneStr);
  457.     UnicodeString julyStr; fmt->format(july, julyStr);
  458.     //try {
  459.         logln((UnicodeString)"format(June 15 1997) = " + juneStr);
  460.         UDate d = fmt->parse(juneStr, status);
  461.         UnicodeString s; fmt->format(d, s);
  462.         int32_t month,yr,day,hr,min,sec; dateToFields(d,yr,month,day,hr,min,sec);
  463.         logln((UnicodeString)"  -> parse -> " + s + " (month = " + month + ")");
  464.         if (month != Calendar::JUNE) errln((UnicodeString)"FAIL: Month should be June");
  465.         logln((UnicodeString)"format(July 15 1997) = " + julyStr);
  466.         d = fmt->parse(julyStr, status);
  467.         fmt->format(d, s);
  468.         dateToFields(d,yr,month,day,hr,min,sec);
  469.         logln((UnicodeString)"  -> parse -> " + s + " (month = " + month + ")");
  470.         if (month != Calendar::JULY) errln((UnicodeString)"FAIL: Month should be July");
  471.     //}
  472.     //catch(ParseException e) {
  473.     if (U_FAILURE(status))
  474.         errln((UnicodeString)"Exception: " + (int32_t)status);
  475.     //}
  476.     delete fmt;
  477. }
  478.  
  479. // -------------------------------------
  480.  
  481. /**
  482.  * Test the handling of 'D' in patterns.
  483.  */
  484. void
  485. DateFormatTest::TestLetterDPattern212()
  486. {
  487.     UErrorCode status = U_ZERO_ERROR;
  488.     UnicodeString dateString("1995-040.05:01:29");
  489.     UnicodeString bigD("yyyy-DDD.hh:mm:ss");
  490.     UnicodeString littleD("yyyy-ddd.hh:mm:ss");
  491.     UDate expLittleD = date(95, 0, 1, 5, 1, 29);
  492.     UDate expBigD = expLittleD + 39 * 24 * 3600000.0;
  493.     expLittleD = expBigD; // Expect the same, with default lenient parsing
  494.     logln((UnicodeString)"dateString= " + dateString);
  495.     SimpleDateFormat *formatter = new SimpleDateFormat(bigD, status);
  496.     ParsePosition pos(0);
  497.     UDate myDate = formatter->parse(dateString, pos);
  498.     logln((UnicodeString)"Using " + bigD + " -> " + myDate);
  499.     if (myDate != expBigD) errln((UnicodeString)"FAIL: Expected " + dateToString(expBigD));
  500.     delete formatter;
  501.     formatter = new SimpleDateFormat(littleD, status);
  502.     pos = ParsePosition(0);
  503.     myDate = formatter->parse(dateString, pos);
  504.     logln((UnicodeString)"Using " + littleD + " -> " + dateToString(myDate));
  505.     if (myDate != expLittleD) errln((UnicodeString)"FAIL: Expected " + dateToString(expLittleD));
  506.     delete formatter;
  507.     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
  508. }
  509.  
  510. // -------------------------------------
  511.  
  512. /**
  513.  * Test the day of year pattern.
  514.  */
  515. void
  516. DateFormatTest::TestDayOfYearPattern195()
  517. {
  518.     UErrorCode status = U_ZERO_ERROR;
  519.     UDate today = Calendar::getNow();
  520.     int32_t year,month,day,hour,min,sec; dateToFields(today,year,month,day,hour,min,sec);
  521.     UDate expected = date(year, month, day);
  522.     logln((UnicodeString)"Test Date: " + dateToString(today));
  523.     SimpleDateFormat* sdf = (SimpleDateFormat*)DateFormat::createDateInstance();
  524.     tryPattern(*sdf, today, 0, expected);
  525.     tryPattern(*sdf, today, "G yyyy DDD", expected);
  526.     delete sdf;
  527.     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
  528. }
  529.  
  530. // -------------------------------------
  531.  
  532. void
  533. DateFormatTest::tryPattern(SimpleDateFormat& sdf, UDate d, const char* pattern, UDate expected)
  534. {
  535.     UErrorCode status = U_ZERO_ERROR;
  536.     if (pattern != 0) sdf.applyPattern(pattern);
  537.     UnicodeString thePat;
  538.     logln((UnicodeString)"pattern: " + sdf.toPattern(thePat));
  539.     UnicodeString formatResult; (*(DateFormat*)&sdf).format(d, formatResult);
  540.     logln((UnicodeString)" format -> " + formatResult);
  541.     // try {
  542.         UDate d2 = sdf.parse(formatResult, status);
  543.         logln((UnicodeString)" parse(" + formatResult + ") -> " + dateToString(d2));
  544.         if (d2 != expected) errln((UnicodeString)"FAIL: Expected " + dateToString(expected));
  545.         UnicodeString format2; (*(DateFormat*)&sdf).format(d2, format2);
  546.         logln((UnicodeString)" format -> " + format2);
  547.         if (!(formatResult == format2)) errln((UnicodeString)"FAIL: Round trip drift");
  548.     //}
  549.     //catch(Exception e) {
  550.     if (U_FAILURE(status))
  551.         errln((UnicodeString)"Error: " + (int32_t)status);
  552.     //}
  553. }
  554.  
  555. // -------------------------------------
  556.  
  557. /**
  558.  * Test the handling of single quotes in patterns.
  559.  */
  560. void
  561. DateFormatTest::TestQuotePattern161()
  562. {
  563.     UErrorCode status = U_ZERO_ERROR;
  564.     SimpleDateFormat* formatter = new SimpleDateFormat("MM/dd/yyyy 'at' hh:mm:ss a zzz", status);
  565.     UDate currentTime_1 = date(97, Calendar::AUGUST, 13, 10, 42, 28);
  566.     UnicodeString dateString; ((DateFormat*)formatter)->format(currentTime_1, dateString);
  567.     UnicodeString exp("08/13/1997 at 10:42:28 AM ");
  568.     logln((UnicodeString)"format(" + dateToString(currentTime_1) + ") = " + dateString);
  569.     if (0 != dateString.compareBetween(0, exp.size(), exp, 0, exp.size())) errln((UnicodeString)"FAIL: Expected " + exp);
  570.     delete formatter;
  571.     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
  572. }
  573.  
  574. // -------------------------------------
  575.  
  576. /**
  577.  * Verify the correct behavior when handling invalid input strings.
  578.  */
  579. void
  580. DateFormatTest::TestBadInput135()
  581. {
  582.     UErrorCode status = U_ZERO_ERROR;
  583.     int32_t looks[] = {
  584.         DateFormat::SHORT, DateFormat::MEDIUM, DateFormat::LONG, DateFormat::FULL
  585.     };
  586.     int32_t looks_length = sizeof(looks) / sizeof(looks[0]);
  587.     const char* strings[] = {
  588.         "Mar 15", "Mar 15 1997", "asdf", "3/1/97 1:23:", "3/1/00 1:23:45 AM"
  589.     };
  590.     int32_t strings_length = sizeof(strings) / sizeof(strings[0]);
  591.     DateFormat *full = DateFormat::createDateTimeInstance(DateFormat::LONG, DateFormat::LONG);
  592.     UnicodeString expected("March 1, 2000 1:23:45 AM ");
  593.     for (int32_t i = 0; i < strings_length;++i) {
  594.         const char* text = strings[i];
  595.         for (int32_t j = 0; j < looks_length;++j) {
  596.             int32_t dateLook = looks[j];
  597.             for (int32_t k = 0; k < looks_length;++k) {
  598.                 int32_t timeLook = looks[k];
  599.                 DateFormat *df = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateLook, (DateFormat::EStyle)timeLook);
  600.                 UnicodeString prefix = UnicodeString(text) + ", " + dateLook + "/" + timeLook + ": ";
  601.                 //try {
  602.                     UDate when = df->parse(text, status);
  603.                     if (when == 0 && U_SUCCESS(status)) {
  604.                         errln(prefix + "SHOULD NOT HAPPEN: parse returned null.");
  605.                         continue;
  606.                     }
  607.                     if (U_SUCCESS(status))
  608.                     {
  609.                         UnicodeString format; full->format(when, format);
  610.                         logln(prefix + "OK: " + format);
  611.                         if (0!=format.compareBetween(0, expected.size(), expected, 0, expected.size()))
  612.                             errln((UnicodeString)"FAIL: Expected " + expected);
  613.                     }
  614.                 //}
  615.                 //catch(ParseException e) {
  616.                     else status = U_ZERO_ERROR;
  617.                 //}
  618.                 //catch(StringIndexOutOfBoundsException e) {
  619.                 //    errln(prefix + "SHOULD NOT HAPPEN: " + (int)status);
  620.                 //}
  621.                 delete df;
  622.             }
  623.         }
  624.     }
  625.     delete full;
  626.     if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
  627. }
  628.  
  629. const char* DateFormatTest::parseFormats[] = {
  630.     "MMMM d, yyyy",
  631.     "MMMM d yyyy",
  632.     "M/d/yy",
  633.     "d MMMM, yyyy",
  634.     "d MMMM yyyy",
  635.     "d MMMM",
  636.     "MMMM d",
  637.     "yyyy",
  638.     "h:mm a MMMM d, yyyy"
  639. };
  640.  
  641. const char* DateFormatTest::inputStrings[] = {
  642.     "bogus string", 0, 0, 0, 0, 0, 0, 0, 0, 0,
  643.     "April 1, 1997", "April 1, 1997", 0, 0, 0, 0, 0, "April 1", 0, 0,
  644.     "Jan 1, 1970", "January 1, 1970", 0, 0, 0, 0, 0, "January 1", 0, 0,
  645.     "Jan 1 2037", 0, "January 1 2037", 0, 0, 0, 0, "January 1", 0, 0,
  646.     "1/1/70", 0, 0, "1/1/70", 0, 0, 0, 0, "0001", 0,
  647.     "5 May 1997", 0, 0, 0, 0, "5 May 1997", "5 May", 0, "0005", 0,
  648.     "16 May", 0, 0, 0, 0, 0, "16 May", 0, "0016", 0,
  649.     "April 30", 0, 0, 0, 0, 0, 0, "April 30", 0, 0,
  650.     "1998", 0, 0, 0, 0, 0, 0, 0, "1998", 0,
  651.     "1", 0, 0, 0, 0, 0, 0, 0, "0001", 0,
  652.     "3:00 pm Jan 1, 1997", 0, 0, 0, 0, 0, 0, 0, "0003", "3:00 PM January 1, 1997",
  653. };
  654.  
  655. // -------------------------------------
  656.  
  657. /**
  658.  * Verify the correct behavior when parsing an array of inputs against an
  659.  * array of patterns, with known results.  The results are encoded after
  660.  * the input strings in each row.
  661.  */
  662. void
  663. DateFormatTest::TestBadInput135a()
  664. {
  665.   UErrorCode status = U_ZERO_ERROR;
  666.   SimpleDateFormat* dateParse = new SimpleDateFormat(status);
  667.   const char* s;
  668.   UDate date;
  669.   int32_t PFLENGTH = sizeof(parseFormats)/sizeof(parseFormats[0]);
  670.   dateParse->applyPattern("d MMMM, yyyy");
  671.   dateParse->adoptTimeZone(TimeZone::createDefault());
  672.   s = "not parseable";
  673.   UnicodeString thePat;
  674.   logln(UnicodeString("Trying to parse \"") + s + "\" with " + dateParse->toPattern(thePat));
  675.   //try {
  676.   date = dateParse->parse(s, status);
  677.   if (U_SUCCESS(status))
  678.     errln((UnicodeString)"FAIL: Expected exception during parse");
  679.   //}
  680.   //catch(Exception ex) {
  681.   else
  682.     logln((UnicodeString)"Exception during parse: " + (int32_t)status);
  683.   status = U_ZERO_ERROR;
  684.   //}
  685.   for (int32_t i = 0; i < sizeof(inputStrings)/sizeof(inputStrings[0]); i += (PFLENGTH + 1)) {
  686.     ParsePosition parsePosition(0);
  687.     UnicodeString s( inputStrings[i]);
  688.     for (int32_t index = 0; index < PFLENGTH;++index) {
  689.       const char* expected = inputStrings[i + 1 + index];
  690.       dateParse->applyPattern(parseFormats[index]);
  691.       dateParse->adoptTimeZone(TimeZone::createDefault());
  692.       //try {
  693.       parsePosition.setIndex(0);
  694.       date = dateParse->parse(s, parsePosition);
  695.       if (parsePosition.getIndex() != 0) {
  696.     UnicodeString s1, s2;
  697.     s.extract(0, parsePosition.getIndex(), s1);
  698.     s.extract(parsePosition.getIndex(), s.size(), s2);
  699.     if (date == 0) errln((UnicodeString)"ERROR: null result fmt=\"" +
  700.                  parseFormats[index] +
  701.                  "\" pos=" + parsePosition.getIndex() + " " +
  702.                  s1 + "|" + s2);
  703.     else {
  704.       UnicodeString result; ((DateFormat*)dateParse)->format(date, result);
  705.       logln((UnicodeString)"Parsed \"" + s + "\" using \"" + dateParse->toPattern(thePat) + "\" to: " + result);
  706.       if (expected == 0) errln((UnicodeString)"FAIL: Expected parse failure");
  707.       else if (!(result == expected)) errln(UnicodeString("FAIL: Expected ") + expected);
  708.     }
  709.       }
  710.       else {
  711.     if (expected != 0) errln(UnicodeString("FAIL: Expected ") + expected + " from \"" +
  712.                  s + "\" with \"" + dateParse->toPattern(thePat) + "\"");
  713.       }
  714.       //}
  715.       //catch(Exception ex) {
  716.       if (U_FAILURE(status))
  717.     errln((UnicodeString)"An exception was thrown during parse: " + (int32_t)status);
  718.       //}
  719.     }
  720.   }
  721.   delete dateParse;
  722.   if (U_FAILURE(status)) errln((UnicodeString)"FAIL: UErrorCode received during test: " + (int32_t)status);
  723. }
  724.  
  725. // -------------------------------------
  726.  
  727. /**
  728.  * Test the parsing of two-digit years.
  729.  */
  730. void
  731. DateFormatTest::TestTwoDigitYear()
  732. {
  733.     DateFormat* fmt = DateFormat::createDateInstance(DateFormat::SHORT);
  734.     parse2DigitYear(*fmt, "6/5/17", date(117, Calendar::JUNE, 5));
  735.     parse2DigitYear(*fmt, "6/4/34", date(34, Calendar::JUNE, 4));
  736.     delete fmt;
  737. }
  738.  
  739. // -------------------------------------
  740.  
  741. void
  742. DateFormatTest::parse2DigitYear(DateFormat& fmt, const char* str, UDate expected)
  743. {
  744.     UErrorCode status = U_ZERO_ERROR;
  745.     //try {
  746.         UDate d = fmt.parse(str, status);
  747.         UnicodeString thePat;
  748.         logln(UnicodeString("Parsing \"") + str + "\" with " + ((SimpleDateFormat*)&fmt)->toPattern(thePat) +
  749.             "  => " + dateToString(d));
  750.         if (d != expected) errln((UnicodeString)"FAIL: Expected " + expected);
  751.     //}
  752.     //catch(ParseException e) {
  753.         if (U_FAILURE(status))
  754.         errln((UnicodeString)"FAIL: Got exception");
  755.     //}
  756. }
  757.  
  758. // -------------------------------------
  759.  
  760. /**
  761.  * Test the formatting of time zones.
  762.  */
  763. void
  764. DateFormatTest::TestDateFormatZone061()
  765. {
  766.     UErrorCode status = U_ZERO_ERROR;
  767.     UDate date;
  768.     DateFormat *formatter;
  769.     date= 859248000000.0;
  770.     logln((UnicodeString)"Date 1997/3/25 00:00 GMT: " + date);
  771.     formatter = new SimpleDateFormat("dd-MMM-yyyyy HH:mm", Locale::UK, status);
  772.     formatter->adoptTimeZone(TimeZone::createTimeZone("GMT"));
  773.     UnicodeString temp; formatter->format(date, temp);
  774.     logln((UnicodeString)"Formatted in GMT to: " + temp);
  775.     //try {
  776.         UDate tempDate = formatter->parse(temp, status);
  777.         logln((UnicodeString)"Parsed to: " + dateToString(tempDate));
  778.         if (tempDate != date) errln((UnicodeString)"FAIL: Expected " + dateToString(date));
  779.     //}
  780.     //catch(Throwable t) {
  781.     if (U_FAILURE(status))
  782.         errln((UnicodeString)"Date Formatter throws: " + (int32_t)status);
  783.     //}
  784.     delete formatter;
  785. }
  786.  
  787. // -------------------------------------
  788.  
  789. /**
  790.  * Test the formatting of time zones.
  791.  */
  792. void
  793. DateFormatTest::TestDateFormatZone146()
  794. {
  795.     TimeZone *saveDefault = TimeZone::createDefault();
  796.  
  797.         //try {
  798.     TimeZone *thedefault = TimeZone::createTimeZone("GMT");
  799.     TimeZone::setDefault(*thedefault);
  800.             // java.util.Locale.setDefault(new java.util.Locale("ar", "", ""));
  801.  
  802.             // check to be sure... its GMT all right
  803. TimeZone *testdefault = TimeZone::createDefault();
  804.         UnicodeString testtimezone;
  805.         testdefault->getID(testtimezone);
  806.         if (testtimezone == "GMT")
  807.             logln("Test timezone = " + testtimezone);
  808.         else
  809.             errln("Test timezone should be GMT, not " + testtimezone);
  810.  
  811.         UErrorCode status = U_ZERO_ERROR;
  812.         // now try to use the default GMT time zone
  813.         GregorianCalendar *greenwichcalendar =
  814.             new GregorianCalendar(1997, 3, 4, 23, 0, status);
  815.         failure(status, "new GregorianCalendar");
  816.         //*****************************greenwichcalendar.setTimeZone(TimeZone.getDefault());
  817.         //greenwichcalendar.set(1997, 3, 4, 23, 0);
  818.         // try anything to set hour to 23:00 !!!
  819.         greenwichcalendar->set(Calendar::HOUR_OF_DAY, 23);
  820.         // get time
  821.         UDate greenwichdate = greenwichcalendar->getTime(status);
  822.         // format every way
  823.         UnicodeString DATA [] = {
  824.             UnicodeString("simple format:  "), UnicodeString("04/04/97 23:00 GMT"),
  825.                 UnicodeString("MM/dd/yy HH:mm z"),
  826.             UnicodeString("full format:    "), UnicodeString("Friday, April 4, 1997 11:00:00 o'clock PM GMT"),
  827.                 UnicodeString("EEEE, MMMM d, yyyy h:mm:ss 'o''clock' a z"),
  828.             UnicodeString("long format:    "), UnicodeString("April 4, 1997 11:00:00 PM GMT"),
  829.                 UnicodeString("MMMM d, yyyy h:mm:ss a z"),
  830.             UnicodeString("default format: "), UnicodeString("04-Apr-97 11:00:00 PM"),
  831.                 UnicodeString("dd-MMM-yy h:mm:ss a"),
  832.             UnicodeString("short format:   "), UnicodeString("4/4/97 11:00 PM"),
  833.                 UnicodeString("M/d/yy h:mm a")
  834.         };
  835.         int32_t DATA_length = sizeof(DATA) / sizeof(DATA[0]);
  836.  
  837.         for (int32_t i=0; i<DATA_length; i+=3) {
  838.             DateFormat *fmt = new SimpleDateFormat(DATA[i+2], Locale::ENGLISH, status);
  839.             if(failure(status, "new SimpleDateFormat")) break;
  840.             fmt->setCalendar(*greenwichcalendar);
  841.             UnicodeString result;
  842.             result = fmt->format(greenwichdate, result);
  843.             logln(DATA[i] + result);
  844.             if (result != DATA[i+1]) 
  845.                 errln("FAIL: Expected " + DATA[i+1] + ", got " + result);
  846.         }
  847.     //}
  848.     //finally {
  849.         TimeZone::adoptDefault(saveDefault);
  850.     //}
  851.  
  852.  
  853. }
  854.  
  855. // -------------------------------------
  856.  
  857. /**
  858.  * Test the formatting of dates in different locales.
  859.  */
  860. void
  861. DateFormatTest::TestLocaleDateFormat() // Bug 495
  862. {
  863.     UDate testDate = date(97, Calendar::SEPTEMBER, 15);
  864.     DateFormat *dfFrench = DateFormat::createDateTimeInstance(DateFormat::FULL, 
  865.         DateFormat::FULL, Locale::FRENCH);
  866.     DateFormat *dfUS = DateFormat::createDateTimeInstance(DateFormat::FULL, 
  867.         DateFormat::FULL, Locale::US);
  868.     UnicodeString expectedFRENCH ( "lundi 15 septembre 1997 00 h 00 GMT-07:00" );
  869.     //UnicodeString expectedUS ( "Monday, September 15, 1997 12:00:00 o'clock AM PDT" );
  870.     UnicodeString expectedUS ( "Monday, September 15, 1997 12:00:00 AM PDT" );
  871.     logln((UnicodeString)"Date set to : " + dateToString(testDate));
  872.     UnicodeString out; 
  873.     dfFrench->format(testDate, out);
  874.     logln((UnicodeString)"Date Formated with French Locale " + out);
  875.     if (!(out == expectedFRENCH))
  876.         errln((UnicodeString)"FAIL: Expected " + expectedFRENCH);
  877.     out.truncate(0);
  878.     dfUS->format(testDate, out);
  879.     logln((UnicodeString)"Date Formated with US Locale " + out);
  880.     if (!(out == expectedUS))
  881.         errln((UnicodeString)"FAIL: Expected " + expectedUS);
  882.     delete dfUS;
  883.     delete dfFrench;
  884. }
  885.  
  886. //eof
  887.