ICU-2895 Relative Dates

X-SVN-Rev: 21381
This commit is contained in:
Steven R. Loomis 2007-04-09 22:29:57 +00:00
parent 28338fd1d6
commit d48f7af250
7 changed files with 176 additions and 2 deletions

View file

@ -62,7 +62,7 @@ LIBS = $(LIBICUUC) $(DEFAULT_LIBS)
OBJECTS = ucln_in.o \
fmtable.o format.o msgfmt.o umsg.o numfmt.o unum.o decimfmt.o dcfmtsym.o \
ucurr.o digitlst.o fmtable_cnv.o \
choicfmt.o datefmt.o smpdtfmt.o dtfmtsym.o udat.o \
choicfmt.o datefmt.o smpdtfmt.o reldtfmt.o dtfmtsym.o udat.o \
nfrs.o nfrule.o nfsubs.o rbnf.o ucsdet.o \
ucal.o calendar.o gregocal.o timezone.o simpletz.o olsontz.o \
astro.o buddhcal.o persncal.o islamcal.o japancal.o gregoimp.o hebrwcal.o \

View file

@ -24,6 +24,7 @@
#include "unicode/ures.h"
#include "unicode/datefmt.h"
#include "unicode/smpdtfmt.h"
#include "reldtfmt.h"
#include "cstring.h"
#include "windtfmt.h"
@ -287,6 +288,13 @@ DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale)
}
#endif
// is it relative?
if(/*((timeStyle!=UDAT_NONE)&&(timeStyle & UDAT_RELATIVE)) || */((dateStyle!=(UDateFormatStyle)UDAT_NONE)&&((dateStyle-kDateOffset) & UDAT_RELATIVE))) {
RelativeDateFormat *r = new RelativeDateFormat((UDateFormatStyle)timeStyle, (UDateFormatStyle)(dateStyle-kDateOffset), locale, status);
if(U_SUCCESS(status)) return r;
delete r;
status = U_ZERO_ERROR;
}
// Try to create a SimpleDateFormat of the desired style.
SimpleDateFormat *f = new SimpleDateFormat(timeStyle, dateStyle, locale, status);

View file

@ -1139,6 +1139,13 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\reldtfmt.cpp"
>
</File>
<File
RelativePath=".\reldtfmt.h"
</File>
<File
RelativePath=".\timezone.cpp"
>

View file

@ -160,6 +160,19 @@ public:
// kShort + kDateOffset = 7
kDateTime = 8,
// relative dates
kRelative = (1 << 7),
kFullRelative = (kFull | kRelative),
kLongRelative = kLong | kRelative,
kMediumRelative = kMedium | kRelative,
kShortRelative = kShort | kRelative,
kDefault = kMedium,

View file

