blob: df7d7f1c04a4973b135ed19ecca7beda8b8067c7 [file] [log] [blame]
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2001, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
#include "callimts.h"
#include "unicode/calendar.h"
#include "unicode/gregocal.h"
#include "unicode/datefmt.h"
#include "unicode/smpdtfmt.h"
U_NAMESPACE_USE
void CalendarLimitTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
if (exec) logln("TestSuite TestCalendarLimit");
switch (index) {
// Re-enable this later
case 0:
name = "TestCalendarLimit";
if (exec) {
logln("TestCalendarLimit---"); logln("");
TestCalendarLimit();
}
break;
default: name = ""; break;
}
}
// *****************************************************************************
// class CalendarLimitTest
// *****************************************************************************
// -------------------------------------
void
CalendarLimitTest::test(UDate millis, U_NAMESPACE_QUALIFIER Calendar* cal, U_NAMESPACE_QUALIFIER DateFormat* fmt)
{
UErrorCode exception = U_ZERO_ERROR;
UnicodeString theDate;
UErrorCode status = U_ZERO_ERROR;
cal->setTime(millis, exception);
if (U_SUCCESS(exception)) {
fmt->format(millis, theDate);
UDate dt = fmt->parse(theDate, status);
// allow a small amount of error (drift)
if(! withinErr(dt, millis, 1e-10))
errln(UnicodeString("FAIL:round trip for large milli, got: ") + dt + " wanted: " + millis);
else {
logln(UnicodeString("OK: got ") + dt + ", wanted " + millis);
logln(UnicodeString(" ") + theDate);
}
}
}
// -------------------------------------
// bug 986c: deprecate nextDouble/previousDouble
//|double
//|CalendarLimitTest::nextDouble(double a)
//|{
//| return uprv_nextDouble(a, TRUE);
//|}
//|
//|double
//|CalendarLimitTest::previousDouble(double a)
//|{
//| return uprv_nextDouble(a, FALSE);
//|}
UBool
CalendarLimitTest::withinErr(double a, double b, double err)
{
return ( uprv_fabs(a - b) < uprv_fabs(a * err) );
}
void
CalendarLimitTest::TestCalendarLimit()
{
UErrorCode status = U_ZERO_ERROR;
Calendar *cal = Calendar::createInstance(status);
if (failure(status, "Calendar::createInstance")) return;
cal->adoptTimeZone(TimeZone::createTimeZone("GMT"));
DateFormat *fmt = DateFormat::createDateTimeInstance();
fmt->adoptCalendar(cal);
((SimpleDateFormat*) fmt)->applyPattern("HH:mm:ss.SSS zzz, EEEE, MMMM d, yyyy G");
// This test used to test the algorithmic limits of the dates that
// GregorianCalendar could handle. However, the algorithm has
// been rewritten completely since then and the prior limits no
// longer apply. Instead, we now do basic round-trip testing of
// some extreme (but still manageable) dates.
UDate m;
for ( m = 1e17; m < 1e18; m *= 1.1) {
test(m, cal, fmt);
}
for ( m = -1e14; m > -1e15; m *= 1.1) {
test(m, cal, fmt);
}
// This is 2^52 - 1, the largest allowable mantissa with a 0
// exponent in a 64-bit double
UDate VERY_EARLY_MILLIS = - 4503599627370495.0;
UDate VERY_LATE_MILLIS = 4503599627370495.0;
// I am removing the previousDouble and nextDouble calls below for
// two reasons: 1. As part of jitterbug 986, I am deprecating
// these methods and removing calls to them. 2. This test is a
// non-critical boundary behavior test.
test(VERY_EARLY_MILLIS, cal, fmt);
//test(previousDouble(VERY_EARLY_MILLIS), cal, fmt);
test(VERY_LATE_MILLIS, cal, fmt);
//test(nextDouble(VERY_LATE_MILLIS), cal, fmt);
delete fmt;
}
// -------------------------------------
// eof