home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / i18n / datefmt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-19  |  10.5 KB  |  368 lines

  1. /*
  2. ********************************************************************************
  3. *                                                                              *
  4. * COPYRIGHT:                                                                   *
  5. *   (C) Copyright Taligent, Inc.,  1997                                        *
  6. *   (C) Copyright International Business Machines Corporation,  1997-1998      *
  7. *   Licensed Material - Program-Property of IBM - All Rights Reserved.         *
  8. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  9. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  10. *                                                                              *
  11. ********************************************************************************
  12. *
  13. * File DATEFMT.CPP
  14. *
  15. * Modification History:
  16. *
  17. *   Date        Name        Description
  18. *   02/19/97    aliu        Converted from java.
  19. *   03/31/97    aliu        Modified extensively to work with 50 locales.
  20. *   04/01/97    aliu        Added support for centuries.
  21. *   08/12/97    aliu        Fixed operator== to use Calendar::equivalentTo.
  22. *    07/20/98    stephen        Changed ParsePosition initialization
  23. ********************************************************************************
  24. */
  25.  
  26. #include "datefmt.h"
  27. #include "smpdtfmt.h"
  28. #include "mutex.h"
  29. #include "resbund.h"
  30.  
  31. // *****************************************************************************
  32. // class DateFormat
  33. // *****************************************************************************
  34.  
  35. int32_t         DateFormat::fgLocalesCount;
  36. const Locale*   DateFormat::fgLocales = 0;
  37.  
  38. DateFormat::DateFormat()
  39. :   fCalendar(0),
  40.     fNumberFormat(0)
  41. {
  42. }
  43.  
  44. //----------------------------------------------------------------------
  45.  
  46. DateFormat::DateFormat(const DateFormat& other)
  47. :   fCalendar(0),
  48.     fNumberFormat(0)
  49. {
  50.     *this = other;
  51. }
  52.  
  53. //----------------------------------------------------------------------
  54.  
  55. DateFormat& DateFormat::operator=(const DateFormat& other)
  56. {
  57.     if (this != &other)
  58.     {
  59.         delete fCalendar;
  60.         delete fNumberFormat;
  61.         fCalendar = other.fCalendar->clone();
  62.         fNumberFormat = (NumberFormat*)other.fNumberFormat->clone();
  63.     }
  64.     return *this;
  65. }
  66.  
  67. //----------------------------------------------------------------------
  68.  
  69. DateFormat::~DateFormat()
  70. {
  71.     delete fCalendar;
  72.     delete fNumberFormat;
  73. }
  74.  
  75. //----------------------------------------------------------------------
  76.  
  77. bool_t
  78. DateFormat::operator==(const Format& other) const
  79. {
  80.     // This protected comparison operator should only be called by subclasses
  81.     // which have confirmed that the other object being compared against is
  82.     // an instance of a sublcass of DateFormat.  THIS IS IMPORTANT.
  83.  
  84.     // We only dereference this pointer after we have confirmed below that
  85.     // 'other' is a DateFormat subclass.
  86.     DateFormat* fmt = (DateFormat*)&other;
  87.  
  88.     return (this == fmt) ||
  89.         ((getDynamicClassID() == other.getDynamicClassID()) &&
  90.          fCalendar->equivalentTo(*fmt->fCalendar) &&
  91.          (*fNumberFormat == *fmt->fNumberFormat));
  92. }
  93.  
  94. //----------------------------------------------------------------------
  95.  
  96. UnicodeString&
  97. DateFormat::format(const Formattable& obj,
  98.                    UnicodeString& toAppendTo,
  99.                    FieldPosition& fieldPosition,
  100.                    UErrorCode& status) const
  101. {
  102.     if (U_FAILURE(status)) return toAppendTo;
  103.  
  104.     // if the type of the Formattable is double or long, treat it as if it were a Date
  105.     switch (obj.getType())
  106.     {
  107.     case Formattable::kDate:
  108.         format(obj.getDate(), toAppendTo, fieldPosition);
  109.         break;
  110.     case Formattable::kDouble:
  111.         format((UDate)obj.getDouble(), toAppendTo, fieldPosition);
  112.         break;
  113.     case Formattable::kLong:
  114.         format((UDate)obj.getLong(), toAppendTo, fieldPosition);
  115.         break;
  116.     default:
  117.         status = U_ILLEGAL_ARGUMENT_ERROR;
  118.         return toAppendTo;
  119.     }
  120.  
  121.     // Is this right?
  122.     //if (fieldPosition.getBeginIndex() == fieldPosition.getEndIndex())
  123.     //  status = U_ILLEGAL_ARGUMENT_ERROR;
  124.  
  125.     return toAppendTo;
  126. }
  127.  
  128. //----------------------------------------------------------------------
  129.  
  130. UnicodeString&
  131. DateFormat::format(UDate date, UnicodeString& result) const
  132. {
  133.     // Note that any error information is just lost.  That's okay
  134.     // for this convenience method.
  135.     FieldPosition fpos(0);
  136.     format(date, result, fpos);
  137.     return result;
  138. }
  139.  
  140. //----------------------------------------------------------------------
  141.  
  142. UDate
  143. DateFormat::parse(const UnicodeString& text,
  144.                   UErrorCode& status) const
  145. {
  146.     if (U_FAILURE(status)) return 0;
  147.  
  148.     ParsePosition pos(0);
  149.     UDate result = parse(text, pos);
  150.     if (pos.getIndex() == 0) status = U_ILLEGAL_ARGUMENT_ERROR;
  151.     return result;
  152. }
  153.  
  154. //----------------------------------------------------------------------
  155.  
  156. void
  157. DateFormat::parseObject(const UnicodeString& source,
  158.                         Formattable& result,
  159.                         ParsePosition& pos) const
  160. {
  161.     result.setDate(parse(source, pos));
  162. }
  163.  
  164. //----------------------------------------------------------------------
  165.  
  166. DateFormat*
  167. DateFormat::createTimeInstance(DateFormat::EStyle style,
  168.                                const Locale& aLocale)
  169. {
  170.     return create(style, kNone, aLocale);
  171. }
  172.  
  173. //----------------------------------------------------------------------
  174.  
  175. DateFormat*
  176. DateFormat::createDateInstance(DateFormat::EStyle style,
  177.                                const Locale& aLocale)
  178. {
  179.     // +4 to set the correct index for getting data out of
  180.     // LocaleElements.
  181.     return create(kNone, (EStyle) (style + kDateOffset), aLocale);
  182. }
  183.  
  184. //----------------------------------------------------------------------
  185.  
  186. DateFormat*
  187. DateFormat::createDateTimeInstance(EStyle dateStyle,
  188.                                    EStyle timeStyle,
  189.                                    const Locale& aLocale)
  190. {
  191.     return create(timeStyle, (EStyle) (dateStyle + kDateOffset), aLocale);
  192. }
  193.  
  194. //----------------------------------------------------------------------
  195.  
  196. DateFormat*
  197. DateFormat::createInstance()
  198. {
  199.     return create(kShort, (EStyle) (kShort + kDateOffset), Locale::getDefault());
  200. }
  201.  
  202. //----------------------------------------------------------------------
  203.  
  204. DateFormat*
  205. DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale)
  206. {
  207.     // Try to create a SimpleDateFormat of the desired style.
  208.     UErrorCode status = U_ZERO_ERROR;
  209.     SimpleDateFormat *f = new SimpleDateFormat(timeStyle, dateStyle, locale, status);
  210.     if (U_SUCCESS(status)) return f;
  211.     delete f;
  212.  
  213.     // If that fails, try to create a format using the default pattern and
  214.     // the DateFormatSymbols for this locale.
  215.     status = U_ZERO_ERROR;
  216.     f = new SimpleDateFormat(locale, status);
  217.     if (U_SUCCESS(status)) return f;
  218.     delete f;
  219.  
  220.     // This should never really happen, because the preceding constructor
  221.     // should always succeed.  If the resource data is unavailable, a last
  222.     // resort object should be returned.
  223.     return 0;
  224. }
  225.  
  226. //----------------------------------------------------------------------
  227.  
  228. const Locale*
  229. DateFormat::getAvailableLocales(int32_t& count)
  230. {
  231.     //  return LocaleData.getAvailableLocales("DateTimePatterns");
  232.  
  233.  
  234.     // We only do this computation once.  Thereafter, we keep it in the static
  235.     // fgLocalesArray.  What we do is iterate over all the locales, and try to
  236.     // load a specific resource from them which indicates that they have
  237.     // date format data.
  238.  
  239.     if (!fgLocales)
  240.     {
  241.         // This is going to load all the locale resource bundles into the
  242.         // cache!
  243.         int32_t localesCount;
  244.         const Locale* locales = Locale::getAvailableLocales(localesCount);
  245.         Locale* temp = new Locale[localesCount];
  246.         int32_t newLocalesCount = 0;
  247.         int32_t i;
  248.         for (i=0; i<localesCount; ++i)
  249.         {
  250.             UErrorCode status = U_ZERO_ERROR;
  251.             ResourceBundle resource(Locale::getDataDirectory(), locales[i], status);
  252.             int32_t ignoredCount;
  253.             resource.getStringArray(SimpleDateFormat::fgDateTimePatternsTag, ignoredCount, status);
  254.             if (U_SUCCESS(status))
  255.             {
  256.                 temp[newLocalesCount++] = locales[i];
  257.             }
  258.         }
  259.         Locale *newLocales = new Locale[newLocalesCount];
  260.         for (i=0; i<newLocalesCount; ++i) ((Locale*)newLocales)[i] = temp[i]; // Cast away const
  261.         delete[] temp;
  262.  
  263.  
  264.         Mutex lock;
  265.         if(!fgLocales)
  266.         {
  267.             fgLocalesCount = newLocalesCount;
  268.             fgLocales = newLocales;
  269.         }
  270.         else
  271.         {
  272.             delete [] newLocales; // *shrug*
  273.         }
  274.     }
  275.  
  276.     count = fgLocalesCount;
  277.     return fgLocales;
  278. }
  279.  
  280. //----------------------------------------------------------------------
  281.  
  282. void
  283. DateFormat::adoptCalendar(Calendar* newCalendar)
  284. {
  285.     delete fCalendar;
  286.     fCalendar = newCalendar;
  287. }
  288.  
  289. //----------------------------------------------------------------------
  290. void
  291. DateFormat::setCalendar(const Calendar& newCalendar)
  292. {
  293.     adoptCalendar(newCalendar.clone());
  294. }
  295.  
  296. //----------------------------------------------------------------------
  297.  
  298. const Calendar*
  299. DateFormat::getCalendar() const
  300. {
  301.     return fCalendar;
  302. }
  303.  
  304. //----------------------------------------------------------------------
  305.  
  306. void
  307. DateFormat::adoptNumberFormat(NumberFormat* newNumberFormat)
  308. {
  309.     delete fNumberFormat;
  310.     fNumberFormat = newNumberFormat;
  311. }
  312. //----------------------------------------------------------------------
  313.  
  314. void
  315. DateFormat::setNumberFormat(const NumberFormat& newNumberFormat)
  316. {
  317.     adoptNumberFormat((NumberFormat*)newNumberFormat.clone());
  318. }
  319.  
  320. //----------------------------------------------------------------------
  321.  
  322. const NumberFormat*
  323. DateFormat::getNumberFormat() const
  324. {
  325.     return fNumberFormat;
  326. }
  327.  
  328. //----------------------------------------------------------------------
  329.  
  330. void
  331. DateFormat::adoptTimeZone(TimeZone* zone)
  332. {
  333.     fCalendar->adoptTimeZone(zone);
  334. }
  335. //----------------------------------------------------------------------
  336.  
  337. void
  338. DateFormat::setTimeZone(const TimeZone& zone)
  339. {
  340.     fCalendar->setTimeZone(zone);
  341. }
  342.  
  343. //----------------------------------------------------------------------
  344.  
  345. const TimeZone&
  346. DateFormat::getTimeZone() const
  347. {
  348.     return fCalendar->getTimeZone();
  349. }
  350.  
  351. //----------------------------------------------------------------------
  352.  
  353. void
  354. DateFormat::setLenient(bool_t lenient)
  355. {
  356.     fCalendar->setLenient(lenient);
  357. }
  358.  
  359. //----------------------------------------------------------------------
  360.  
  361. bool_t
  362. DateFormat::isLenient() const
  363. {
  364.     return fCalendar->isLenient();
  365. }
  366.  
  367. //eof
  368.