@ -151,6 +151,19 @@ typedef enum UDateFormatStyle {
UDAT_SHORT,
/** Default style */
UDAT_DEFAULT = UDAT_MEDIUM,
/** Bitfield for relative date */
UDAT_RELATIVE = (1 << 7),
UDAT_FULL_RELATIVE = UDAT_FULL | UDAT_RELATIVE,
UDAT_LONG_RELATIVE = UDAT_LONG | UDAT_RELATIVE,
UDAT_MEDIUM_RELATIVE = UDAT_MEDIUM | UDAT_RELATIVE,
UDAT_SHORT_RELATIVE = UDAT_SHORT | UDAT_RELATIVE,
/** No style */
UDAT_NONE = -1,
/** for internal API use only */

View file

@ -19,6 +19,7 @@
#include "cmemory.h"
#include "cstring.h"
#include "caltest.h" // for fieldName
#include <stdio.h> // for sprintf
#ifdef U_WINDOWS
#include "windttst.h"
@ -26,7 +27,7 @@
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
#define ASSERT_OK(status) if(U_FAILURE(status)) {errln(#status " = %s", u_errorName(status)); return; }
#define ASSERT_OK(status) if(U_FAILURE(status)) {errln(#status " = %s @ %s:%d", u_errorName(status), __FILE__, __LINE__); return; }
//--------------------------------------------------------------------
// Time bomb - allows temporary behavior that expires at a given
@ -76,6 +77,11 @@ void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &nam
TESTCASE(31,TestStandAloneMonths);
TESTCASE(32,TestQuarters);
TESTCASE(33,TestZTimeZoneParsing);
TESTCASE(34,TestRelative);
/*
TESTCASE(35,TestRelativeError);
TESTCASE(36,TestRelativeOther);
*/
default: name = ""; break;
}
}
@ -1966,6 +1972,119 @@ void DateFormatTest::TestHost(void)
#endif
}
// Relative Date Tests
void DateFormatTest::TestRelative(int daysdelta,
const Locale& loc,
const char *expectChars) {
char banner[25];
sprintf(banner, "%d", daysdelta);
UnicodeString bannerStr(banner, "");
UErrorCode status = U_ZERO_ERROR;
FieldPosition pos(0);
UnicodeString test;
Locale en("en");
DateFormat *fullrelative = DateFormat::createDateInstance(DateFormat::kFullRelative, loc);
DateFormat *full = DateFormat::createDateInstance(DateFormat::kFull , loc);
DateFormat *en_full = DateFormat::createDateInstance(DateFormat::kFull, en);
DateFormat *en_fulltime = DateFormat::createDateTimeInstance(DateFormat::kFull,DateFormat::kFull,en);
UnicodeString result;
UnicodeString normalResult;
UnicodeString expect;
UnicodeString parseResult;
Calendar *c = Calendar::createInstance(status);
// Today = Today
c->setTime(Calendar::getNow(), status);
if(daysdelta != 0) {
c->add(Calendar::DATE,daysdelta,status);
}
ASSERT_OK(status);
// calculate the expected string
if(expectChars != NULL) {
expect = expectChars;
} else {
full->format(*c, expect, pos); // expected = normal full
}
fullrelative ->format(*c, result, pos);
en_full ->format(*c, normalResult, pos);
if(result != expect) {
errln("FAIL: Relative Format ["+bannerStr+"] of "+normalResult+" failed, expected "+expect+" but got " + result);
} else {
logln("PASS: Relative Format ["+bannerStr+"] of "+normalResult+" got " + result);
}
//verify
UDate d = fullrelative->parse(result, status);
ASSERT_OK(status);
UnicodeString parseFormat; // parse rel->format full
en_full->format(d, parseFormat, status);
UnicodeString origFormat;
en_full->format(*c, origFormat, pos);
if(parseFormat!=origFormat) {
errln("FAIL: Relative Parse ["+bannerStr+"] of "+result+" failed, expected "+parseFormat+" but got "+origFormat);
} else {
logln("PASS: Relative Parse ["+bannerStr+"] of "+result+" passed, got "+parseFormat);
}
delete full;
delete fullrelative;
delete en_fulltime;
delete en_full;
delete c;
}
void DateFormatTest::TestRelative(void)
{
Locale en("en");
TestRelative( 0, en, "Today");
TestRelative(-1, en, "Yesterday");
TestRelative( 1, en, "Tomorrow");
TestRelative( 2, en, NULL);
TestRelative( -2, en, NULL);
TestRelative( 3, en, NULL);
TestRelative( -3, en, NULL);
TestRelative( 300, en, NULL);
TestRelative( -300, en, NULL);
}
/*
void DateFormatTest::TestRelativeError(void)
{
UErrorCode status;
Locale en("en");
DateFormat *en_reltime_reldate = DateFormat::createDateTimeInstance(DateFormat::kFullRelative,DateFormat::kFullRelative,en);
if(en_reltime_reldate == NULL) {
logln("PASS: rel date/rel time failed");
} else {
errln("FAIL: rel date/rel time created, should have failed.");
delete en_reltime_reldate;
}
}
void DateFormatTest::TestRelativeOther(void)
{
logln("Nothing in this test. When we get more data from CLDR, put in some tests of -2, +2, etc. ");
}
*/
#endif /* #if !UCONFIG_NO_FORMATTING */
//eof

View file

@ -180,6 +180,20 @@ public:
void TestQuarters(void);
void TestZTimeZoneParsing(void);
public:
/***
* Test Relative Dates
*/
void TestRelative(void);
/* void TestRelativeError(void);
void TestRelativeOther(void);
*/
private:
void TestRelative(int daysdelta,
const Locale& loc,
const char *expectChars);
private:
void expectParse(const char** data, int32_t data_length,