ICU-5787 merge from feature branch revision 22024:22252.

X-SVN-Rev: 22260
This commit is contained in:
Claire Ho 2007-08-03 18:43:04 +00:00
parent c68a28f9ee
commit efe2014ed1
16 changed files with 4284 additions and 5 deletions

View file

@ -64,7 +64,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 reldtfmt.o dtfmtsym.o udat.o \
choicfmt.o datefmt.o smpdtfmt.o reldtfmt.o dtfmtsym.o udat.o dtptngen.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 taiwncal.o buddhcal.o persncal.o islamcal.o japancal.o gregoimp.o hebrwcal.o indiancal.o \
@ -75,7 +75,7 @@ translit.o utrans.o esctrn.o unesctrn.o funcrepl.o strrepl.o tridpars.o \
cpdtrans.o rbt.o rbt_data.o rbt_pars.o rbt_rule.o rbt_set.o \
nultrans.o remtrans.o casetrn.o titletrn.o tolowtrn.o toupptrn.o anytrans.o \
name2uni.o uni2name.o nortrans.o quant.o transreg.o \
regexcmp.o rematch.o repattrn.o regexst.o uregex.o uregexc.o \
regexcmp.o rematch.o repattrn.o regexst.o udatpg.o uregex.o uregexc.o \
ulocdata.o measfmt.o currfmt.o curramt.o currunit.o measure.o utmscale.o \
csdetect.o csmatch.o csr2022.o csrecog.o csrmbcs.o csrsbcs.o csrucode.o csrutf8.o inputext.o \
windtfmt.o winnmfmt.o basictz.o dtrule.o rbtz.o tzrule.o tztrans.o vtzone.o

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,381 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and
* others. All Rights Reserved. *
*******************************************************************************
*
* File DTPTNGEN.H
*
*******************************************************************************
*/
#include "uvector.h"
#ifndef __DTPTNGEN_IMPL_H__
#define __DTPTNGEN_IMPL_H__
// TODO(claireho): Split off Builder class.
// TODO(claireho): If splitting off Builder class: As subclass or independent?
#define MAX_PATTERN_ENTRIES 52
#define MAX_CLDR_FIELD_LEN 60
#define MAX_DT_TOKEN 50
#define MAX_RESOURCE_FIELD 11
#define MAX_AVAILABLE_FORMATS 12
#define NONE 0
#define EXTRA_FIELD 0x10000
#define MISSING_FIELD 0x1000
#define MAX_STRING_ENUMERATION 200
#define SINGLE_QUOTE ((UChar)0x0027)
#define FORWARDSLASH ((UChar)0x002F)
#define BACKSLASH ((UChar)0x005C)
#define SPACE ((UChar)0x0020)
#define QUOTATION_MARK ((UChar)0x0022)
#define ASTERISK ((UChar)0x002A)
#define PLUSSITN ((UChar)0x002B)
#define COMMA ((UChar)0x002C)
#define HYPHEN ((UChar)0x002D)
#define DOT ((UChar)0x002E)
#define COLON ((UChar)0x003A)
#define CAP_A ((UChar)0x0041)
#define CAP_C ((UChar)0x0043)
#define CAP_D ((UChar)0x0044)
#define CAP_E ((UChar)0x0045)
#define CAP_F ((UChar)0x0046)
#define CAP_G ((UChar)0x0047)
#define CAP_H ((UChar)0x0048)
#define CAP_L ((UChar)0x004C)
#define CAP_M ((UChar)0x004D)
#define CAP_O ((UChar)0x004F)
#define CAP_Q ((UChar)0x0051)
#define CAP_S ((UChar)0x0053)
#define CAP_T ((UChar)0x0054)
#define CAP_V ((UChar)0x0056)
#define CAP_W ((UChar)0x0057)
#define CAP_Y ((UChar)0x0059)
#define CAP_Z ((UChar)0x005A)
#define LOWLINE ((UChar)0x005F)
#define LOW_A ((UChar)0x0061)
#define LOW_C ((UChar)0x0063)
#define LOW_D ((UChar)0x0064)
#define LOW_E ((UChar)0x0065)
#define LOW_F ((UChar)0x0066)
#define LOW_G ((UChar)0x0067)
#define LOW_H ((UChar)0x0068)
#define LOW_I ((UChar)0x0069)
#define LOW_K ((UChar)0x006B)
#define LOW_L ((UChar)0x006C)
#define LOW_M ((UChar)0x006D)
#define LOW_N ((UChar)0x006E)
#define LOW_O ((UChar)0x006F)
#define LOW_P ((UChar)0x0070)
#define LOW_Q ((UChar)0x0071)
#define LOW_R ((UChar)0x0072)
#define LOW_S ((UChar)0x0073)
#define LOW_T ((UChar)0x0074)
#define LOW_U ((UChar)0x0075)
#define LOW_V ((UChar)0x0076)
#define LOW_W ((UChar)0x0077)
#define LOW_Y ((UChar)0x0079)
#define LOW_Z ((UChar)0x007A)
#define DT_SHORT -0x101
#define DT_LONG -0x102
#define DT_NUMERIC 0x100
#define DT_NARROW -0x100
#define DT_DELTA 0x10
U_NAMESPACE_BEGIN
const int32_t UDATPG_FRACTIONAL_MASK = 1<<UDATPG_FRACTIONAL_SECOND_FIELD;
const int32_t UDATPG_SECOND_AND_FRACTIONAL_MASK = (1<<UDATPG_SECOND_FIELD) | (1<<UDATPG_FRACTIONAL_SECOND_FIELD);
typedef enum dtStrEnum {
DT_BASESKELETON,
DT_SKELETON,
DT_PATTERN,
}dtStrEnum ;
typedef struct dtTypeElem {
UChar patternChar;
UDateTimePatternField field;
int32_t type;
int32_t minLen;
int32_t weight;
}dtTypeElem;
class U_I18N_API PtnSkeleton : public UObject {
public:
int32_t type[UDATPG_FIELD_COUNT];
UnicodeString original[UDATPG_FIELD_COUNT];
UnicodeString baseOriginal[UDATPG_FIELD_COUNT];
PtnSkeleton();
PtnSkeleton(PtnSkeleton& other);
UBool equals(PtnSkeleton& other);
UnicodeString getSkeleton();
virtual ~PtnSkeleton();
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 3.8
*
*/
static UClassID U_EXPORT2 getStaticClassID(void);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @draft ICU 3.8
*/
virtual UClassID getDynamicClassID() const;
};
class U_I18N_API PtnElem : public UObject {
public:
UnicodeString *basePattern;
PtnSkeleton *skeleton;
UnicodeString *pattern;
PtnElem *next;
PtnElem();
virtual ~PtnElem();
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 3.8
*
*/
static UClassID U_EXPORT2 getStaticClassID(void);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @draft ICU 3.8
*/
virtual UClassID getDynamicClassID() const;
};
class U_I18N_API FormatParser : public UObject{
public:
UnicodeString items[MAX_DT_TOKEN];
int32_t itemNumber;
FormatParser();
virtual ~FormatParser();
/**
* Set the string to parse
* @param string
* @return this, for chaining
* @deprecated
* @internal
*/
void set(const UnicodeString& patternString);
/**
* Check string 's' is a quoted literal
* @param string with quoted literals
* @param starting index of items and return the next index of items of end quoted literal
* @return TRUE if s is a quote literal, FALSE if s is not a quote literal.
* @deprecated
* @internal
*/
UBool isQuoteLiteral(UnicodeString s);
/**
* produce a quoted literal
* @param string with quoted literals
* @param starting index of items and return the next index of items of end quoted literal
* @return none
* @deprecated
* @internal
*/
void getQuoteLiteral(UnicodeString& quote, int32_t *itemIndex);
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 3.8
*
*/
static UClassID U_EXPORT2 getStaticClassID(void);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @draft ICU 3.8
*/
virtual UClassID getDynamicClassID() const;
int32_t getCanonicalIndex(const UnicodeString& s);
UBool isPatternSeparator(UnicodeString& field);
void setFilter(UErrorCode &status);
private:
typedef enum TokenStatus {
START,
ADD_TOKEN,
SYNTAX_ERROR,
DONE
} ToeknStatus;
TokenStatus status;
UnicodeSet *quoteFilter;
virtual TokenStatus setTokens(const UnicodeString& pattern, int32_t startPos, int32_t *len);
};
class U_I18N_API DistanceInfo : public UObject {
public:
int32_t missingFieldMask;
int32_t extraFieldMask;
DistanceInfo() {};
virtual ~DistanceInfo() {};
void clear() { missingFieldMask = extraFieldMask = 0; };
void setTo(DistanceInfo& other);
void addMissing(int32_t field) { missingFieldMask |= (1<<field); };
void addExtra(int32_t field) { extraFieldMask |= (1<<field); };
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 3.8
*
*/
static UClassID U_EXPORT2 getStaticClassID(void);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @draft ICU 3.8
*/
virtual UClassID getDynamicClassID() const;
};
class U_I18N_API DateTimeMatcher: public UObject {
public:
PtnSkeleton skeleton;
void getBasePattern(UnicodeString &basePattern);
UnicodeString getPattern();
void set(const UnicodeString& pattern, FormatParser* fp);
void set(const UnicodeString& pattern, FormatParser* fp, PtnSkeleton& skeleton);
void copyFrom(PtnSkeleton& skeleton);
void copyFrom();
PtnSkeleton* getSkeletonPtr();
UBool equals(DateTimeMatcher* other);
int32_t getDistance(DateTimeMatcher& other, int32_t includeMask, DistanceInfo& distanceInfo);
DateTimeMatcher();
virtual ~DateTimeMatcher() {};
int32_t getFieldMask();
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 3.8
*/
static UClassID U_EXPORT2 getStaticClassID();
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @draft ICU 3.8
*/
virtual UClassID getDynamicClassID() const;
};
class U_I18N_API PatternMap : public UObject{
public:
PtnElem *boot[MAX_PATTERN_ENTRIES];
PatternMap();
virtual ~PatternMap();
void add(const UnicodeString& basePattern, const PtnSkeleton& skeleton, const UnicodeString& value, UErrorCode& status);
UErrorCode status;
UnicodeString* getPatternFromBasePattern(UnicodeString& basePattern);
UnicodeString* getPatternFromSkeleton(PtnSkeleton& skeleton);
void copyFrom(const PatternMap& other, UErrorCode& status);
UBool equals(const PatternMap& other);
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 3.8
*
*/
static UClassID U_EXPORT2 getStaticClassID(void);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @draft ICU 3.8
*/
virtual UClassID getDynamicClassID() const;
private:
UBool isDupAllowed;
PtnElem* getDuplicateElem(const UnicodeString &basePattern, const PtnSkeleton& skeleton, PtnElem *baseElem);
}; // end PatternMap
class U_I18N_API PatternMapIterator : public UObject {
public:
PatternMapIterator();
virtual ~PatternMapIterator();
void set(PatternMap& patternMap);
PtnSkeleton* getSkeleton();
UBool hasNext();
DateTimeMatcher& next();
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 3.8
*
*/
static UClassID U_EXPORT2 getStaticClassID(void);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @draft ICU 3.8
*/
virtual UClassID getDynamicClassID() const;
private:
int32_t bootIndex;
PtnElem *nodePtr;
DateTimeMatcher *matcher;
PatternMap *patternMap;
};
class U_I18N_API DTSkeletonEnumeration : public StringEnumeration {
public:
DTSkeletonEnumeration(PatternMap &patternMap, dtStrEnum type, UErrorCode& status);
virtual ~DTSkeletonEnumeration();
static UClassID U_EXPORT2 getStaticClassID(void);
virtual UClassID getDynamicClassID(void) const;
virtual const UnicodeString* snext(UErrorCode& status);
virtual void reset(UErrorCode& status);
virtual int32_t count(UErrorCode& status) const;
private:
int32_t pos;
UBool isCanonicalItem(const UnicodeString& item);
UVector *fSkeletons;
};
class U_I18N_API DTRedundantEnumeration : public StringEnumeration {
public:
DTRedundantEnumeration();
virtual ~DTRedundantEnumeration();
static UClassID U_EXPORT2 getStaticClassID(void);
virtual UClassID getDynamicClassID(void) const;
virtual const UnicodeString* snext(UErrorCode& status);
virtual void reset(UErrorCode& status);
virtual int32_t count(UErrorCode& status) const;
void add(const UnicodeString &pattern, UErrorCode& status);
private:
int32_t pos;
UBool isCanonicalItem(const UnicodeString& item);
UVector *fPatterns;
};
U_NAMESPACE_END
#endif

