• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***********************************************************************
2  * COPYRIGHT:
3  * Copyright (c) 1997-2006, International Business Machines Corporation
4  * and others. All Rights Reserved.
5  ***********************************************************************/
6 
7 #include "unicode/utypes.h"
8 
9 #if !UCONFIG_NO_FORMATTING
10 
11 #include "callimts.h"
12 #include "caltest.h"
13 #include "unicode/calendar.h"
14 #include "unicode/gregocal.h"
15 #include "unicode/datefmt.h"
16 #include "unicode/smpdtfmt.h"
17 #include "putilimp.h"
18 
19 U_NAMESPACE_USE
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)20 void CalendarLimitTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
21 {
22     if (exec) logln("TestSuite TestCalendarLimit");
23     switch (index) {
24         // Re-enable this later
25         case 0:
26             name = "TestCalendarLimit";
27             if (exec) {
28                 logln("TestCalendarLimit---"); logln("");
29                 TestCalendarLimit();
30             }
31             break;
32         default: name = ""; break;
33     }
34 }
35 
36 
37 // *****************************************************************************
38 // class CalendarLimitTest
39 // *****************************************************************************
40 
41 // -------------------------------------
42 void
test(UDate millis,U_NAMESPACE_QUALIFIER Calendar * cal,U_NAMESPACE_QUALIFIER DateFormat * fmt)43 CalendarLimitTest::test(UDate millis, U_NAMESPACE_QUALIFIER Calendar* cal, U_NAMESPACE_QUALIFIER DateFormat* fmt)
44 {
45   static const UDate kDrift = 1e-10;
46     UErrorCode exception = U_ZERO_ERROR;
47     UnicodeString theDate;
48     UErrorCode status = U_ZERO_ERROR;
49     cal->setTime(millis, exception);
50     if (U_SUCCESS(exception)) {
51         fmt->format(millis, theDate);
52         UDate dt = fmt->parse(theDate, status);
53         // allow a small amount of error (drift)
54         if(! withinErr(dt, millis, kDrift)) {
55           errln("FAIL:round trip for large milli, got: %.1lf wanted: %.1lf. (delta %.2lf greater than %.2lf)",
56                 dt, millis, uprv_fabs(millis-dt), uprv_fabs(dt*kDrift));
57           logln(UnicodeString("   ") + theDate + " " + CalendarTest::calToStr(*cal));
58           } else {
59             logln(UnicodeString("OK: got ") + dt + ", wanted " + millis);
60             logln(UnicodeString("    ") + theDate);
61         }
62     }
63 }
64 
65 // -------------------------------------
66 
67 // bug 986c: deprecate nextDouble/previousDouble
68 //|double
69 //|CalendarLimitTest::nextDouble(double a)
70 //|{
71 //|    return uprv_nextDouble(a, TRUE);
72 //|}
73 //|
74 //|double
75 //|CalendarLimitTest::previousDouble(double a)
76 //|{
77 //|    return uprv_nextDouble(a, FALSE);
78 //|}
79 
80 UBool
withinErr(double a,double b,double err)81 CalendarLimitTest::withinErr(double a, double b, double err)
82 {
83     return ( uprv_fabs(a - b) < uprv_fabs(a * err) );
84 }
85 
86 void
TestCalendarLimit()87 CalendarLimitTest::TestCalendarLimit()
88 {
89     UErrorCode status = U_ZERO_ERROR;
90     Calendar *cal = Calendar::createInstance(status);
91     if (failure(status, "Calendar::createInstance")) return;
92     cal->adoptTimeZone(TimeZone::createTimeZone("GMT"));
93     DateFormat *fmt = DateFormat::createDateTimeInstance();
94     if(!fmt || !cal) {
95        dataerrln("can't open cal and/or fmt");
96        return;
97     }
98     fmt->adoptCalendar(cal);
99     ((SimpleDateFormat*) fmt)->applyPattern("HH:mm:ss.SSS zzz, EEEE, MMMM d, yyyy G");
100 
101 
102     // This test used to test the algorithmic limits of the dates that
103     // GregorianCalendar could handle.  However, the algorithm has
104     // been rewritten completely since then and the prior limits no
105     // longer apply.  Instead, we now do basic round-trip testing of
106     // some extreme (but still manageable) dates.
107     UDate m;
108     logln("checking 1e16..1e17");
109     for ( m = 1e16; m < 1e17; m *= 1.1) {
110         test(m, cal, fmt);
111     }
112     logln("checking -1e14..-1e15");
113     for ( m = -1e14; m > -1e15; m *= 1.1) {
114         test(m, cal, fmt);
115     }
116 
117     // This is 2^52 - 1, the largest allowable mantissa with a 0
118     // exponent in a 64-bit double
119     UDate VERY_EARLY_MILLIS = - 4503599627370495.0;
120     UDate VERY_LATE_MILLIS  =   4503599627370495.0;
121 
122     // I am removing the previousDouble and nextDouble calls below for
123     // two reasons: 1. As part of jitterbug 986, I am deprecating
124     // these methods and removing calls to them.  2. This test is a
125     // non-critical boundary behavior test.
126     test(VERY_EARLY_MILLIS, cal, fmt);
127     //test(previousDouble(VERY_EARLY_MILLIS), cal, fmt);
128     test(VERY_LATE_MILLIS, cal, fmt);
129     //test(nextDouble(VERY_LATE_MILLIS), cal, fmt);
130     delete fmt;
131 }
132 
133 #endif /* #if !UCONFIG_NO_FORMATTING */
134 
135 // eof
136