ICU-4732 Default century support in Persian calendar.

X-SVN-Rev: 24130
This commit is contained in:
Yoshito Umaoka 2008-06-09 21:37:46 +00:00
parent c504eafdc8
commit 7c178f621e
2 changed files with 124 additions and 11 deletions

View file

@ -12,10 +12,14 @@
* 9/23/2003 mehran posted to icu-design
*****************************************************************************
*/
#include "persncal.h"
#if !UCONFIG_NO_FORMATTING
#include "umutex.h"
#include <float.h>
static const int8_t monthDays[] = { 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 };
static int32_t
@ -371,19 +375,89 @@ PersianCalendar::inDaylightTime(UErrorCode& status) const
return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE);
}
// default century
const UDate PersianCalendar::fgSystemDefaultCentury = DBL_MIN;
const int32_t PersianCalendar::fgSystemDefaultCenturyYear = -1;
UDate PersianCalendar::fgSystemDefaultCenturyStart = DBL_MIN;
int32_t PersianCalendar::fgSystemDefaultCenturyStartYear = -1;
UBool PersianCalendar::haveDefaultCentury() const
{
return FALSE;
return TRUE;
}
UDate PersianCalendar::defaultCenturyStart() const
{
return -1;
return internalGetDefaultCenturyStart();
}
int32_t PersianCalendar::defaultCenturyStartYear() const
{
return -1;
return internalGetDefaultCenturyStartYear();
}
UDate
PersianCalendar::internalGetDefaultCenturyStart() const
{
// lazy-evaluate systemDefaultCenturyStart
UBool needsUpdate;
UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
if (needsUpdate) {
initializeSystemDefaultCentury();
}
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStart
return fgSystemDefaultCenturyStart;
}
int32_t
PersianCalendar::internalGetDefaultCenturyStartYear() const
{
// lazy-evaluate systemDefaultCenturyStartYear
UBool needsUpdate;
UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate);
if (needsUpdate) {
initializeSystemDefaultCentury();
}
// use defaultCenturyStart unless it's the flag value;
// then use systemDefaultCenturyStartYear
return fgSystemDefaultCenturyStartYear;
}
void
PersianCalendar::initializeSystemDefaultCentury()
{
// initialize systemDefaultCentury and systemDefaultCenturyYear based
// on the current time. They'll be set to 80 years before
// the current time.
// No point in locking as it should be idempotent.
if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury)
{
UErrorCode status = U_ZERO_ERROR;
PersianCalendar calendar(Locale("@calendar=persian"),status);
if (U_SUCCESS(status))
{
calendar.setTime(Calendar::getNow(), status);
calendar.add(UCAL_YEAR, -80, status);
UDate newStart = calendar.getTime(status);
int32_t newYear = calendar.get(UCAL_YEAR, status);
{
umtx_lock(NULL);
fgSystemDefaultCenturyStart = newStart;
fgSystemDefaultCenturyStartYear = newYear;
umtx_unlock(NULL);
}
}
// We have no recourse upon failure unless we want to propagate the failure
// out.
}
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(PersianCalendar)

View file

@ -1,6 +1,6 @@
/*
******************************************************************************
* Copyright (C) 2003-2007, International Business Machines Corporation
* Copyright (C) 2003-2008, International Business Machines Corporation
* and others. All Rights Reserved.
******************************************************************************
*
@ -279,7 +279,6 @@ class PersianCalendar : public Calendar {
private:
PersianCalendar(); // default constructor not implemented
// Default century.
protected:
/**
@ -293,27 +292,67 @@ class PersianCalendar : public Calendar {
*/
virtual UBool inDaylightTime(UErrorCode& status) const;
/**
* Returns FALSE because the Persian Calendar does not have a default century
* Returns TRUE because the Persian Calendar does have a default century
* @internal
*/
virtual UBool haveDefaultCentury() const;
/**
* Returns -1
* @return -1
* Returns the date of the start of the default century
* @return start of century - in milliseconds since epoch, 1970
* @internal
*/
virtual UDate defaultCenturyStart() const;
/**
* Returns -1
* Returns the year in which the default century begins
* @internal
*/
virtual int32_t defaultCenturyStartYear() const;
private: // default century stuff.
/**
* The system maintains a static default century start date. This is initialized
* the first time it is used. Before then, it is set to SYSTEM_DEFAULT_CENTURY to
* indicate an uninitialized state. Once the system default century date and year
* are set, they do not change.
*/
static UDate fgSystemDefaultCenturyStart;
/**
* See documentation for systemDefaultCenturyStart.
*/
static int32_t fgSystemDefaultCenturyStartYear;
/**
* Default value that indicates the defaultCenturyStartYear is unitialized
*/
static const int32_t fgSystemDefaultCenturyYear;
/**
* start of default century, as a date
*/
static const UDate fgSystemDefaultCentury;
/**
* Returns the beginning date of the 100-year window that dates
* with 2-digit years are considered to fall within.
*/
UDate internalGetDefaultCenturyStart(void) const;
/**
* Returns the first year of the 100-year window that dates with
* 2-digit years are considered to fall within.
*/
int32_t internalGetDefaultCenturyStartYear(void) const;
/**
* Initializes the 100-year window that dates with 2-digit years
* are considered to fall within so that its start date is 80 years
* before the current time.
*/
static void initializeSystemDefaultCentury(void);
};
U_NAMESPACE_END