View file

@ -762,6 +762,36 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\dtptngen.cpp"
>
</File>
<File
RelativePath=".\unicode\dtptngen.h"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
Outputs="..\..\include\unicode\$(InputFileName)"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
Outputs="..\..\include\unicode\$(InputFileName)"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\dtptngen_impl.h"
>
</File>
<File
RelativePath=".\dtrule.cpp"
>
@ -1310,6 +1340,32 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\udatpg.cpp"
>
</File>
<File
RelativePath=".\unicode\udatpg.h"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
Outputs="..\..\include\unicode\$(InputFileName)"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
CommandLine="copy &quot;$(InputPath)&quot; ..\..\include\unicode&#x0D;&#x0A;"
Outputs="..\..\include\unicode\$(InputFileName)"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\ulocdata.c"
>

View file

@ -0,0 +1,248 @@
/*
*******************************************************************************
*
* Copyright (C) 2007, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: udatpg.cpp
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2007jul30
* created by: Markus W. Scherer
*/
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "unicode/udatpg.h"
#include "unicode/uenum.h"
#include "unicode/strenum.h"
#include "unicode/dtptngen.h"
#include "ustrenum.h"
U_NAMESPACE_USE
U_DRAFT UDateTimePatternGenerator * U_EXPORT2
udatpg_open(const char *locale, UErrorCode *pErrorCode) {
if(locale==NULL) {
return (UDateTimePatternGenerator *)DateTimePatternGenerator::createInstance(*pErrorCode);
} else {
return (UDateTimePatternGenerator *)DateTimePatternGenerator::createInstance(Locale(locale), *pErrorCode);
}
}
U_DRAFT UDateTimePatternGenerator * U_EXPORT2
udatpg_openEmpty(UErrorCode *pErrorCode) {
return (UDateTimePatternGenerator *)DateTimePatternGenerator::createEmptyInstance(*pErrorCode);
}
U_DRAFT void U_EXPORT2
udatpg_close(UDateTimePatternGenerator *dtpg) {
delete (DateTimePatternGenerator *)dtpg;
}
U_DRAFT UDateTimePatternGenerator * U_EXPORT2
udatpg_clone(const UDateTimePatternGenerator *dtpg, UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return NULL;
}
return (UDateTimePatternGenerator *)(((const DateTimePatternGenerator *)dtpg)->clone());
}
U_DRAFT int32_t U_EXPORT2
udatpg_getBestPattern(UDateTimePatternGenerator *dtpg,
const UChar *skeleton, int32_t length,
UChar *bestPattern, int32_t capacity,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return 0;
}
if(skeleton==NULL && length!=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString skeletonString((UBool)(length<0), skeleton, length);
UnicodeString result=((DateTimePatternGenerator *)dtpg)->getBestPattern(skeletonString, *pErrorCode);
return result.extract(bestPattern, capacity, *pErrorCode);
}
U_DRAFT int32_t U_EXPORT2
udatpg_getSkeleton(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t length,
UChar *skeleton, int32_t capacity,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return 0;
}
if(pattern==NULL && length!=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString patternString((UBool)(length<0), pattern, length);
UnicodeString result=((DateTimePatternGenerator *)dtpg)->getSkeleton(patternString, *pErrorCode);
return result.extract(skeleton, capacity, *pErrorCode);
}
U_DRAFT int32_t U_EXPORT2
udatpg_getBaseSkeleton(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t length,
UChar *skeleton, int32_t capacity,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return 0;
}
if(pattern==NULL && length!=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString patternString((UBool)(length<0), pattern, length);
UnicodeString result=((DateTimePatternGenerator *)dtpg)->getBaseSkeleton(patternString, *pErrorCode);
return result.extract(skeleton, capacity, *pErrorCode);
}
U_DRAFT UDateTimePatternConflict U_EXPORT2
udatpg_addPattern(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t patternLength,
UBool override,
UChar *conflictingPattern, int32_t capacity, int32_t *pLength,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return UDATPG_NO_CONFLICT;
}
if(pattern==NULL && patternLength!=0) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return UDATPG_NO_CONFLICT;
}
UnicodeString patternString((UBool)(patternLength<0), pattern, patternLength);
UnicodeString conflictingPatternString;
UDateTimePatternConflict result=((DateTimePatternGenerator *)dtpg)->
addPattern(patternString, override, conflictingPatternString, *pErrorCode);
int32_t length=conflictingPatternString.extract(conflictingPattern, capacity, *pErrorCode);
if(pLength!=NULL) {
*pLength=length;
}
return result;
}
U_DRAFT void U_EXPORT2
udatpg_setAppendItemFormat(UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
const UChar *value, int32_t length) {
UnicodeString valueString((UBool)(length<0), value, length);
((DateTimePatternGenerator *)dtpg)->setAppendItemFormat(field, valueString);
}
U_DRAFT const UChar * U_EXPORT2
udatpg_getAppendItemFormat(const UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
int32_t *pLength) {
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getAppendItemFormat(field);
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
U_DRAFT void U_EXPORT2
udatpg_setAppendItemName(UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
const UChar *value, int32_t length) {
UnicodeString valueString((UBool)(length<0), value, length);
((DateTimePatternGenerator *)dtpg)->setAppendItemName(field, valueString);
}
U_DRAFT const UChar * U_EXPORT2
udatpg_getAppendItemName(const UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
int32_t *pLength) {
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getAppendItemName(field);
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
U_DRAFT void U_EXPORT2
udatpg_setDateTimeFormat(const UDateTimePatternGenerator *dtpg,
const UChar *dtFormat, int32_t length) {
UnicodeString dtFormatString((UBool)(length<0), dtFormat, length);
((DateTimePatternGenerator *)dtpg)->setDateTimeFormat(dtFormatString);
}
U_DRAFT const UChar * U_EXPORT2
udatpg_getDateTimeFormat(const UDateTimePatternGenerator *dtpg,
int32_t *pLength) {
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getDateTimeFormat();
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
U_DRAFT void U_EXPORT2
udatpg_setDecimal(UDateTimePatternGenerator *dtpg,
const UChar *decimal, int32_t length) {
UnicodeString decimalString((UBool)(length<0), decimal, length);
((DateTimePatternGenerator *)dtpg)->setDecimal(decimalString);
}
U_DRAFT const UChar * U_EXPORT2
udatpg_getDecimal(const UDateTimePatternGenerator *dtpg,
int32_t *pLength) {
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getDecimal();
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
U_DRAFT int32_t U_EXPORT2
udatpg_replaceFieldTypes(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t patternLength,
const UChar *skeleton, int32_t skeletonLength,
UChar *dest, int32_t destCapacity,
UErrorCode *pErrorCode) {
if(U_FAILURE(*pErrorCode)) {
return 0;
}
if((pattern==NULL && patternLength!=0) || (skeleton==NULL && skeletonLength!=0)) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
UnicodeString patternString((UBool)(patternLength<0), pattern, patternLength);
UnicodeString skeletonString((UBool)(skeletonLength<0), skeleton, skeletonLength);
UnicodeString result=((DateTimePatternGenerator *)dtpg)->replaceFieldTypes(patternString, skeletonString, *pErrorCode);
return result.extract(dest, destCapacity, *pErrorCode);
}
U_DRAFT UEnumeration * U_EXPORT2
udatpg_openSkeletons(const UDateTimePatternGenerator *dtpg, UErrorCode *pErrorCode) {
return uenum_openStringEnumeration(
((DateTimePatternGenerator *)dtpg)->getSkeletons(*pErrorCode),
pErrorCode);
}
U_DRAFT UEnumeration * U_EXPORT2
udatpg_openBaseSkeletons(const UDateTimePatternGenerator *dtpg, UErrorCode *pErrorCode) {
return uenum_openStringEnumeration(
((DateTimePatternGenerator *)dtpg)->getBaseSkeletons(*pErrorCode),
pErrorCode);
}
U_DRAFT const UChar * U_EXPORT2
udatpg_getPatternForSkeleton(const UDateTimePatternGenerator *dtpg,
const UChar *skeleton, int32_t skeletonLength,
int32_t *pLength) {
UnicodeString skeletonString((UBool)(skeletonLength<0), skeleton, skeletonLength);
const UnicodeString &result=((const DateTimePatternGenerator *)dtpg)->getPatternForSkeleton(skeletonString);
if(pLength!=NULL) {
*pLength=result.length();
}
return result.getBuffer();
}
#endif

View file

@ -0,0 +1,413 @@
/*
*******************************************************************************
* Copyright (C) 2007, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
* File DTPTNGEN.H
*
*******************************************************************************
*/
#ifndef __DTPTNGEN_H__
#define __DTPTNGEN_H__
#include "unicode/utypes.h"
#include "unicode/format.h"
#include "unicode/datefmt.h"
#include "unicode/calendar.h"
#include "unicode/ustring.h"
#include "unicode/locid.h"
#include "unicode/udat.h"
#include "unicode/udatpg.h"
#include "unicode/uniset.h"
U_NAMESPACE_BEGIN
class DateFormatSymbols;
class DateFormat;
class Hashtable;
class FormatParser;
class DateTimeMatcher;
class DistanceInfo;
class PatternMap;
/**
* This class provides flexible generation of date format patterns, like "yy-MM-dd".
* The user can build up the generator by adding successive patterns. Once that
* is done, a query can be made using a "skeleton", which is a pattern which just
* includes the desired fields and lengths. The generator will return the "best fit"
* pattern corresponding to that skeleton.
* <p>The main method people will use is getBestPattern(String skeleton),
* since normally this class is pre-built with data from a particular locale.
* However, generators can be built directly from other data as well.
* <p><i>Issue: may be useful to also have a function that returns the list of
* fields in a pattern, in order, since we have that internally.
* That would be useful for getting the UI order of field elements.</i>
* @draft ICU 3.8
**/
class U_I18N_API DateTimePatternGenerator : public UObject {
public:
/**
* Construct a flexible generator according to default locale.
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @draft ICU 3.8
*/
static DateTimePatternGenerator* U_EXPORT2 createInstance(UErrorCode& status);
/**
* Construct a flexible generator according to data for a given locale.
* @param uLocale
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @draft ICU 3.8
*/
static DateTimePatternGenerator* U_EXPORT2 createInstance(const Locale& uLocale, UErrorCode& status);
/**
* Create an empty generator, to be constructed with add(...) etc.
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @draft ICU 3.8
*/
static DateTimePatternGenerator* U_EXPORT2 createEmptyInstance(UErrorCode& status);
/**
* Destructor.
*/
virtual ~DateTimePatternGenerator();
/**
* Clone DateTimePatternGenerator object. Clients are responsible for
* deleting the DateTimePatternGenerator object cloned.
* @draft ICU 3.8
*/
DateTimePatternGenerator* clone() const;
/**
* Return true if another object is semantically equal to this one.
*
* @param other the DateTimePatternGenerator object to be compared with.
* @return true if other is semantically equal to this.
* @draft ICU 3.8
*/
UBool operator==(const DateTimePatternGenerator& other) const;
/**
* Utility to return a unique skeleton from a given pattern. For example,
* both "MMM-dd" and "dd/MMM" produce the skeleton "MMMdd".
*
* @param pattern Input pattern, such as "dd/MMM"
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @return skeleton such as "MMMdd"
* @draft ICU 3.8
*/
UnicodeString getSkeleton(const UnicodeString& pattern, UErrorCode& status);
/**
* Utility to return a unique base skeleton from a given pattern. This is
* the same as the skeleton, except that differences in length are minimized
* so as to only preserve the difference between string and numeric form. So
* for example, both "MMM-dd" and "d/MMM" produce the skeleton "MMMd"
* (notice the single d).
*
* @param pattern Input pattern, such as "dd/MMM"
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @return base skeleton, such as "Md"
* @draft ICU 3.8
*/
UnicodeString getBaseSkeleton(const UnicodeString& pattern, UErrorCode& status);
/**
* Adds a pattern to the generator. If the pattern has the same skeleton as
* an existing pattern, and the override parameter is set, then the previous
* value is overriden. Otherwise, the previous value is retained. In either
* case, the conflicting status is set and previous vale is stored in
* conflicting pattern.
* <p>
* Note that single-field patterns (like "MMM") are automatically added, and
* don't need to be added explicitly!
*
* @param pattern Input pattern, such as "dd/MMM"
* @param override When existing values are to be overridden use true,
* otherwise use false.
* @param conflicting pattern Previous pattern with the same skeleton.
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @return conflicting status. The value could be UDATPG_NO_CONFLICT,
* UDATPG_BASE_CONFLICT or UDATPG_CONFLICT.
* @draft ICU 3.8
*/
UDateTimePatternConflict addPattern(const UnicodeString& pattern,
UBool override,
UnicodeString& conflictingPattern,
UErrorCode& status);
/**
* An AppendItem format is a pattern used to append a field if there is no
* good match. For example, suppose that the input skeleton is "GyyyyMMMd",
* and there is no matching pattern internally, but there is a pattern
* matching "yyyyMMMd", say "d-MM-yyyy". Then that pattern is used, plus the
* G. The way these two are conjoined is by using the AppendItemFormat for G
* (era). So if that value is, say "{0}, {1}" then the final resulting
* pattern is "d-MM-yyyy, G".
* <p>
* There are actually three available variables: {0} is the pattern so far,
* {1} is the element we are adding, and {2} is the name of the element.
* <p>
* This reflects the way that the CLDR data is organized.
*
* @param field such as UDATPG_ERA_FIELD.
* @param value pattern, such as "{0}, {1}"
* @draft ICU 3.8
*/
void setAppendItemFormat(UDateTimePatternField field, const UnicodeString& value);
/**
* Getter corresponding to setAppendItemFormat. Values below 0 or at or
* above UDATPG_FIELD_COUNT are illegal arguments.
*
* @param field such as UDATPG_ERA_FIELD.
* @return append pattern for field
* @draft ICU 3.8
*/
const UnicodeString& getAppendItemFormat(UDateTimePatternField field) const;
/**
* Sets the names of field, eg "era" in English for ERA. These are only
* used if the corresponding AppendItemFormat is used, and if it contains a
* {2} variable.
* <p>
* This reflects the way that the CLDR data is organized.
*
* @param field such as UDATPG_ERA_FIELD.
* @param value name of the field
* @draft ICU 3.8
*/
void setAppendItemName(UDateTimePatternField field, const UnicodeString& value);
/**
* Getter corresponding to setAppendItemNames. Values below 0 or at or above
* UDATPG_FIELD_COUNT are illegal arguments.
*
* @param field such as UDATPG_ERA_FIELD.
* @return name for field
* @draft ICU 3.8
*/
const UnicodeString& getAppendItemName(UDateTimePatternField field) const;
/**
* The date time format is a message format pattern used to compose date and
* time patterns. The default value is "{0} {1}", where {0} will be replaced
* by the date pattern and {1} will be replaced by the time pattern.
* <p>
* This is used when the input skeleton contains both date and time fields,
* but there is not a close match among the added patterns. For example,
* suppose that this object was created by adding "dd-MMM" and "hh:mm", and
* its datetimeFormat is the default "{0} {1}". Then if the input skeleton
* is "MMMdhmm", there is not an exact match, so the input skeleton is
* broken up into two components "MMMd" and "hmm". There are close matches
* for those two skeletons, so the result is put together with this pattern,
* resulting in "d-MMM h:mm".
*
* @param dateTimeFormat
* message format pattern, here {0} will be replaced by the date
* pattern and {1} will be replaced by the time pattern.
* @draft ICU 3.8
*/
void setDateTimeFormat(const UnicodeString& dtFormat);
/**
* Getter corresponding to setDateTimeFormat.
* @return DateTimeFormat.
* @draft ICU 3.8
*/
const UnicodeString& getDateTimeFormat() const;
/**
* Return the best pattern matching the input skeleton. It is guaranteed to
* have all of the fields in the skeleton.
*
* @param skeleton
* The skeleton is a pattern containing only the variable fields.
* For example, "MMMdd" and "mmhh" are skeletons.
* @return bestPattern
* The best pattern found from the given skeleton.
* @draft ICU 3.8
*/
UnicodeString getBestPattern(const UnicodeString& skeleton, UErrorCode& status);
/**
* Adjusts the field types (width and subtype) of a pattern to match what is
* in a skeleton. That is, if you supply a pattern like "d-M H:m", and a
* skeleton of "MMMMddhhmm", then the input pattern is adjusted to be
* "dd-MMMM hh:mm". This is used internally to get the best match for the
* input skeleton, but can also be used externally.
*
* @param pattern Input pattern
* @param skeleton
* The skeleton is a pattern containing only the variable fields.
* For example, "MMMdd" and "mmhh" are skeletons.
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @return pattern adjusted to match the skeleton fields widths and subtypes.
* @draft ICU 3.8
*/
UnicodeString replaceFieldTypes(const UnicodeString& pattern,
const UnicodeString& skeleton,
UErrorCode& status);
/**
* Return a list of all the skeletons (in canonical form) from this class.
*
* Call getPatternForSkeleton() to get the corresponding pattern.
*
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @return StringEnumeration with the skeletons.
* The caller must delete the object.
* @draft ICU 3.8
*/
StringEnumeration* getSkeletons(UErrorCode& status) const;
/**
* Get the pattern corresponding to a given skeleton.
* @param skeleton
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @return pattern corresponding to a given skeleton.
* @draft ICU 3.8
*/
const UnicodeString& getPatternForSkeleton(const UnicodeString& skeleton) const;
/**
* Return a list of all the base skeletons (in canonical form) from this class.
*
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @return a StringEnumeration with the base skeletons.
* The caller must delete the object.
* @draft ICU 3.8
*/
StringEnumeration* getBaseSkeletons(UErrorCode& status) const;
/**
* Return a list of redundant patterns are those which if removed, make no
* difference in the resulting getBestPattern values. This method returns a
* list of them, to help check the consistency of the patterns used to build
* this generator.
*
* @param status Must be a reference to an error code value,
* which must not indicate a failure before the function call.
* @return a StringEnumeration with the redundant pattern.
* The caller must delete the object.
* @internal ICU 3.8
*/
StringEnumeration* getRedundants(UErrorCode& status);
/**
* The decimal value is used in formatting fractions of seconds. If the
* skeleton contains fractional seconds, then this is used with the
* fractional seconds. For example, suppose that the input pattern is
* "hhmmssSSSS", and the best matching pattern internally is "H:mm:ss", and
* the decimal string is ",". Then the resulting pattern is modified to be
* "H:mm:ss,SSSS"
*
* @param decimal
* @draft ICU 3.8
*/
void setDecimal(const UnicodeString& decimal);
/**
* Getter corresponding to setDecimal.
* @return UnicodeString corresponding to the decimal point
* @draft ICU 3.8
*/
const UnicodeString& getDecimal() const;
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @draft ICU 3.8
*/
virtual UClassID getDynamicClassID() const;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @draft ICU 3.8
*/
static UClassID U_EXPORT2 getStaticClassID(void);
private:
/**
* Constructor.
* @draft ICU 3.8
*/
DateTimePatternGenerator(UErrorCode & status);
/**
* Constructor.
* @draft ICU 3.8
*/
DateTimePatternGenerator(const Locale& locale, UErrorCode & status);
/**
* Copy constructor.
* @param other DateTimePatternGenerator to copy
* @draft ICU 3.8
*/
DateTimePatternGenerator(const DateTimePatternGenerator& other);
/**
* Default assignment operator.
* @param other DateTimePatternGenerator to copy
* @draft ICU 3.8
*/
DateTimePatternGenerator& operator=(const DateTimePatternGenerator& other);
Locale pLocale; // pattern locale
FormatParser *fp;
DateTimeMatcher* dtMatcher;
DistanceInfo *distanceInfo;
PatternMap *patternMap;
UnicodeString appendItemFormats[UDATPG_FIELD_COUNT];
UnicodeString appendItemNames[UDATPG_FIELD_COUNT];
UnicodeString dateTimeFormat;
UnicodeString decimal;
DateTimeMatcher *skipMatcher;
Hashtable *fAvailableFormatKeyHash;
UnicodeString hackPattern;
UErrorCode fStatus;
UnicodeString emptyString;
void initData(const Locale &locale);
void addCanonicalItems();
void addICUPatterns(const Locale& locale);
void hackTimes(UnicodeString& hackPattern, UErrorCode& status);
void addCLDRData(const Locale& locale);
void initHashtable(UErrorCode& status);
void setDateTimeFromCalendar(const Locale& locale);
void setDecimalSymbols(const Locale& locale, UErrorCode& status);
UDateTimePatternField getAppendFormatNumber(const char* field);
UDateTimePatternField getAppendNameNumber(const char* field);
void getAppendName(UDateTimePatternField field, UnicodeString& value);
int32_t getCanonicalIndex(const UnicodeString& field);
UnicodeString* getBestRaw(DateTimeMatcher& source, int32_t includeMask, DistanceInfo* missingFields);
UnicodeString adjustFieldTypes(const UnicodeString& pattern, UBool fixFractionalSeconds);
UnicodeString getBestAppending(const int32_t missingFields);
int32_t getTopBitNumber(int32_t foundMask);
void setAvailableFormat(const char* key, UErrorCode& status);
UBool isAvailableFormatSet(const char* key);
void copyHashtable(Hashtable *other);
UBool isCanonicalItem(const UnicodeString& item);
UErrorCode getStatus() { return fStatus; } ;
} ;// end class DateTimePatternGenerator
U_NAMESPACE_END
#endif

View file

@ -0,0 +1,472 @@
/*
*******************************************************************************
*
* Copyright (C) 2007, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: udatpg.h
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2007jul30
* created by: Markus W. Scherer
*/
#ifndef __UDATPG_H__
#define __UDATPG_H__
#include "unicode/utypes.h"
#include "unicode/uenum.h"
/**
* \file
* \brief C API: Wrapper for DateTimePatternGenerator (unicode/dtptngen.h).
*
* UDateTimePatternGenerator provides flexible generation of date format patterns,
* like "yy-MM-dd". The user can build up the generator by adding successive
* patterns. Once that is done, a query can be made using a "skeleton", which is
* a pattern which just includes the desired fields and lengths. The generator
* will return the "best fit" pattern corresponding to that skeleton.
* <p>The main method people will use is udatpg_getBestPattern, since normally
* UDateTimePatternGenerator is pre-built with data from a particular locale.
* However, generators can be built directly from other data as well.
* <p><i>Issue: may be useful to also have a function that returns the list of
* fields in a pattern, in order, since we have that internally.
* That would be useful for getting the UI order of field elements.</i>
*/
/**
* Opaque type for a date/time pattern generator object.
* @draft ICU 3.8
*/
typedef void *UDateTimePatternGenerator;
#ifndef U_HIDE_DRAFT_API
/**
* Field number constants for udatpg_getAppendItemFormats() and similar functions.
* These constants are separate from UDateFormatField despite semantic overlap
* because some fields are merged for the date/time pattern generator.
* @draft ICU 3.8
*/
typedef enum UDateTimePatternField {
/** @draft ICU 3.8 */
UDATPG_ERA_FIELD,
/** @draft ICU 3.8 */
UDATPG_YEAR_FIELD,
/** @draft ICU 3.8 */
UDATPG_QUARTER_FIELD,
/** @draft ICU 3.8 */
UDATPG_MONTH_FIELD,
/** @draft ICU 3.8 */
UDATPG_WEEK_OF_YEAR_FIELD,
/** @draft ICU 3.8 */
UDATPG_WEEK_OF_MONTH_FIELD,
/** @draft ICU 3.8 */
UDATPG_WEEKDAY_FIELD,
/** @draft ICU 3.8 */
UDATPG_DAY_OF_YEAR_FIELD,
/** @draft ICU 3.8 */
UDATPG_DAY_OF_WEEK_IN_MONTH_FIELD,
/** @draft ICU 3.8 */
UDATPG_DAY_FIELD,
/** @draft ICU 3.8 */
UDATPG_DAYPERIOD_FIELD,
/** @draft ICU 3.8 */
UDATPG_HOUR_FIELD,
/** @draft ICU 3.8 */
UDATPG_MINUTE_FIELD,
/** @draft ICU 3.8 */
UDATPG_SECOND_FIELD,
/** @draft ICU 3.8 */
UDATPG_FRACTIONAL_SECOND_FIELD,
/** @draft ICU 3.8 */
UDATPG_ZONE_FIELD,
/** @draft ICU 3.8 */
UDATPG_FIELD_COUNT
} UDateTimePatternField;
/**
* Status return values from udatpg_addPattern().
* @draft ICU 3.8
*/
typedef enum UDateTimePatternConflict {
/** @draft ICU 3.8 */
UDATPG_NO_CONFLICT,
/** @draft ICU 3.8 */
UDATPG_BASE_CONFLICT,
/** @draft ICU 3.8 */
UDATPG_CONFLICT,
/** @draft ICU 3.8 */
UDATPG_CONFLICT_COUNT
} UDateTimePatternConflict;
#endif
/**
* Open a generator according to a given locale.
* @param locale
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call.
* @return a pointer to UDateTimePatternGenerator.
* @draft ICU 3.8
*/
U_DRAFT UDateTimePatternGenerator * U_EXPORT2
udatpg_open(const char *locale, UErrorCode *pErrorCode);
/**
* Open an empty generator, to be constructed with udatpg_addPattern(...) etc.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call.
* @return a pointer to UDateTimePatternGenerator.
* @draft ICU 3.8
*/
U_DRAFT UDateTimePatternGenerator * U_EXPORT2
udatpg_openEmpty(UErrorCode *pErrorCode);
/**
* Close a generator.
* @param a pointer to UDateTimePatternGenerator.
* @draft ICU 3.8
*/
U_DRAFT void U_EXPORT2
udatpg_close(UDateTimePatternGenerator *dtpg);
/**
* Create a copy pf a generator.
* @param a pointer to UDateTimePatternGenerator to be copied.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call.
* @return a pointer to a new UDateTimePatternGenerator.
* @draft ICU 3.8
*/
U_DRAFT UDateTimePatternGenerator * U_EXPORT2
udatpg_clone(const UDateTimePatternGenerator *dtpg, UErrorCode *pErrorCode);
/**
* Get the best pattern matching the input skeleton. It is guaranteed to
* have all of the fields in the skeleton.
*
* Note that this function uses a non-const UDateTimePatternGenerator:
* It uses a stateful pattern parser which is set up for each generator object,
* rather than creating one for each function call.
* Consecutive calls to this function do not affect each other,
* but this function cannot be used concurrently on a single generator object.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param skeleton
* The skeleton is a pattern containing only the variable fields.
* For example, "MMMdd" and "mmhh" are skeletons.
* @param length the length of skeleton
* @param bestPattern
* The best pattern found from the given skeleton.
* @param capacity the capacity of bestPattern.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call.
* @return the length of bestPattern.
* @draft ICU 3.8
*/
U_DRAFT int32_t U_EXPORT2
udatpg_getBestPattern(UDateTimePatternGenerator *dtpg,
const UChar *skeleton, int32_t length,
UChar *bestPattern, int32_t capacity,
UErrorCode *pErrorCode);
/**
* Get a unique skeleton from a given pattern. For example,
* both "MMM-dd" and "dd/MMM" produce the skeleton "MMMdd".
*
* Note that this function uses a non-const UDateTimePatternGenerator:
* It uses a stateful pattern parser which is set up for each generator object,
* rather than creating one for each function call.
* Consecutive calls to this function do not affect each other,
* but this function cannot be used concurrently on a single generator object.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param pattern input pattern, such as "dd/MMM".
* @param length the length of pattern.
* @param skeleton such as "MMMdd"
* @param capacity the capacity of skeleton.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call.
* @return the length of skeleton.
* @draft ICU 3.8
*/
U_DRAFT int32_t U_EXPORT2
udatpg_getSkeleton(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t length,
UChar *skeleton, int32_t capacity,
UErrorCode *pErrorCode);
/**
* Get a unique base skeleton from a given pattern. This is the same
* as the skeleton, except that differences in length are minimized so
* as to only preserve the difference between string and numeric form. So
* for example, both "MMM-dd" and "d/MMM" produce the skeleton "MMMd"
* (notice the single d).
*
* Note that this function uses a non-const UDateTimePatternGenerator:
* It uses a stateful pattern parser which is set up for each generator object,
* rather than creating one for each function call.
* Consecutive calls to this function do not affect each other,
* but this function cannot be used concurrently on a single generator object.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param pattern input pattern, such as "dd/MMM".
* @param length the length of pattern.
* @param baseSkeleton such as "Md"
* @param capacity the capacity of base skeleton.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call.
* @return the length of baseSkeleton.
* @draft ICU 3.8
*/
U_DRAFT int32_t U_EXPORT2
udatpg_getBaseSkeleton(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t length,
UChar *baseSkeleton, int32_t capacity,
UErrorCode *pErrorCode);
/**
* Adds a pattern to the generator. If the pattern has the same skeleton as
* an existing pattern, and the override parameter is set, then the previous
* value is overriden. Otherwise, the previous value is retained. In either
* case, the conflicting status is set and previous vale is stored in
* conflicting pattern.
* <p>
* Note that single-field patterns (like "MMM") are automatically added, and
* don't need to be added explicitly!
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param pattern input pattern, such as "dd/MMM"
* @param patternLength the length of pattern.
* @param override When existing values are to be overridden use true,
* otherwise use false.
* @param conflictingPattern Previous pattern with the same skeleton.
* @param capacity the capacity of conflictingPattern.
* @param pLength a pointer to the length of conflictingPattern.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call.
* @return conflicting status. The value could be UDATPG_NO_CONFLICT,
* UDATPG_BASE_CONFLICT or UDATPG_CONFLICT.
* @draft ICU 3.8
*/
U_DRAFT UDateTimePatternConflict U_EXPORT2
udatpg_addPattern(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t patternLength,
UBool override,
UChar *conflictingPattern, int32_t capacity, int32_t *pLength,
UErrorCode *pErrorCode);
/**
* An AppendItem format is a pattern used to append a field if there is no
* good match. For example, suppose that the input skeleton is "GyyyyMMMd",
* and there is no matching pattern internally, but there is a pattern
* matching "yyyyMMMd", say "d-MM-yyyy". Then that pattern is used, plus the
* G. The way these two are conjoined is by using the AppendItemFormat for G
* (era). So if that value is, say "{0}, {1}" then the final resulting
* pattern is "d-MM-yyyy, G".
* <p>
* There are actually three available variables: {0} is the pattern so far,
* {1} is the element we are adding, and {2} is the name of the element.
* <p>
* This reflects the way that the CLDR data is organized.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param field UDateTimePatternField, such as UDATPG_ERA_FIELD
* @param value pattern, such as "{0}, {1}"
* @param length the length of value.
* @draft ICU 3.8
*/
U_DRAFT void U_EXPORT2
udatpg_setAppendItemFormat(UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
const UChar *value, int32_t length);
/**
* Getter corresponding to setAppendItemFormat. Values below 0 or at or
* above UDATPG_FIELD_COUNT are illegal arguments.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param field UDateTimePatternField, such as UDATPG_ERA_FIELD
* @param length pointer of the length of appendItemFormat.
* @return appendItemFormat for field.
* @draft ICU 3.8
*/
U_DRAFT const UChar * U_EXPORT2
udatpg_getAppendItemFormat(const UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
int32_t *pLength);
/**
* Set the name of field, eg "era" in English for ERA. These are only
* used if the corresponding AppendItemFormat is used, and if it contains a
* {2} variable.
* <p>
* This reflects the way that the CLDR data is organized.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param field UDateTimePatternField
* @param value name for the field.
* @param length the length of value.
* @draft ICU 3.8
*/
U_DRAFT void U_EXPORT2
udatpg_setAppendItemName(UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
const UChar *value, int32_t length);
/**
* Getter corresponding to setAppendItemNames. Values below 0 or at or above
* UDATPG_FIELD_COUNT are illegal arguments.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param field UDateTimePatternField, such as UDATPG_ERA_FIELD
* @param length pointer of the length of name for field.
* @return name for field
* @draft ICU 3.8
*/
U_DRAFT const UChar * U_EXPORT2
udatpg_getAppendItemName(const UDateTimePatternGenerator *dtpg,
UDateTimePatternField field,
int32_t *pLength);
/**
* The date time format is a message format pattern used to compose date and
* time patterns. The default value is "{0} {1}", where {0} will be replaced
* by the date pattern and {1} will be replaced by the time pattern.
* <p>
* This is used when the input skeleton contains both date and time fields,
* but there is not a close match among the added patterns. For example,
* suppose that this object was created by adding "dd-MMM" and "hh:mm", and
* its datetimeFormat is the default "{0} {1}". Then if the input skeleton
* is "MMMdhmm", there is not an exact match, so the input skeleton is
* broken up into two components "MMMd" and "hmm". There are close matches
* for those two skeletons, so the result is put together with this pattern,
* resulting in "d-MMM h:mm".
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param dtFormat
* message format pattern, here {0} will be replaced by the date
* pattern and {1} will be replaced by the time pattern.
* @param length the length of dtFormat.
* @draft ICU 3.8
*/
U_DRAFT void U_EXPORT2
udatpg_setDateTimeFormat(const UDateTimePatternGenerator *dtpg,
const UChar *dtFormat, int32_t length);
/**
* Getter corresponding to setDateTimeFormat.
* @param dtpg a pointer to UDateTimePatternGenerator.
* @return dateTimeFormat.
* @draft ICU 3.8
*/
U_DRAFT const UChar * U_EXPORT2
udatpg_getDateTimeFormat(const UDateTimePatternGenerator *dtpg,
int32_t *pLength);
/**
* The decimal value is used in formatting fractions of seconds. If the
* skeleton contains fractional seconds, then this is used with the
* fractional seconds. For example, suppose that the input pattern is
* "hhmmssSSSS", and the best matching pattern internally is "H:mm:ss", and
* the decimal string is ",". Then the resulting pattern is modified to be
* "H:mm:ss,SSSS"
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param decimal
* @param length the length of decimal.
* @draft ICU 3.8
*/
U_DRAFT void U_EXPORT2
udatpg_setDecimal(UDateTimePatternGenerator *dtpg,
const UChar *decimal, int32_t length);
/**
* Getter corresponding to setDecimal.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param length a pointer to the length of decimal.
* @return corresponding to the decimal point.
* @draft ICU 3.8
*/
U_DRAFT const UChar * U_EXPORT2
udatpg_getDecimal(const UDateTimePatternGenerator *dtpg,
int32_t *pLength);
/**
* Adjusts the field types (width and subtype) of a pattern to match what is
* in a skeleton. That is, if you supply a pattern like "d-M H:m", and a
* skeleton of "MMMMddhhmm", then the input pattern is adjusted to be
* "dd-MMMM hh:mm". This is used internally to get the best match for the
* input skeleton, but can also be used externally.
*
* Note that this function uses a non-const UDateTimePatternGenerator:
* It uses a stateful pattern parser which is set up for each generator object,
* rather than creating one for each function call.
* Consecutive calls to this function do not affect each other,
* but this function cannot be used concurrently on a single generator object.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param pattern Input pattern
* @param patternLength the length of input pattern.
* @param skeleton
* @param skeletonLength the length of input skeleton.
* @param dest pattern adjusted to match the skeleton fields widths and subtypes.
* @param capacity the capacity of dest.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call.
* @return the length of dest.
* @draft ICU 3.8
*/
U_DRAFT int32_t U_EXPORT2
udatpg_replaceFieldTypes(UDateTimePatternGenerator *dtpg,
const UChar *pattern, int32_t patternLength,
const UChar *skeleton, int32_t skeletonLength,
UChar *dest, int32_t destCapacity,
UErrorCode *pErrorCode);
/**
* Return a UEnumeration list of all the skeletons in canonical form.
* Call udatpg_getPatternForSkeleton() to get the corresponding pattern.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call
* @return a UEnumeration list of all the skeletons
* The caller must close the object.
* @draft ICU 3.8
*/
U_DRAFT UEnumeration * U_EXPORT2
udatpg_openSkeletons(const UDateTimePatternGenerator *dtpg, UErrorCode *pErrorCode);
/**
* Return a UEnumeration list of all the base skeletons in canonical form.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
* failure before the function call.
* @return a UEnumeration list of all the base skeletons
* The caller must close the object.
* @draft ICU 3.8
*/
U_DRAFT UEnumeration * U_EXPORT2
udatpg_openBaseSkeletons(const UDateTimePatternGenerator *dtpg, UErrorCode *pErrorCode);
/**
* Get the pattern corresponding to a given skeleton.
*
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param skeleton
* @param skeletonLength pointer to the length of skeleton.
* @param pLength pointer to the length of return pattern.
* @return pattern corresponding to a given skeleton.
* @draft ICU 3.8
*/
U_DRAFT const UChar * U_EXPORT2
udatpg_getPatternForSkeleton(const UDateTimePatternGenerator *dtpg,
const UChar *skeleton, int32_t skeletonLength,
int32_t *pLength);
#endif

View file

@ -48,7 +48,7 @@ cmsccoll.o cmsgtst.o cposxtst.o cldrtest.o \
cnmdptst.o cnormtst.o cnumtst.o crestst.o creststn.o cturtst.o \
cucdapi.o cucdtst.o custrtst.o cstrcase.o cutiltst.o nucnvtst.o nccbtst.o bocu1tst.o \
cbiditst.o cbididat.o eurocreg.o udatatst.o utf16tst.o utransts.o \
ncnvfbts.o ncnvtst.o putiltst.o cstrtest.o utf8tst.o \
ncnvfbts.o ncnvtst.o putiltst.o cstrtest.o udatpg_test.o utf8tst.o \
stdnmtst.o usrchtst.o custrtrn.o sorttest.o trietest.o usettest.o \
uenumtst.o utmstest.o currtest.o \
idnatest.o nfsprep.o spreptst.o sprpdata.o \

View file

@ -1,6 +1,6 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2005, International Business Machines Corporation
* Copyright (c) 1997-2007, International Business Machines Corporation
* and others. All Rights Reserved.
********************************************************************/
/********************************************************************************
@ -24,6 +24,7 @@
void addCalTest(TestNode**);
void addDateForTest(TestNode**);
void addDateTimePatternGeneratorTest(TestNode** root);
void addNumForTest(TestNode**);
void addMsgForTest(TestNode**);
void addDateForRgrTest(TestNode**);
@ -38,6 +39,7 @@ void addFormatTest(TestNode** root)
{
addCalTest(root);
addDateForTest(root);
addDateTimePatternGeneratorTest(root);
addNumForTest(root);
addNumFrDepTest(root);
addMsgForTest(root);

View file

@ -534,6 +534,10 @@
RelativePath=".\currtest.c"
>
</File>
<File
RelativePath=".\udatpg_test.c"
>
</File>
<File
RelativePath=".\utmstest.c"
>

View file

@ -0,0 +1,290 @@
/*
*******************************************************************************
*
* Copyright (C) 2007, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
* file name: udatpg_test.c
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2007aug01
* created by: Markus W. Scherer
*
* Test of the C wrapper for the DateTimePatternGenerator.
* Calls each C API function and exercises code paths in the wrapper,
* but the full functionality is tested in the C++ intltest.
*
* One item to note: C API functions which return a const UChar *
* should return a NUL-terminated string.
* (The C++ implementation needs to use getTerminatedBuffer()
* on UnicodeString objects which end up being returned this way.)
*/
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "unicode/udatpg.h"
#include "unicode/ustring.h"
#include "cintltst.h"
void addDateTimePatternGeneratorTest(TestNode** root);
#define TESTCASE(x) addTest(root, &x, "tsformat/udatpg_test/" #x)
static void TestOpenClose(void);
static void TestUsage(void);
static void TestBuilder(void);
void addDateTimePatternGeneratorTest(TestNode** root) {
TESTCASE(TestOpenClose);
TESTCASE(TestUsage);
TESTCASE(TestBuilder);
}
/*
* Pipe symbol '|'. We pass only the first UChar without NUL-termination.
* The second UChar is just to verify that the API does not pick that up.
*/
static const UChar pipeString[]={ 0x7c, 0x0a };
static const UChar testSkeleton1[]={ 0x48, 0x48, 0x6d, 0x6d, 0 }; /* HHmm */
static const UChar expectingBestPattern[]={ 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0 }; /* HH.mm */
static const UChar testPattern[]={ 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0 }; /* HH:mm */
static const UChar expectingSkeleton[]= { 0x48, 0x48, 0x6d, 0x6d, 0 }; /* HHmm */
static const UChar expectingBaseSkeleton[]= { 0x48, 0x6d, 0 }; /* HHmm */
static const UChar redundantPattern[]={ 0x79, 0x79, 0x4d, 0x4d, 0x4d, 0 }; /* yyMMM */
static const UChar testFormat[]= {0x7B, 0x31, 0x7D, 0x20, 0x7B, 0x30, 0x7D, 0}; /* {1} {0} */
static const UChar appendItemName[]= {0x68, 0x72, 0}; /* hr */
static const UChar testPattern2[]={ 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x20, 0x76, 0 }; /* HH:mm v */
static const UChar replacedStr[]={ 0x76, 0x76, 0x76, 0x76, 0 }; /* vvvv */
static void TestOpenClose() {
UErrorCode errorCode=U_ZERO_ERROR;
UDateTimePatternGenerator *dtpg, *dtpg2;
const UChar *s;
int32_t length;
/* Open a DateTimePatternGenerator for the default locale. */
dtpg=udatpg_open(NULL, &errorCode);
if(U_FAILURE(errorCode)) {
log_err("udatpg_open(NULL) failed - %s\n", u_errorName(errorCode));
return;
}
udatpg_close(dtpg);
/* Now one for German. */
dtpg=udatpg_open("de", &errorCode);
if(U_FAILURE(errorCode)) {
log_err("udatpg_open(de) failed - %s\n", u_errorName(errorCode));
return;
}
/* Make some modification which we verify gets passed on to the clone. */
udatpg_setDecimal(dtpg, pipeString, 1);
/* Clone the generator. */
dtpg2=udatpg_clone(dtpg, &errorCode);
if(U_FAILURE(errorCode) || dtpg2==NULL) {
log_err("udatpg_clone() failed - %s\n", u_errorName(errorCode));
return;
}
/* Verify that the clone has the custom decimal symbol. */
s=udatpg_getDecimal(dtpg2, &length);
if(s==pipeString || length!=1 || 0!=u_memcmp(s, pipeString, length) || s[length]!=0) {
log_err("udatpg_getDecimal(cloned object) did not return the expected string\n");
return;
}
udatpg_close(dtpg);
udatpg_close(dtpg2);
}
static void TestUsage() {
UErrorCode errorCode=U_ZERO_ERROR;
UDateTimePatternGenerator *dtpg;
UChar bestPattern[20];
UChar result[20];
int32_t length;
UChar *s;
const UChar *r;
dtpg=udatpg_open("fi", &errorCode);
if(U_FAILURE(errorCode)) {
log_err("udatpg_open(fi) failed - %s\n", u_errorName(errorCode));
return;
}
length = udatpg_getBestPattern(dtpg, testSkeleton1, 4,
bestPattern, 20, &errorCode);
if(U_FAILURE(errorCode)) {
log_err("udatpg_getBestPattern failed - %s\n", u_errorName(errorCode));
return;
}
if((u_memcmp(bestPattern, expectingBestPattern, length)!=0) || bestPattern[length]!=0) {
log_err("udatpg_getBestPattern did not return the expected string\n");
return;
}
/* Test skeleton == NULL */
s=NULL;
length = udatpg_getBestPattern(dtpg, s, 0, bestPattern, 20, &errorCode);
if(!U_FAILURE(errorCode)&&(length!=0) ) {
log_err("udatpg_getBestPattern failed in illegal argument - skeleton is NULL.\n");
return;
}
/* Test udatpg_getSkeleton */
length = udatpg_getSkeleton(dtpg, testPattern, 5, result, 20, &errorCode);
if(U_FAILURE(errorCode)) {
log_err("udatpg_getSkeleton failed - %s\n", u_errorName(errorCode));
return;
}
if((u_memcmp(result, expectingSkeleton, length)!=0) || result[length]!=0) {
log_err("udatpg_getSkeleton did not return the expected string\n");
return;
}
/* Test pattern == NULL */
s=NULL;
length = udatpg_getSkeleton(dtpg, s, 0, result, 20, &errorCode);
if(!U_FAILURE(errorCode)&&(length!=0) ) {
log_err("udatpg_getSkeleton failed in illegal argument - pattern is NULL.\n");
return;
}
/* Test udatpg_getBaseSkeleton */
length = udatpg_getBaseSkeleton(dtpg, testPattern, 5, result, 20, &errorCode);
if(U_FAILURE(errorCode)) {
log_err("udatpg_getBaseSkeleton failed - %s\n", u_errorName(errorCode));
return;
}
if((u_memcmp(result, expectingBaseSkeleton, length)!=0) || result[length]!=0) {
log_err("udatpg_getBaseSkeleton did not return the expected string\n");
return;
}
/* Test pattern == NULL */
s=NULL;
length = udatpg_getBaseSkeleton(dtpg, s, 0, result, 20, &errorCode);
if(!U_FAILURE(errorCode)&&(length!=0) ) {
log_err("udatpg_getBaseSkeleton failed in illegal argument - pattern is NULL.\n");
return;
}
/* set append format to {1}{0} */
udatpg_setAppendItemFormat( dtpg, UDATPG_MONTH_FIELD, testFormat, 7 );
r = udatpg_getAppendItemFormat(dtpg, UDATPG_MONTH_FIELD, &length);
if(length!=7 || 0!=u_memcmp(r, testFormat, length) || r[length]!=0) {
log_err("udatpg_setAppendItemFormat did not return the expected string\n");
return;
}
/* set append name to hr */
udatpg_setAppendItemName( dtpg, UDATPG_HOUR_FIELD, appendItemName, 7 );
r = udatpg_getAppendItemName(dtpg, UDATPG_HOUR_FIELD, &length);
if(length!=7 || 0!=u_memcmp(r, appendItemName, length) || r[length]!=0) {
log_err("udatpg_setAppendItemName did not return the expected string\n");
return;
}
/* set date time format to {1}{0} */
udatpg_setDateTimeFormat( dtpg, testFormat, 7 );
r = udatpg_getDateTimeFormat(dtpg, &length);
if(length!=7 || 0!=u_memcmp(r, testFormat, length) || r[length]!=0) {
log_err("udatpg_setDateTimeFormat did not return the expected string\n");
return;
}
udatpg_close(dtpg);
}
static void TestBuilder() {
UErrorCode errorCode=U_ZERO_ERROR;
UDateTimePatternGenerator *dtpg;
UDateTimePatternConflict conflict;
UEnumeration *en;
UChar result[20];
int32_t length, pLength;
UChar *s, *p;
/* test create an empty DateTimePatternGenerator */
dtpg=udatpg_openEmpty(&errorCode);
if(U_FAILURE(errorCode)) {
log_err("udatpg_openEmpty() failed - %s\n", u_errorName(errorCode));
return;
}
/* Add a pattern */
conflict = udatpg_addPattern(dtpg, redundantPattern, 5, FALSE, result, 20,
&length, &errorCode);
if(U_FAILURE(errorCode)) {
log_err("udatpg_addPattern() failed - %s\n", u_errorName(errorCode));
return;
}
/* Add a redundant pattern */
conflict = udatpg_addPattern(dtpg, redundantPattern, 5, FALSE, result, 20,
&length, &errorCode);
if(conflict == UDATPG_NO_CONFLICT) {
log_err("udatpg_addPattern() failed to find the duplicate pattern.\n");
return;
}
/* Test pattern == NULL */
s=NULL;
length = udatpg_addPattern(dtpg, s, 0, FALSE, result, 20,
&length, &errorCode);
if(!U_FAILURE(errorCode)&&(length!=0) ) {
log_err("udatpg_addPattern failed in illegal argument - pattern is NULL.\n");
return;
}
/* replace field type */
errorCode=U_ZERO_ERROR;
conflict = udatpg_addPattern(dtpg, testPattern2, 7, FALSE, result, 20,
&length, &errorCode);
if((conflict != UDATPG_NO_CONFLICT)||U_FAILURE(errorCode)) {
log_err("udatpg_addPattern() failed to add HH:mm v. - %s\n", u_errorName(errorCode));
return;
}
length = udatpg_replaceFieldTypes(dtpg, testPattern2, 7, replacedStr, 4,
result, 20, &errorCode);
if (U_FAILURE(errorCode) || (length==0) ) {
log_err("udatpg_replaceFieldTypes failed!\n");
return;
}
/* Get all skeletons and the crroespong pattern for each skeleton. */
en = udatpg_openSkeletons(dtpg, &errorCode);
if (U_FAILURE(errorCode) || (length==0) ) {
log_err("udatpg_openSkeletons failed!\n");
return;
}
while ( (s=uenum_next(en, &length, &errorCode))!= NULL) {
p = udatpg_getPatternForSkeleton(dtpg, s, length, &pLength);
if (U_FAILURE(errorCode) || p==NULL ) {
log_err("udatpg_getPatternForSkeleton failed!\n");
return;
}
}
uenum_close(en);
/* Get all baseSkeletons */
en = udatpg_openBaseSkeletons(dtpg, &errorCode);
if (U_FAILURE(errorCode) || (length==0) ) {
log_err("udatpg_openSkeletons failed!\n");
return;
}
uenum_close(en);
udatpg_close(dtpg);
}
#endif

View file

@ -42,7 +42,7 @@ LIBS = $(LIBCTESTFW) $(LIBICUI18N) $(LIBICUUC) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS)
OBJECTS = aliastst.o allcoll.o apicoll.o astrotst.o callimts.o calregts.o caltest.o \
caltztst.o canittst.o citrtest.o cntabcol.o convtest.o currcoll.o \
dadrcal.o dadrcoll.o dcfmapts.o decoll.o dtfmapts.o dtfmrgts.o dtfmtrtts.o dtfmttst.o \
encoll.o escoll.o ficoll.o frcoll.o g7coll.o intltest.o \
dtptngts.o encoll.o escoll.o ficoll.o frcoll.o g7coll.o intltest.o \
itercoll.o itformat.o itmajor.o itutil.o jacoll.o lcukocol.o \
loctest.o miscdtfm.o mnkytst.o msfmrgts.o nmfmapts.o nmfmtrt.o \
numfmtst.o numrgts.o pptest.o regcoll.o restest.o restsnew.o \

View file

@ -0,0 +1,431 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 2007, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
#if !UCONFIG_NO_FORMATTING
#include <stdio.h>
#include <stdlib.h>
#include "dtptngts.h"
#include "unicode/calendar.h"
#include "unicode/smpdtfmt.h"
#include "unicode/dtfmtsym.h"
#include "unicode/dtptngen.h"
#include "unicode/utypes.h"
#include "loctest.h"
static const UnicodeString patternData[] = {
UnicodeString("yM"),
UnicodeString("yMMM"),
UnicodeString("yMd"),
UnicodeString("yMMMd"),
UnicodeString("Md"),
UnicodeString("MMMd"),
UnicodeString("yQQQ"),
UnicodeString("hhmm"),
UnicodeString("HHmm"),
UnicodeString("mmss"),
UnicodeString(""),
};
#define MAX_LOCALE 4
static const char* testLocale[MAX_LOCALE][3] = {
{"en", "US","\0"},
{"zh", "Hans", "CN"},
{"de","DE", "\0"},
{"fi","\0", "\0"},
};
static const UnicodeString patternResults[] = {
UnicodeString("1/1999"), // en_US
UnicodeString("Jan 1999"),
UnicodeString("1/13/1999"),
UnicodeString("Jan/13/1999"),
UnicodeString("1/13"),
UnicodeString("Jan 13"),
UnicodeString("Q1 1999"),
UnicodeString("11:58 PM"),
UnicodeString("23:58"),
UnicodeString("58:59"),
UnicodeString("1999-1"), // zh_Hans_CN
UnicodeString("1999 1"),
UnicodeString("1999113"),
UnicodeString("1999113"),
// TODO: These are diff from CLDR 1.4 to CLDR 1.5. will verify the result soon.
//CharsToUnicodeString("1999\\u5E741\\u670813\\u65E5"),
//CharsToUnicodeString("1999\\u5E741\\u670813\\u65E5"),
UnicodeString("1-13"),
UnicodeString("1 13"),
CharsToUnicodeString("1999 Q1"),
CharsToUnicodeString("\\u4E0B\\u534811:58"),
CharsToUnicodeString("23:58"),
UnicodeString("58:59"),
UnicodeString("1.1999"), // de_DE
UnicodeString("Jan 1999"),
UnicodeString("13.1.1999"),
UnicodeString("13. Jan 1999"),
UnicodeString("13.1."),
UnicodeString("13. Jan"),
UnicodeString("Q1 1999"),
UnicodeString("23:58"),
UnicodeString("23:58"),
UnicodeString("58:59"),
UnicodeString("1/1999"), // fi
UnicodeString("tammi 1999"),
UnicodeString("13.1.1999"),
UnicodeString("13. tammita 1999"),
UnicodeString("13.1."),
UnicodeString("13. tammita"),
UnicodeString("1. nelj./1999"),
UnicodeString("23.58"),
UnicodeString("23.58"),
UnicodeString("58.59"),
UnicodeString(""),
};
// This is an API test, not a unit test. It doesn't test very many cases, and doesn't
// try to test the full functionality. It just calls each function in the class and
// verifies that it works on a basic level.
void IntlTestDateTimePatternGeneratorAPI::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
{
if (exec) logln("TestSuite DateTimePatternGeneratorAPI");
switch (index) {
case 0: name = "DateTimePatternGenerator API test";
if (exec) {
logln("DateTimePatternGenerator API test---"); logln("");
UErrorCode status = U_ZERO_ERROR;
Locale saveLocale;
Locale::setDefault(Locale::getEnglish(), status);
if(U_FAILURE(status)) {
errln("ERROR: Could not set default locale, test may not give correct results");
}
testAPI(/*par*/);
Locale::setDefault(saveLocale, status);
}
break;
default: name = ""; break;
}
}
/**
* Test various generic API methods of DateTimePatternGenerator for API coverage.
*/
void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/)
{
UErrorCode status = U_ZERO_ERROR;
UnicodeString conflictingPattern;
UDateTimePatternConflict conflictingStatus;
// ======= Test CreateInstance with default locale
logln("Testing DateTimePatternGenerator createInstance from default locale");
DateTimePatternGenerator *instFromDefaultLocale=DateTimePatternGenerator::createInstance(status);
if (U_FAILURE(status)) {
dataerrln("ERROR: Could not create DateTimePatternGenerator (default) - exitting");
return;
}
else {
delete instFromDefaultLocale;
}
// ======= Test CreateInstance with given locale
logln("Testing DateTimePatternGenerator createInstance from French locale");
status = U_ZERO_ERROR;
DateTimePatternGenerator *instFromLocale=DateTimePatternGenerator::createInstance(Locale::getFrench(), status);
if (U_FAILURE(status)) {
dataerrln("ERROR: Could not create DateTimePatternGenerator (Locale::getFrench()) - exitting");
return;
}
// ======= Test clone DateTimePatternGenerator
logln("Testing DateTimePatternGenerator::clone()");
status = U_ZERO_ERROR;
UnicodeString decimalSymbol = instFromLocale->getDecimal();
UnicodeString newDecimalSymbol = UnicodeString("*");
decimalSymbol = instFromLocale->getDecimal();
instFromLocale->setDecimal(newDecimalSymbol);
DateTimePatternGenerator *cloneDTPatternGen=instFromLocale->clone();
decimalSymbol = cloneDTPatternGen->getDecimal();
if (decimalSymbol != newDecimalSymbol) {
dataerrln("ERROR: inconsistency is found in cloned object- exitting");
return;
}
if (U_FAILURE(status)) {
delete instFromLocale;
dataerrln("ERROR: Could not create DateTimePatternGenerator (Locale::getFrench()) - exitting");
return;
}
else {
delete instFromLocale;
delete cloneDTPatternGen;
}
// ======= Test simple use cases
logln("Testing simple use cases");
status = U_ZERO_ERROR;
Locale deLocale=Locale::getGermany();
UDate sampleDate=LocaleTest::date(99, 9, 13, 23, 58, 59);
DateTimePatternGenerator *gen = DateTimePatternGenerator::createInstance(deLocale, status);
UnicodeString findPattern = gen->getBestPattern(UnicodeString("MMMddHmm"), status);
SimpleDateFormat *format = new SimpleDateFormat(findPattern, deLocale, status);
//TimeZone *zone = TimeZone::createTimeZone(UnicodeString("Europe/Paris"));
TimeZone *zone = TimeZone::createTimeZone(UnicodeString("ECT"));
format->setTimeZone(*zone);
UnicodeString dateReturned, expectedResult;
dateReturned="";
dateReturned = format->format(sampleDate, dateReturned, status);
expectedResult=UnicodeString("8:58 14. Okt");
if ( dateReturned != expectedResult ) {
if ( format != NULL ) delete format;
if ( zone != NULL ) delete zone;
if ( gen != NULL ) delete gen;
dataerrln("ERROR: Simple test in Locale::getGermany()) - exitting");
return;
}
// add new pattern
conflictingStatus = gen->addPattern(UnicodeString("d'. von' MMMM"), true, conflictingPattern, status);
status = U_ZERO_ERROR;
UnicodeString testPattern=gen->getBestPattern(UnicodeString("MMMMdd"), status);
testPattern=gen->getBestPattern(UnicodeString("MMMddHmm"), status);
format->applyPattern(gen->getBestPattern(UnicodeString("MMMMddHmm"), status));
dateReturned="";
dateReturned = format->format(sampleDate, dateReturned, status);
expectedResult=UnicodeString("8:58 14. von Oktober");
if ( dateReturned != expectedResult ) {
if ( format != NULL ) delete format;
if ( zone != NULL ) delete zone;
if ( gen != NULL ) delete gen;
dataerrln("ERROR: Simple test add pattern d\'. von\' MMMM - exitting");
return;
}
if ( format != NULL ) delete format;
// get a pattern and modify it
format = (SimpleDateFormat *)DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull,
deLocale);
format->setTimeZone(*zone);
UnicodeString pattern;
pattern = format->toPattern(pattern);
dateReturned="";
dateReturned = format->format(sampleDate, dateReturned, status);
//expectedResult=UnicodeString("Donnerstag, 14. Oktober 1999 08:58:59 Frankreich");
//The mismatch is caused by the setup of Timezone. The output pattern is same as in Java.
expectedResult=UnicodeString("Donnerstag, 14. Oktober 1999 08:58:59 GMT+02:00");
if ( dateReturned != expectedResult ) {
if ( format != NULL ) delete format;
if ( zone != NULL ) delete zone;
if ( gen != NULL ) delete gen;
dataerrln("ERROR: Simple test uses full date format.- exitting");
return;
}
// modify it to change the zone.
UnicodeString newPattern = gen->replaceFieldTypes(pattern, UnicodeString("vvvv"), status);
format->applyPattern(newPattern);
dateReturned="";
dateReturned = format->format(sampleDate, dateReturned, status);
expectedResult=UnicodeString("Donnerstag, 14. Oktober 1999 08:58:59 GMT+02:00");
// expectedResult=UnicodeString("Donnerstag, 14. Oktober 1999 08:58:59 Frankreich:);
// The mismatch is caused by the setup of Timezone. The output pattern is same as in Java.
if ( dateReturned != expectedResult ) {
if ( format != NULL ) delete format;
if ( zone != NULL ) delete zone;
if ( gen != NULL ) delete gen;
dataerrln("ERROR: Simple test modify the timezone - exitting");
return;
}
/*
printf("\n replace pattern:");
for (int32_t i=0; i<pattern.length(); ++i) {
printf("%c", pattern.charAt(i));
}
printf(" with pattern:");
for (int32_t i=0; i<newPattern.length(); ++i) {
printf("%c", newPattern.charAt(i));
}
printf(" returnedDate:");
for (int32_t i=0; i<dateReturned.length(); ++i) {
printf("%c", dateReturned.charAt(i));
}
*/
if ( format != NULL ) delete format;
if ( zone != NULL ) delete zone;
// ======== Test getSkeletons and getBaseSkeletons
UnicodeString patterns[40];
UnicodeString skeletons[40];
UnicodeString baseSkeletons[40];
int32_t cntSkeletons=0;
int32_t cntBaseSktns=0;
StringEnumeration* ptrSkeletonEnum = gen->getSkeletons(status);
if(U_FAILURE(status)) {
errln("ERROR: Fail to get skeletons !\n");
}
UnicodeString returnPattern, *ptrSkeleton;
ptrSkeletonEnum->reset(status);
int32_t count=ptrSkeletonEnum->count(status);
for (int32_t i=0; i<count; ++i) {
ptrSkeleton = (UnicodeString *)ptrSkeletonEnum->snext(status);
returnPattern = gen->getPatternForSkeleton(*ptrSkeleton);
}
StringEnumeration* ptrBaseSkeletonEnum = gen->getBaseSkeletons(status);
if(U_FAILURE(status)) {
errln("ERROR: Fail to get base skeletons !\n");
}
count=ptrBaseSkeletonEnum->count(status);
for (int32_t i=0; i<count; ++i) {
ptrSkeleton = (UnicodeString *)ptrBaseSkeletonEnum->snext(status);
}
if ( gen != NULL ) delete gen;
// ======= Test various skeletons.
logln("Testing DateTimePatternGenerator with various skeleton");
status = U_ZERO_ERROR;
int32_t localeIndex=0;
int32_t resultIndex=0;
UnicodeString resultDate;
UDate testDate= LocaleTest::date(99, 0, 13, 23, 58, 59);
while (localeIndex < MAX_LOCALE )
{
int32_t dataIndex=0;
UnicodeString bestPattern;
Locale loc(testLocale[localeIndex][0], testLocale[localeIndex][1], testLocale[localeIndex][2], "");
//printf("\n\n Locale: %s_%s_%s", testLocale[localeIndex][0], testLocale[localeIndex][1], testLocale[localeIndex][2]);
//printf("\n Status:%d", status);
DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status);
if(U_FAILURE(status)) {
errln("ERROR: Could not create DateTimePatternGenerator with locale index:%d .\n", localeIndex);
}
while (patternData[dataIndex].length() > 0) {
bestPattern = patGen->getBestPattern(patternData[dataIndex++], status);
SimpleDateFormat* sdf = new SimpleDateFormat(bestPattern, loc, status);
resultDate = "";
resultDate = sdf->format(testDate, resultDate);
if ( resultDate != patternResults[resultIndex] ) {
errln("\nERROR: Test various skeletons[%d] .", dataIndex-1);
// TODO Remove printf once ICU pick up CLDR 1.5
/*
printf("\nUnmatched result!\n TestPattern:");
for (int32_t i=0; i < patternData[dataIndex-1].length(); ++i) {
printf("%c", patternData[dataIndex-1].charAt(i));
}
printf(" BestPattern:");
for (int32_t i=0; i < bestPattern.length(); ++i) {
printf("%c", bestPattern.charAt(i));
}
printf(" expected result:");
for (int32_t i=0; i < patternResults[resultIndex].length(); ++i) {
printf("%c", patternResults[resultIndex].charAt(i));
}
printf("\n expected result in hex:");
for (int32_t i=0; i < patternResults[resultIndex].length(); ++i) {
printf("0x%x ", patternResults[resultIndex].charAt(i));
}
printf("\n running result:");
for (int32_t i=0; i < resultDate.length(); ++i) {
printf("%c", resultDate.charAt(i));
}
printf(" running result in hex:");
for (int32_t i=0; i < resultDate.length(); ++i) {
printf("0x%x ", resultDate.charAt(i));
}
*/
}
resultIndex++;
delete sdf;
}
delete patGen;
localeIndex++;
}
// ======= Test random skeleton
const char randomChars[80] = {
'1','2','3','4','5','6','7','8','9','0','!','@','#','$','%','^','&','*','(',')',
'`',' ','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r',
's','t','u','v','w','x','y','z','A','B','C','D','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',':',';','<','.','?',';','\\'};
DateTimePatternGenerator *randDTGen= DateTimePatternGenerator::createInstance(status);
if (U_FAILURE(status)) {
dataerrln("ERROR: Could not create DateTimePatternGenerator (Locale::getFrench()) - exitting");
return;
}
for (int32_t i=0; i<10; ++i) {
UnicodeString randomSkeleton="";
int32_t len = rand() % 20;
for (int32_t j=0; j<len; ++j ) {
randomSkeleton += rand()%80;
}
UnicodeString bestPattern = randDTGen->getBestPattern(randomSkeleton, status);
}
delete randDTGen;
// UnicodeString randomString=Unicode
// ======= Test getStaticClassID()
logln("Testing getStaticClassID()");
status = U_ZERO_ERROR;
DateTimePatternGenerator *test= DateTimePatternGenerator::createInstance(status);
if(test->getDynamicClassID() != DateTimePatternGenerator::getStaticClassID()) {
errln("ERROR: getDynamicClassID() didn't return the expected value");
}
if (test!=NULL) {
delete test;
test=NULL;
}
// ====== Test createEmptyInstance()
logln("Testing createEmptyInstance()");
status = U_ZERO_ERROR;
test = DateTimePatternGenerator::createEmptyInstance(status);
if(U_FAILURE(status)) {
errln("ERROR: Fail to create an empty instance !\n");
}
conflictingStatus = test->addPattern(UnicodeString("MMMMd"), true, conflictingPattern, status);
status = U_ZERO_ERROR;
testPattern=test->getBestPattern(UnicodeString("MMMMdd"), status);
conflictingStatus = test->addPattern(UnicodeString("HH:mm"), true, conflictingPattern, status);
conflictingStatus = test->addPattern(UnicodeString("MMMMMd"), true, conflictingPattern, status); //duplicate pattern
StringEnumeration *output=NULL;
output = test->getRedundants(status);
expectedResult=UnicodeString("MMMMd");
if (output != NULL) {
output->reset(status);
const UnicodeString *dupPattern=output->snext(status);
if ( (dupPattern==NULL) || (*dupPattern != expectedResult) ) {
errln("ERROR: Fail in getRedundants !\n");
}
}
if (test!=NULL) {
delete test;
}
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -0,0 +1,31 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2001, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
#ifndef _INTLTESTDATETIMEPATTERNGENERATORAPI
#define _INTLTESTDATETIMEPATTERNGENERATORAPI
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
#include "intltest.h"
/**
* Test basic functionality of various API functions
**/
class IntlTestDateTimePatternGeneratorAPI : public IntlTest {
void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL );
private:
/**
* Performs tests on many API functions, see detailed comments in source code
**/
void testAPI(/* char* par */);
};
#endif /* #if !UCONFIG_NO_FORMATTING */
#endif

View file

@ -597,6 +597,14 @@
RelativePath=".\dtfmttst.h"
>
</File>
<File
RelativePath=".\dtptngts.cpp"
>
</File>
<File
RelativePath=".\dtptngts.h"
>
</File>
<File
RelativePath=".\incaltst.cpp"
>

View file

@ -44,6 +44,8 @@
#include "calcasts.h" // CalendarCaseTest
#include "tzrulets.h" // TimeZoneRuleTest
#include "dadrcal.h" // DataDrivenCalendarTest
#include "dtptngts.h" // IntlTestDateTimePatternGeneratorAPI
#define TESTCLASS(id, TestClass) \
case id: \
@ -105,6 +107,8 @@ void IntlTestFormat::runIndexedTest( int32_t index, UBool exec, const char* &nam
TESTCLASS(28,CalendarCaseTest);
TESTCLASS(29,TimeZoneRuleTest);
TESTCLASS(30,DataDrivenCalendarTest);
TESTCLASS(31,IntlTestDateTimePatternGeneratorAPI);
default: name = ""; break; //needed to end loop
}