mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 00:43:32 +00:00
ICU-5655 Integrate Mehran Mehr's Persian Calendar support
X-SVN-Rev: 21293
This commit is contained in:
parent
020900f62d
commit
114486b002
8 changed files with 809 additions and 2 deletions
.gitattributes
icu4c/source
2
.gitattributes
vendored
2
.gitattributes
vendored
|
@ -80,6 +80,8 @@ icu4c/source/data/mappings/ibm-950_P110_P100-1999.ucm -text
|
|||
icu4c/source/data/mappings/ibm-954_P101_P101-2000.ucm -text
|
||||
icu4c/source/data/mappings/ibm-964_P110_P100-1999.ucm -text
|
||||
icu4c/source/data/mappings/ibm-970_P110_P110-2006.ucm -text
|
||||
icu4c/source/i18n/persncal.cpp -text
|
||||
icu4c/source/i18n/persncal.h -text
|
||||
icu4c/source/samples/ucnv/data02.bin -text
|
||||
icu4c/source/test/testdata/icu26_testtypes.res -text
|
||||
icu4c/source/test/testdata/icu26e_testtypes.res -text
|
||||
|
|
|
@ -65,7 +65,7 @@ ucurr.o digitlst.o fmtable_cnv.o \
|
|||
choicfmt.o datefmt.o smpdtfmt.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 islamcal.o japancal.o gregoimp.o hebrwcal.o \
|
||||
astro.o buddhcal.o persncal.o islamcal.o japancal.o gregoimp.o hebrwcal.o \
|
||||
coleitr.o coll.o tblcoll.o sortkey.o bocsu.o ucoleitr.o \
|
||||
ucol.o ucol_res.o ucol_bld.o ucol_sit.o ucol_tok.o ucol_wgt.o ucol_cnt.o ucol_elm.o \
|
||||
strmatch.o usearch.o search.o stsearch.o \
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "japancal.h"
|
||||
#include "islamcal.h"
|
||||
#include "hebrwcal.h"
|
||||
#include "persncal.h"
|
||||
//#include "chnsecal.h"
|
||||
#include "unicode/calendar.h"
|
||||
#include "cpputils.h"
|
||||
|
@ -155,6 +156,7 @@ static const char * const gCalendarKeywords[] = {
|
|||
"gregorian",
|
||||
"japanese",
|
||||
"buddhist",
|
||||
"persian",
|
||||
"islamic-civil",
|
||||
"islamic",
|
||||
"hebrew",
|
||||
|
@ -209,6 +211,8 @@ static Calendar *createStandardCalendar(char *calType, const Locale &canLoc, UEr
|
|||
return new IslamicCalendar(canLoc, status, IslamicCalendar::ASTRONOMICAL);
|
||||
} else if(!uprv_strcmp(calType, "hebrew")) {
|
||||
return new HebrewCalendar(canLoc, status);
|
||||
} else if(!uprv_strcmp(calType, "persian")) {
|
||||
return new PersianCalendar(canLoc, status);
|
||||
//} else if(!uprv_strcmp(calType, "chinese")) {
|
||||
//return new ChineseCalendar(canLoc, status);
|
||||
} else {
|
||||
|
|
|
@ -883,6 +883,14 @@
|
|||
RelativePath=".\islamcal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\persncal.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\persncal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\japancal.cpp"
|
||||
>
|
||||
|
|
404
icu4c/source/i18n/persncal.cpp
Normal file
404
icu4c/source/i18n/persncal.cpp
Normal file
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* Copyright (C) 2003-2007, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
*
|
||||
* File PERSNCAL.CPP
|
||||
*
|
||||
* Modification History:
|
||||
*
|
||||
* Date Name Description
|
||||
* 9/23/2003 mehran posted to icu-design
|
||||
*****************************************************************************
|
||||
*/
|
||||
#include "persncal.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
static const int monthDays[] = { 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 };
|
||||
|
||||
static int32_t
|
||||
jalali_to_julian (int year, int month, int day)
|
||||
{
|
||||
int32_t daysNo=0;
|
||||
int i;
|
||||
|
||||
year = year -475+2820;
|
||||
month -= 1;
|
||||
|
||||
daysNo=(year/2820)*1029983;
|
||||
year=year % 2820;
|
||||
|
||||
daysNo+=(year/128)* 46751;
|
||||
if((year/128)>21)
|
||||
{
|
||||
daysNo-=46751;
|
||||
year=(year%128)+128;
|
||||
}
|
||||
else
|
||||
year=year%128;
|
||||
|
||||
if(year>=29)
|
||||
{
|
||||
year-=29;
|
||||
daysNo+=10592;
|
||||
}
|
||||
|
||||
if(year>=66)
|
||||
{
|
||||
year-=66;
|
||||
daysNo+=24106;
|
||||
}
|
||||
else if( year>=33)
|
||||
{
|
||||
daysNo+=(year/33)* 12053;
|
||||
year=year%33;
|
||||
}
|
||||
|
||||
if (year >= 5)
|
||||
{
|
||||
daysNo += 1826;
|
||||
year -=5;
|
||||
}
|
||||
else if (year == 4)
|
||||
{
|
||||
daysNo += 1460;
|
||||
year -=4;
|
||||
}
|
||||
|
||||
daysNo += 1461 * (year/4);
|
||||
year %= 4;
|
||||
daysNo += 365 * year;
|
||||
|
||||
for (i = 0; i < month; i++)
|
||||
daysNo += monthDays[i];
|
||||
|
||||
daysNo += day;
|
||||
|
||||
return daysNo-856493;
|
||||
|
||||
}
|
||||
|
||||
static void julian_to_jalali (int32_t daysNo, int *h_y, int *h_m, int *h_d)
|
||||
{
|
||||
int year=0, month=0, day=0,scalarDays=0;
|
||||
int i,yearOffset,monthOffset;
|
||||
|
||||
daysNo+=856493;
|
||||
scalarDays=daysNo;
|
||||
year=(daysNo/1029983)*2820;
|
||||
daysNo=daysNo%1029983;
|
||||
|
||||
if((daysNo/46751)<=21)
|
||||
{
|
||||
year+=(daysNo/46751)* 128;
|
||||
daysNo=daysNo%46751;
|
||||
}
|
||||
else
|
||||
{
|
||||
year+=(daysNo/46751)* 128;
|
||||
daysNo=daysNo%46751;
|
||||
year-=128;
|
||||
daysNo+=46751;
|
||||
}
|
||||
|
||||
if (daysNo >= 10592)
|
||||
{
|
||||
year+= 29;
|
||||
daysNo -= 10592;
|
||||
}
|
||||
|
||||
if(daysNo>=24106)
|
||||
{
|
||||
daysNo-=24106;
|
||||
year+=66;
|
||||
}
|
||||
|
||||
if(daysNo>=12053)
|
||||
{
|
||||
daysNo-=12053;
|
||||
year+=33;
|
||||
}
|
||||
|
||||
|
||||
if (daysNo >= 1826)
|
||||
{
|
||||
year+= 5;
|
||||
daysNo -= 1826;
|
||||
}
|
||||
else if (daysNo > 1095)
|
||||
{
|
||||
year+= 3;
|
||||
daysNo -= 1095;
|
||||
|
||||
}
|
||||
|
||||
year +=(4 * (daysNo/1461));
|
||||
daysNo %= 1461;
|
||||
|
||||
if (daysNo == 0)
|
||||
{
|
||||
year -= 1;
|
||||
daysNo = 366;
|
||||
}
|
||||
else
|
||||
{
|
||||
year += daysNo/365;
|
||||
daysNo = daysNo % 365;
|
||||
if (daysNo == 0)
|
||||
{
|
||||
year -= 1;
|
||||
daysNo = 365;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < 11 && daysNo > monthDays[i]; ++i)
|
||||
|
||||
daysNo -= monthDays[i];
|
||||
|
||||
month = i + 1;
|
||||
|
||||
day = daysNo;
|
||||
|
||||
*h_d = day;
|
||||
*h_m = month;
|
||||
*h_y = year-2345;
|
||||
}
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// Implementation of the PersianCalendar class
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Constructors...
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
const char *PersianCalendar::getType() const {
|
||||
return "persian";
|
||||
}
|
||||
|
||||
Calendar* PersianCalendar::clone() const {
|
||||
return new PersianCalendar(*this);
|
||||
}
|
||||
|
||||
PersianCalendar::PersianCalendar(const Locale& aLocale, UErrorCode& success)
|
||||
: Calendar(TimeZone::createDefault(), aLocale, success)
|
||||
{
|
||||
setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
|
||||
}
|
||||
|
||||
PersianCalendar::PersianCalendar(const PersianCalendar& other) : Calendar(other) {
|
||||
}
|
||||
|
||||
PersianCalendar::~PersianCalendar()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Minimum / Maximum access functions
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
static const int32_t LIMITS[UCAL_FIELD_COUNT][4] = {
|
||||
// Minimum Greatest Least Maximum
|
||||
// Minimum Maximum
|
||||
{ 0, 0, 0, 0 }, // ERA
|
||||
{ -2500, -2500, 2500, 2500 }, // YEAR
|
||||
{ 0, 0, 11, 11 }, // MONTH
|
||||
{ 1, 1, 52, 53 }, // WEEK_OF_YEAR
|
||||
{ 0, 0, 5, 6 }, // WEEK_OF_MONTH
|
||||
{ 1, 1, 29, 31 }, // DAY_OF_MONTH
|
||||
{ 1, 1, 365, 366 }, // DAY_OF_YEAR
|
||||
{ 0, 0, 6, 6 }, // DAY_OF_WEEK
|
||||
{ 1, 1, 4, 6 }, // DAY_OF_WEEK_IN_MONTH
|
||||
{ 0, 0, 1, 1 }, // AM_PM
|
||||
{ 0, 0, 11, 11 }, // HOUR
|
||||
{ 0, 0, 23, 23 }, // HOUR_OF_DAY
|
||||
{ 0, 0, 59, 59 }, // MINUTE
|
||||
{ 0, 0, 59, 59 }, // SECOND
|
||||
{ 0, 0, 999, 999 }, // MILLISECOND
|
||||
{ -12, -12, 12, 12 }, // ZONE_OFFSET
|
||||
{ 0, 0, 1, 1 }, // DST_OFFSET
|
||||
{ -140742, -140742, 144683, 140742 }, // YEAR_WOY
|
||||
{ 0, 0, 6, 6 }, // DOW_LOCAL
|
||||
{ -2500, -2500, 2500, 2500 }, // EXTENDED_YEAR
|
||||
{/* -1, -1, -1, -1 */}, // JULIAN_DAY
|
||||
{/* -1, -1, -1, -1 */}, // MILLISECONDS_IN_DAY
|
||||
};
|
||||
static const int32_t MONTH_COUNT[12][4] = {
|
||||
//len len2 st st2
|
||||
{ 31, 31, 0, 0 }, // Farvardin
|
||||
{ 31, 31, 31, 31 }, // Ordibehesht
|
||||
{ 31, 31, 62, 62 }, // Khordad
|
||||
{ 31, 31, 93, 93 }, // Tir
|
||||
{ 31, 31, 124, 124 }, // Mordad
|
||||
{ 31, 31, 155, 155 }, // Shahrivar
|
||||
{ 30, 30, 186, 186 }, // Mehr
|
||||
{ 30, 30, 216, 216 }, // Aban
|
||||
{ 30, 30, 246, 246 }, // Azar
|
||||
{ 30, 30, 276, 276 }, // Dey
|
||||
{ 30, 30, 306, 306 }, // Bahman
|
||||
{ 29, 30, 336, 336 } // Esfand
|
||||
// len length of month
|
||||
// len2 length of month in a leap year
|
||||
// st days in year before start of month
|
||||
// st2 days in year before month in leap year
|
||||
};
|
||||
|
||||
/**
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
int32_t PersianCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const {
|
||||
return LIMITS[field][limitType];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Assorted calculation utilities
|
||||
//
|
||||
|
||||
/**
|
||||
* Determine whether a year is a leap year in the Persian calendar
|
||||
*/
|
||||
UBool PersianCalendar::isLeapYear(int32_t year)
|
||||
{
|
||||
return jalali_to_julian(year+1,1,1)-jalali_to_julian(year,1,1) == 366;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the day # on which the given year starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*/
|
||||
int32_t PersianCalendar::yearStart(int32_t year) {
|
||||
return handleComputeMonthStart(year,1,FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the day # on which the given month starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*
|
||||
* @param year The hijri shamsi year
|
||||
* @param year The hijri shamsi month, 0-based
|
||||
*/
|
||||
int32_t PersianCalendar::monthStart(int32_t year, int32_t month) const {
|
||||
return handleComputeMonthStart(year,month,FALSE);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Calendar framework
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return the length (in days) of the given month.
|
||||
*
|
||||
* @param year The hijri shamsi year
|
||||
* @param year The hijri shamsi month, 0-based
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
int32_t PersianCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const {
|
||||
return MONTH_COUNT[month][PersianCalendar::isLeapYear(extendedYear)?1:0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of days in the given Persian year
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
int32_t PersianCalendar::handleGetYearLength(int32_t extendedYear) const {
|
||||
return 365 + (PersianCalendar::isLeapYear(extendedYear) ? 1 : 0);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions for converting from field values to milliseconds....
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Return JD of start of given month/year
|
||||
/**
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
int32_t PersianCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool useMonth) const {
|
||||
// If the month is out of range, adjust it into range, and
|
||||
// modify the extended year value accordingly.
|
||||
if (month < 0 || month > 11) {
|
||||
eyear += month / 12;
|
||||
month = month % 12;
|
||||
}
|
||||
return jalali_to_julian(eyear,useMonth?month+1:1,1)-1+1947955L;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions for converting from milliseconds to field values
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
int32_t PersianCalendar::handleGetExtendedYear() {
|
||||
int32_t year;
|
||||
if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
|
||||
year = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
|
||||
} else {
|
||||
year = internalGet(UCAL_YEAR, 1); // Default to year 1
|
||||
}
|
||||
return year;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override Calendar to compute several fields specific to the Persian
|
||||
* calendar system. These are:
|
||||
*
|
||||
* <ul><li>ERA
|
||||
* <li>YEAR
|
||||
* <li>MONTH
|
||||
* <li>DAY_OF_MONTH
|
||||
* <li>DAY_OF_YEAR
|
||||
* <li>EXTENDED_YEAR</ul>
|
||||
*
|
||||
* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
|
||||
* method is called. The getGregorianXxx() methods return Gregorian
|
||||
* calendar equivalents for the given Julian day.
|
||||
* @draft ICU 3.8
|
||||
*/
|
||||
void PersianCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/) {
|
||||
int jy,jm,jd;
|
||||
julian_to_jalali(julianDay-1947955L,&jy,&jm,&jd);
|
||||
internalSet(UCAL_ERA, 0);
|
||||
internalSet(UCAL_YEAR, jy);
|
||||
internalSet(UCAL_EXTENDED_YEAR, jy);
|
||||
internalSet(UCAL_MONTH, jm-1);
|
||||
internalSet(UCAL_DAY_OF_MONTH, jd);
|
||||
internalSet(UCAL_DAY_OF_YEAR, jd + MONTH_COUNT[jm-1][2]);
|
||||
}
|
||||
|
||||
UBool
|
||||
PersianCalendar::inDaylightTime(UErrorCode& status) const
|
||||
{
|
||||
// copied from GregorianCalendar
|
||||
if (U_FAILURE(status) || !getTimeZone().useDaylightTime())
|
||||
return FALSE;
|
||||
|
||||
// Force an update of the state of the Calendar.
|
||||
((PersianCalendar*)this)->complete(status); // cast away const
|
||||
|
||||
return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE);
|
||||
}
|
||||
|
||||
UBool PersianCalendar::haveDefaultCentury() const
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UDate PersianCalendar::defaultCenturyStart() const
|
||||
{
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
int32_t PersianCalendar::defaultCenturyStartYear() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(PersianCalendar)
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
324
icu4c/source/i18n/persncal.h
Normal file
324
icu4c/source/i18n/persncal.h
Normal file
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* Copyright (C) 2003-2007, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
*
|
||||
* File PERSNCAL.H
|
||||
*
|
||||
* Modification History:
|
||||
*
|
||||
* Date Name Description
|
||||
* 9/23/2003 mehran posted to icu-design
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef PERSNCAL_H
|
||||
#define PERSNCAL_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/calendar.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* <code>PersianCalendar</code> is a subclass of <code>Calendar</code>
|
||||
* that implements the Persian calendar. It is used as the official
|
||||
* calendar in Iran. This calendar is also known as the "Hijri Shamsi"
|
||||
* calendar, since it starts at the time of Mohammed's emigration (or
|
||||
* "hijra") to Medinah on Thursday, July 15, 622 AD (Julian) and is a
|
||||
* solar calendar system (or "shamsi").
|
||||
* <p>
|
||||
* The Persian calendar is strictly solar, and thus a Persian year has twelve
|
||||
* solar months. A Persian year is about 365 days long, except in leap years
|
||||
* which is 366 days long.
|
||||
* <p>
|
||||
* The six first months of Persian Calendar are 31 days long. The next five
|
||||
* months are 30 days long. The last month is 29 days long in normal years,
|
||||
* and 30 days long in leap years.
|
||||
*
|
||||
* @see GregorianCalendar
|
||||
*
|
||||
* @author Mehran Mehr
|
||||
* @internal
|
||||
*/
|
||||
class U_I18N_API PersianCalendar : public Calendar {
|
||||
public:
|
||||
//-------------------------------------------------------------------------
|
||||
// Constants...
|
||||
//-------------------------------------------------------------------------
|
||||
/**
|
||||
* Constants for the months
|
||||
* @internal
|
||||
*/
|
||||
enum EMonths {
|
||||
/**
|
||||
* Constant for Farvardin, the 1st month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
FARVARDIN = 0,
|
||||
|
||||
/**
|
||||
* Constant for Ordibehesht, the 2nd month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
ORDIBEHESHT = 1,
|
||||
|
||||
/**
|
||||
* Constant for Khordad, the 3rd month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
KHORDAD = 2,
|
||||
|
||||
/**
|
||||
* Constant for Tir, the 4th month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
TIR = 3,
|
||||
|
||||
/**
|
||||
* Constant for Mordad, the 5th month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
MORDAD = 4,
|
||||
|
||||
/**
|
||||
* Constant for Shahrivar, the 6th month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
SHAHRIVAR = 5,
|
||||
|
||||
/**
|
||||
* Constant for Mehr, the 7th month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
MEHR = 6,
|
||||
|
||||
/**
|
||||
* Constant for Aban, the 8th month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
ABAN = 7,
|
||||
|
||||
/**
|
||||
* Constant for Azar, the 9th month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
AZAR = 8,
|
||||
|
||||
/**
|
||||
* Constant for Dei, the 10th month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
DEI = 9,
|
||||
|
||||
/**
|
||||
* Constant for Bahman, the 11th month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
BAHMAN = 10,
|
||||
|
||||
/**
|
||||
* Constant for Esfand, the 12th month of the Persian year.
|
||||
* @internal
|
||||
*/
|
||||
ESFAND = 11,
|
||||
|
||||
PERSIAN_MONTH_MAX
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Constructors...
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs a PersianCalendar based on the current time in the default time zone
|
||||
* with the given locale.
|
||||
*
|
||||
* @param aLocale The given locale.
|
||||
* @param success Indicates the status of PersianCalendar object construction.
|
||||
* Returns U_ZERO_ERROR if constructed successfully.
|
||||
* @internal
|
||||
*/
|
||||
PersianCalendar(const Locale& aLocale, UErrorCode &success);
|
||||
|
||||
/**
|
||||
* Copy Constructor
|
||||
* @internal
|
||||
*/
|
||||
PersianCalendar(const PersianCalendar& other);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* @internal
|
||||
*/
|
||||
virtual ~PersianCalendar();
|
||||
|
||||
// TODO: copy c'tor, etc
|
||||
|
||||
// clone
|
||||
virtual Calendar* clone() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Determine whether a year is a leap year in the Persian calendar
|
||||
*/
|
||||
static UBool isLeapYear(int32_t year);
|
||||
|
||||
/**
|
||||
* Return the day # on which the given year starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*/
|
||||
int32_t yearStart(int32_t year);
|
||||
|
||||
/**
|
||||
* Return the day # on which the given month starts. Days are counted
|
||||
* from the Hijri epoch, origin 0.
|
||||
*
|
||||
* @param year The hijri shamsi year
|
||||
* @param year The hijri shamsi month, 0-based
|
||||
*/
|
||||
int32_t monthStart(int32_t year, int32_t month) const;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Calendar framework
|
||||
//----------------------------------------------------------------------
|
||||
protected:
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const;
|
||||
|
||||
/**
|
||||
* Return the length (in days) of the given month.
|
||||
*
|
||||
* @param year The hijri shamsi year
|
||||
* @param year The hijri shamsi month, 0-based
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const;
|
||||
|
||||
/**
|
||||
* Return the number of days in the given Persian year
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetYearLength(int32_t extendedYear) const;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions for converting from field values to milliseconds....
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Return JD of start of given month/year
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month, UBool useMonth) const;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Functions for converting from milliseconds to field values
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t handleGetExtendedYear();
|
||||
|
||||
/**
|
||||
* Override Calendar to compute several fields specific to the Persian
|
||||
* calendar system. These are:
|
||||
*
|
||||
* <ul><li>ERA
|
||||
* <li>YEAR
|
||||
* <li>MONTH
|
||||
* <li>DAY_OF_MONTH
|
||||
* <li>DAY_OF_YEAR
|
||||
* <li>EXTENDED_YEAR</ul>
|
||||
*
|
||||
* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
|
||||
* method is called. The getGregorianXxx() methods return Gregorian
|
||||
* calendar equivalents for the given Julian day.
|
||||
* @internal
|
||||
*/
|
||||
virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);
|
||||
|
||||
// UObject stuff
|
||||
public:
|
||||
/**
|
||||
* @return The class ID for this object. All objects of a given class have the
|
||||
* same class ID. Objects of other classes have different class IDs.
|
||||
* @internal
|
||||
*/
|
||||
virtual UClassID getDynamicClassID(void) const;
|
||||
|
||||
/**
|
||||
* Return the class ID for this class. This is useful only for comparing to a return
|
||||
* value from getDynamicClassID(). For example:
|
||||
*
|
||||
* Base* polymorphic_pointer = createPolymorphicObject();
|
||||
* if (polymorphic_pointer->getDynamicClassID() ==
|
||||
* Derived::getStaticClassID()) ...
|
||||
*
|
||||
* @return The class ID for all objects of this class.
|
||||
* @internal
|
||||
*/
|
||||
static UClassID U_EXPORT2 getStaticClassID(void);
|
||||
|
||||
/**
|
||||
* return the calendar type, "persian".
|
||||
*
|
||||
* @return calendar type
|
||||
* @internal
|
||||
*/
|
||||
virtual const char * getType() const;
|
||||
|
||||
private:
|
||||
PersianCalendar(); // default constructor not implemented
|
||||
|
||||
// Default century.
|
||||
protected:
|
||||
|
||||
/**
|
||||
* (Overrides Calendar) Return true if the current date for this Calendar is in
|
||||
* Daylight Savings Time. Recognizes DST_OFFSET, if it is set.
|
||||
*
|
||||
* @param status Fill-in parameter which receives the status of this operation.
|
||||
* @return True if the current date for this Calendar is in Daylight Savings Time,
|
||||
* false, otherwise.
|
||||
* @internal
|
||||
*/
|
||||
virtual UBool inDaylightTime(UErrorCode& status) const;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns FALSE because the Persian Calendar does not have a default century
|
||||
* @internal
|
||||
*/
|
||||
virtual UBool haveDefaultCentury() const;
|
||||
|
||||
/**
|
||||
* Returns -1
|
||||
* @return -1
|
||||
* @internal
|
||||
*/
|
||||
virtual UDate defaultCenturyStart() const;
|
||||
|
||||
/**
|
||||
* Returns -1
|
||||
* @internal
|
||||
*/
|
||||
virtual int32_t defaultCenturyStartYear() const;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -75,6 +75,8 @@ void IntlCalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &n
|
|||
CASE(4,TestBuddhistFormat);
|
||||
CASE(5,TestJapaneseFormat);
|
||||
CASE(6,TestJapanese3860);
|
||||
CASE(7,TestPersian);
|
||||
CASE(8,TestPersianFormat);
|
||||
default: name = ""; break;
|
||||
}
|
||||
}
|
||||
|
@ -657,6 +659,66 @@ void IntlCalendarTest::TestJapanese3860()
|
|||
delete fmt2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Verify the Persian Calendar.
|
||||
*/
|
||||
void IntlCalendarTest::TestPersian() {
|
||||
UDate timeA = Calendar::getNow();
|
||||
|
||||
Calendar *cal;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
cal = Calendar::createInstance("fa_IR@calendar=persian", status);
|
||||
CHECK(status, UnicodeString("Creating fa_IR@calendar=persian calendar"));
|
||||
// Sanity check the calendar
|
||||
UDate timeB = Calendar::getNow();
|
||||
UDate timeCal = cal->getTime(status);
|
||||
|
||||
if(!(timeA <= timeCal) || !(timeCal <= timeB)) {
|
||||
errln((UnicodeString)"Error: Calendar time " + timeCal +
|
||||
" is not within sampled times [" + timeA + " to " + timeB + "]!");
|
||||
}
|
||||
// end sanity check
|
||||
// quasiGregorianTest(*cal,Locale("ja_JP"),data);
|
||||
delete cal;
|
||||
}
|
||||
|
||||
void IntlCalendarTest::TestPersianFormat() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale(" en_US@calendar=persian"), status);
|
||||
CHECK(status, "creating date format instance");
|
||||
SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status);
|
||||
CHECK(status, "creating gregorian date format instance");
|
||||
UnicodeString gregorianDate("January 18, 2007 AD");
|
||||
UDate aDate = fmt2->parse(gregorianDate, status);
|
||||
if(!fmt) {
|
||||
errln("Coudln't create en_US instance");
|
||||
} else {
|
||||
UnicodeString str;
|
||||
fmt->format(aDate, str);
|
||||
logln(UnicodeString() + "as Persian Calendar: " + escape(str));
|
||||
UnicodeString expected("Dey 28, 1385 AP");
|
||||
if(str != expected) {
|
||||
errln("Expected " + escape(expected) + " but got " + escape(str));
|
||||
}
|
||||
UDate otherDate = fmt->parse(expected, status);
|
||||
if(otherDate != aDate) {
|
||||
UnicodeString str3;
|
||||
fmt->format(otherDate, str3);
|
||||
errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate + ", " + escape(str3));
|
||||
} else {
|
||||
logln("Parsed OK: " + expected);
|
||||
}
|
||||
delete fmt;
|
||||
}
|
||||
delete fmt2;
|
||||
|
||||
CHECK(status, "Error occured testing Persian Calendar in English ");
|
||||
}
|
||||
|
||||
|
||||
void IntlCalendarTest::simpleTest(const Locale& loc, const UnicodeString& expect, UDate expectDate, UErrorCode& status)
|
||||
{
|
||||
UnicodeString tmp;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 1997-2005, International Business Machines Corporation and
|
||||
* Copyright (c) 1997-2007, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
|
||||
|
@ -30,6 +30,9 @@ public:
|
|||
void TestJapanese(void);
|
||||
void TestJapaneseFormat(void);
|
||||
void TestJapanese3860(void);
|
||||
|
||||
void TestPersian(void);
|
||||
void TestPersianFormat(void);
|
||||
|
||||
protected:
|
||||
// Test a Gregorian-Like calendar
|
||||
|
|
Loading…
Add table
Reference in a new issue