udat.cpp 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. *******************************************************************************
  5. * Copyright (C) 1996-2015, International Business Machines
  6. * Corporation and others. All Rights Reserved.
  7. *******************************************************************************
  8. */
  9. #include "unicode/utypes.h"
  10. #if !UCONFIG_NO_FORMATTING
  11. #include "unicode/udat.h"
  12. #include "unicode/uloc.h"
  13. #include "unicode/datefmt.h"
  14. #include "unicode/timezone.h"
  15. #include "unicode/smpdtfmt.h"
  16. #include "unicode/fieldpos.h"
  17. #include "unicode/parsepos.h"
  18. #include "unicode/calendar.h"
  19. #include "unicode/numfmt.h"
  20. #include "unicode/dtfmtsym.h"
  21. #include "unicode/ustring.h"
  22. #include "unicode/udisplaycontext.h"
  23. #include "unicode/ufieldpositer.h"
  24. #include "cpputils.h"
  25. #include "reldtfmt.h"
  26. #include "umutex.h"
  27. U_NAMESPACE_USE
  28. /**
  29. * Verify that fmt is a SimpleDateFormat. Invalid error if not.
  30. * @param fmt the UDateFormat, definitely a DateFormat, maybe something else
  31. * @param status error code, will be set to failure if there is a failure or the fmt is nullptr.
  32. */
  33. static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) {
  34. if(U_SUCCESS(*status) &&
  35. dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==nullptr) {
  36. *status = U_ILLEGAL_ARGUMENT_ERROR;
  37. }
  38. }
  39. // This mirrors the correspondence between the
  40. // SimpleDateFormat::fgPatternIndexToDateFormatField and
  41. // SimpleDateFormat::fgPatternIndexToCalendarField arrays.
  42. static UCalendarDateFields gDateFieldMapping[] = {
  43. UCAL_ERA, // UDAT_ERA_FIELD = 0
  44. UCAL_YEAR, // UDAT_YEAR_FIELD = 1
  45. UCAL_MONTH, // UDAT_MONTH_FIELD = 2
  46. UCAL_DATE, // UDAT_DATE_FIELD = 3
  47. UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY1_FIELD = 4
  48. UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY0_FIELD = 5
  49. UCAL_MINUTE, // UDAT_MINUTE_FIELD = 6
  50. UCAL_SECOND, // UDAT_SECOND_FIELD = 7
  51. UCAL_MILLISECOND, // UDAT_FRACTIONAL_SECOND_FIELD = 8
  52. UCAL_DAY_OF_WEEK, // UDAT_DAY_OF_WEEK_FIELD = 9
  53. UCAL_DAY_OF_YEAR, // UDAT_DAY_OF_YEAR_FIELD = 10
  54. UCAL_DAY_OF_WEEK_IN_MONTH, // UDAT_DAY_OF_WEEK_IN_MONTH_FIELD = 11
  55. UCAL_WEEK_OF_YEAR, // UDAT_WEEK_OF_YEAR_FIELD = 12
  56. UCAL_WEEK_OF_MONTH, // UDAT_WEEK_OF_MONTH_FIELD = 13
  57. UCAL_AM_PM, // UDAT_AM_PM_FIELD = 14
  58. UCAL_HOUR, // UDAT_HOUR1_FIELD = 15
  59. UCAL_HOUR, // UDAT_HOUR0_FIELD = 16
  60. UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_FIELD = 17
  61. UCAL_YEAR_WOY, // UDAT_YEAR_WOY_FIELD = 18
  62. UCAL_DOW_LOCAL, // UDAT_DOW_LOCAL_FIELD = 19
  63. UCAL_EXTENDED_YEAR, // UDAT_EXTENDED_YEAR_FIELD = 20
  64. UCAL_JULIAN_DAY, // UDAT_JULIAN_DAY_FIELD = 21
  65. UCAL_MILLISECONDS_IN_DAY, // UDAT_MILLISECONDS_IN_DAY_FIELD = 22
  66. UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_RFC_FIELD = 23 (also UCAL_DST_OFFSET)
  67. UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_GENERIC_FIELD = 24 (also UCAL_DST_OFFSET)
  68. UCAL_DOW_LOCAL, // UDAT_STANDALONE_DAY_FIELD = 25
  69. UCAL_MONTH, // UDAT_STANDALONE_MONTH_FIELD = 26
  70. UCAL_MONTH, // UDAT_QUARTER_FIELD = 27
  71. UCAL_MONTH, // UDAT_STANDALONE_QUARTER_FIELD = 28
  72. UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_SPECIAL_FIELD = 29 (also UCAL_DST_OFFSET)
  73. UCAL_YEAR, // UDAT_YEAR_NAME_FIELD = 30
  74. UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD = 31 (also UCAL_DST_OFFSET)
  75. UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_ISO_FIELD = 32 (also UCAL_DST_OFFSET)
  76. UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_ISO_LOCAL_FIELD = 33 (also UCAL_DST_OFFSET)
  77. UCAL_EXTENDED_YEAR, // UDAT_RELATED_YEAR_FIELD = 34 (not an exact match)
  78. UCAL_FIELD_COUNT, // UDAT_AM_PM_MIDNIGHT_NOON_FIELD=35 (no match)
  79. UCAL_FIELD_COUNT, // UDAT_FLEXIBLE_DAY_PERIOD_FIELD=36 (no match)
  80. UCAL_FIELD_COUNT, // UDAT_TIME_SEPARATOR_FIELD = 37 (no match)
  81. // UDAT_FIELD_COUNT = 38 as of ICU 67
  82. // UCAL_IS_LEAP_MONTH is not the target of a mapping
  83. };
  84. U_CAPI UCalendarDateFields U_EXPORT2
  85. udat_toCalendarDateField(UDateFormatField field) UPRV_NO_SANITIZE_UNDEFINED {
  86. static_assert(UDAT_FIELD_COUNT == UPRV_LENGTHOF(gDateFieldMapping),
  87. "UDateFormatField and gDateFieldMapping should have the same number of entries and be kept in sync.");
  88. return (field >= UDAT_ERA_FIELD && field < UPRV_LENGTHOF(gDateFieldMapping))? gDateFieldMapping[field]: UCAL_FIELD_COUNT;
  89. }
  90. /* For now- one opener. */
  91. static UDateFormatOpener gOpener = nullptr;
  92. U_CAPI void U_EXPORT2
  93. udat_registerOpener(UDateFormatOpener opener, UErrorCode *status)
  94. {
  95. if(U_FAILURE(*status)) return;
  96. umtx_lock(nullptr);
  97. if(gOpener==nullptr) {
  98. gOpener = opener;
  99. } else {
  100. *status = U_ILLEGAL_ARGUMENT_ERROR;
  101. }
  102. umtx_unlock(nullptr);
  103. }
  104. U_CAPI UDateFormatOpener U_EXPORT2
  105. udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status)
  106. {
  107. if(U_FAILURE(*status)) return nullptr;
  108. UDateFormatOpener oldOpener = nullptr;
  109. umtx_lock(nullptr);
  110. if(gOpener==nullptr || gOpener!=opener) {
  111. *status = U_ILLEGAL_ARGUMENT_ERROR;
  112. } else {
  113. oldOpener=gOpener;
  114. gOpener=nullptr;
  115. }
  116. umtx_unlock(nullptr);
  117. return oldOpener;
  118. }
  119. U_CAPI UDateFormat* U_EXPORT2
  120. udat_open(UDateFormatStyle timeStyle,
  121. UDateFormatStyle dateStyle,
  122. const char *locale,
  123. const char16_t *tzID,
  124. int32_t tzIDLength,
  125. const char16_t *pattern,
  126. int32_t patternLength,
  127. UErrorCode *status)
  128. {
  129. DateFormat *fmt;
  130. if(U_FAILURE(*status)) {
  131. return 0;
  132. }
  133. if(gOpener!=nullptr) { // if it's registered
  134. fmt = (DateFormat*) (*gOpener)(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status);
  135. if(fmt!=nullptr) {
  136. return (UDateFormat*)fmt;
  137. } // else fall through.
  138. }
  139. if(timeStyle != UDAT_PATTERN) {
  140. if(locale == 0) {
  141. fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
  142. (DateFormat::EStyle)timeStyle);
  143. }
  144. else {
  145. fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
  146. (DateFormat::EStyle)timeStyle,
  147. Locale(locale));
  148. }
  149. }
  150. else {
  151. UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
  152. if(locale == 0) {
  153. fmt = new SimpleDateFormat(pat, *status);
  154. }
  155. else {
  156. fmt = new SimpleDateFormat(pat, Locale(locale), *status);
  157. }
  158. }
  159. if(fmt == nullptr) {
  160. *status = U_MEMORY_ALLOCATION_ERROR;
  161. return nullptr;
  162. }
  163. if (U_FAILURE(*status)) {
  164. delete fmt;
  165. return nullptr;
  166. }
  167. if(tzID != 0) {
  168. TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength));
  169. if(zone == 0) {
  170. *status = U_MEMORY_ALLOCATION_ERROR;
  171. delete fmt;
  172. return 0;
  173. }
  174. fmt->adoptTimeZone(zone);
  175. }
  176. return (UDateFormat*)fmt;
  177. }
  178. U_CAPI void U_EXPORT2
  179. udat_close(UDateFormat* format)
  180. {
  181. if (format == nullptr) return;
  182. delete (DateFormat*)format;
  183. }
  184. U_CAPI UDateFormat* U_EXPORT2
  185. udat_clone(const UDateFormat *fmt,
  186. UErrorCode *status)
  187. {
  188. if(U_FAILURE(*status)) return 0;
  189. Format *res = ((DateFormat*)fmt)->clone();
  190. if(res == 0) {
  191. *status = U_MEMORY_ALLOCATION_ERROR;
  192. return 0;
  193. }
  194. return (UDateFormat*) res;
  195. }
  196. U_CAPI int32_t U_EXPORT2
  197. udat_format( const UDateFormat* format,
  198. UDate dateToFormat,
  199. char16_t* result,
  200. int32_t resultLength,
  201. UFieldPosition* position,
  202. UErrorCode* status)
  203. {
  204. if(U_FAILURE(*status)) {
  205. return -1;
  206. }
  207. if (result == nullptr ? resultLength != 0 : resultLength < 0) {
  208. *status = U_ILLEGAL_ARGUMENT_ERROR;
  209. return -1;
  210. }
  211. UnicodeString res;
  212. if (result != nullptr) {
  213. // nullptr destination for pure preflighting: empty dummy string
  214. // otherwise, alias the destination buffer
  215. res.setTo(result, 0, resultLength);
  216. }
  217. FieldPosition fp;
  218. if(position != 0)
  219. fp.setField(position->field);
  220. ((DateFormat*)format)->format(dateToFormat, res, fp);
  221. if(position != 0) {
  222. position->beginIndex = fp.getBeginIndex();
  223. position->endIndex = fp.getEndIndex();
  224. }
  225. return res.extract(result, resultLength, *status);
  226. }
  227. U_CAPI int32_t U_EXPORT2
  228. udat_formatCalendar(const UDateFormat* format,
  229. UCalendar* calendar,
  230. char16_t* result,
  231. int32_t resultLength,
  232. UFieldPosition* position,
  233. UErrorCode* status)
  234. {
  235. if(U_FAILURE(*status)) {
  236. return -1;
  237. }
  238. if (result == nullptr ? resultLength != 0 : resultLength < 0) {
  239. *status = U_ILLEGAL_ARGUMENT_ERROR;
  240. return -1;
  241. }
  242. UnicodeString res;
  243. if (result != nullptr) {
  244. // nullptr destination for pure preflighting: empty dummy string
  245. // otherwise, alias the destination buffer
  246. res.setTo(result, 0, resultLength);
  247. }
  248. FieldPosition fp;
  249. if(position != 0)
  250. fp.setField(position->field);
  251. ((DateFormat*)format)->format(*(Calendar*)calendar, res, fp);
  252. if(position != 0) {
  253. position->beginIndex = fp.getBeginIndex();
  254. position->endIndex = fp.getEndIndex();
  255. }
  256. return res.extract(result, resultLength, *status);
  257. }
  258. U_CAPI int32_t U_EXPORT2
  259. udat_formatForFields( const UDateFormat* format,
  260. UDate dateToFormat,
  261. char16_t* result,
  262. int32_t resultLength,
  263. UFieldPositionIterator* fpositer,
  264. UErrorCode* status)
  265. {
  266. if(U_FAILURE(*status)) {
  267. return -1;
  268. }
  269. if (result == nullptr ? resultLength != 0 : resultLength < 0) {
  270. *status = U_ILLEGAL_ARGUMENT_ERROR;
  271. return -1;
  272. }
  273. UnicodeString res;
  274. if (result != nullptr) {
  275. // nullptr destination for pure preflighting: empty dummy string
  276. // otherwise, alias the destination buffer
  277. res.setTo(result, 0, resultLength);
  278. }
  279. ((DateFormat*)format)->format(dateToFormat, res, (FieldPositionIterator*)fpositer, *status);
  280. return res.extract(result, resultLength, *status);
  281. }
  282. U_CAPI int32_t U_EXPORT2
  283. udat_formatCalendarForFields(const UDateFormat* format,
  284. UCalendar* calendar,
  285. char16_t* result,
  286. int32_t resultLength,
  287. UFieldPositionIterator* fpositer,
  288. UErrorCode* status)
  289. {
  290. if(U_FAILURE(*status)) {
  291. return -1;
  292. }
  293. if (result == nullptr ? resultLength != 0 : resultLength < 0) {
  294. *status = U_ILLEGAL_ARGUMENT_ERROR;
  295. return -1;
  296. }
  297. UnicodeString res;
  298. if (result != nullptr) {
  299. // nullptr destination for pure preflighting: empty dummy string
  300. // otherwise, alias the destination buffer
  301. res.setTo(result, 0, resultLength);
  302. }
  303. ((DateFormat*)format)->format(*(Calendar*)calendar, res, (FieldPositionIterator*)fpositer, *status);
  304. return res.extract(result, resultLength, *status);
  305. }
  306. U_CAPI UDate U_EXPORT2
  307. udat_parse( const UDateFormat* format,
  308. const char16_t* text,
  309. int32_t textLength,
  310. int32_t *parsePos,
  311. UErrorCode *status)
  312. {
  313. if(U_FAILURE(*status)) return (UDate)0;
  314. const UnicodeString src((UBool)(textLength == -1), text, textLength);
  315. ParsePosition pp;
  316. int32_t stackParsePos = 0;
  317. UDate res;
  318. if(parsePos == nullptr) {
  319. parsePos = &stackParsePos;
  320. }
  321. pp.setIndex(*parsePos);
  322. res = ((DateFormat*)format)->parse(src, pp);
  323. if(pp.getErrorIndex() == -1)
  324. *parsePos = pp.getIndex();
  325. else {
  326. *parsePos = pp.getErrorIndex();
  327. *status = U_PARSE_ERROR;
  328. }
  329. return res;
  330. }
  331. U_CAPI void U_EXPORT2
  332. udat_parseCalendar(const UDateFormat* format,
  333. UCalendar* calendar,
  334. const char16_t* text,
  335. int32_t textLength,
  336. int32_t *parsePos,
  337. UErrorCode *status)
  338. {
  339. if(U_FAILURE(*status)) return;
  340. const UnicodeString src((UBool)(textLength == -1), text, textLength);
  341. ParsePosition pp;
  342. int32_t stackParsePos = 0;
  343. if(parsePos == nullptr) {
  344. parsePos = &stackParsePos;
  345. }
  346. pp.setIndex(*parsePos);
  347. ((DateFormat*)format)->parse(src, *(Calendar*)calendar, pp);
  348. if(pp.getErrorIndex() == -1)
  349. *parsePos = pp.getIndex();
  350. else {
  351. *parsePos = pp.getErrorIndex();
  352. *status = U_PARSE_ERROR;
  353. }
  354. }
  355. U_CAPI UBool U_EXPORT2
  356. udat_isLenient(const UDateFormat* fmt)
  357. {
  358. return ((DateFormat*)fmt)->isLenient();
  359. }
  360. U_CAPI void U_EXPORT2
  361. udat_setLenient( UDateFormat* fmt,
  362. UBool isLenient)
  363. {
  364. ((DateFormat*)fmt)->setLenient(isLenient);
  365. }
  366. U_CAPI UBool U_EXPORT2
  367. udat_getBooleanAttribute(const UDateFormat* fmt,
  368. UDateFormatBooleanAttribute attr,
  369. UErrorCode* status)
  370. {
  371. if(U_FAILURE(*status)) return false;
  372. return ((DateFormat*)fmt)->getBooleanAttribute(attr, *status);
  373. //return false;
  374. }
  375. U_CAPI void U_EXPORT2
  376. udat_setBooleanAttribute(UDateFormat *fmt,
  377. UDateFormatBooleanAttribute attr,
  378. UBool newValue,
  379. UErrorCode* status)
  380. {
  381. if(U_FAILURE(*status)) return;
  382. ((DateFormat*)fmt)->setBooleanAttribute(attr, newValue, *status);
  383. }
  384. U_CAPI const UCalendar* U_EXPORT2
  385. udat_getCalendar(const UDateFormat* fmt)
  386. {
  387. return (const UCalendar*) ((DateFormat*)fmt)->getCalendar();
  388. }
  389. U_CAPI void U_EXPORT2
  390. udat_setCalendar(UDateFormat* fmt,
  391. const UCalendar* calendarToSet)
  392. {
  393. ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet));
  394. }
  395. U_CAPI const UNumberFormat* U_EXPORT2
  396. udat_getNumberFormatForField(const UDateFormat* fmt, char16_t field)
  397. {
  398. UErrorCode status = U_ZERO_ERROR;
  399. verifyIsSimpleDateFormat(fmt, &status);
  400. if (U_FAILURE(status)) return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat();
  401. return (const UNumberFormat*) ((SimpleDateFormat*)fmt)->getNumberFormatForField(field);
  402. }
  403. U_CAPI const UNumberFormat* U_EXPORT2
  404. udat_getNumberFormat(const UDateFormat* fmt)
  405. {
  406. return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat();
  407. }
  408. U_CAPI void U_EXPORT2
  409. udat_adoptNumberFormatForFields( UDateFormat* fmt,
  410. const char16_t* fields,
  411. UNumberFormat* numberFormatToSet,
  412. UErrorCode* status)
  413. {
  414. verifyIsSimpleDateFormat(fmt, status);
  415. if (U_FAILURE(*status)) return;
  416. if (fields!=nullptr) {
  417. UnicodeString overrideFields(fields);
  418. ((SimpleDateFormat*)fmt)->adoptNumberFormat(overrideFields, (NumberFormat*)numberFormatToSet, *status);
  419. }
  420. }
  421. U_CAPI void U_EXPORT2
  422. udat_setNumberFormat(UDateFormat* fmt,
  423. const UNumberFormat* numberFormatToSet)
  424. {
  425. ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet));
  426. }
  427. U_CAPI void U_EXPORT2
  428. udat_adoptNumberFormat( UDateFormat* fmt,
  429. UNumberFormat* numberFormatToAdopt)
  430. {
  431. ((DateFormat*)fmt)->adoptNumberFormat((NumberFormat*)numberFormatToAdopt);
  432. }
  433. U_CAPI const char* U_EXPORT2
  434. udat_getAvailable(int32_t index)
  435. {
  436. return uloc_getAvailable(index);
  437. }
  438. U_CAPI int32_t U_EXPORT2
  439. udat_countAvailable()
  440. {
  441. return uloc_countAvailable();
  442. }
  443. U_CAPI UDate U_EXPORT2
  444. udat_get2DigitYearStart( const UDateFormat *fmt,
  445. UErrorCode *status)
  446. {
  447. verifyIsSimpleDateFormat(fmt, status);
  448. if(U_FAILURE(*status)) return (UDate)0;
  449. return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status);
  450. }
  451. U_CAPI void U_EXPORT2
  452. udat_set2DigitYearStart( UDateFormat *fmt,
  453. UDate d,
  454. UErrorCode *status)
  455. {
  456. verifyIsSimpleDateFormat(fmt, status);
  457. if(U_FAILURE(*status)) return;
  458. ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status);
  459. }
  460. U_CAPI int32_t U_EXPORT2
  461. udat_toPattern( const UDateFormat *fmt,
  462. UBool localized,
  463. char16_t *result,
  464. int32_t resultLength,
  465. UErrorCode *status)
  466. {
  467. if(U_FAILURE(*status)) {
  468. return -1;
  469. }
  470. if (result == nullptr ? resultLength != 0 : resultLength < 0) {
  471. *status = U_ILLEGAL_ARGUMENT_ERROR;
  472. return -1;
  473. }
  474. UnicodeString res;
  475. if (result != nullptr) {
  476. // nullptr destination for pure preflighting: empty dummy string
  477. // otherwise, alias the destination buffer
  478. res.setTo(result, 0, resultLength);
  479. }
  480. const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt);
  481. const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df);
  482. const RelativeDateFormat *reldtfmt;
  483. if (sdtfmt!=nullptr) {
  484. if(localized)
  485. sdtfmt->toLocalizedPattern(res, *status);
  486. else
  487. sdtfmt->toPattern(res);
  488. } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=nullptr) {
  489. reldtfmt->toPattern(res, *status);
  490. } else {
  491. *status = U_ILLEGAL_ARGUMENT_ERROR;
  492. return -1;
  493. }
  494. return res.extract(result, resultLength, *status);
  495. }
  496. // TODO: should this take an UErrorCode?
  497. // A: Yes. Of course.
  498. U_CAPI void U_EXPORT2
  499. udat_applyPattern( UDateFormat *format,
  500. UBool localized,
  501. const char16_t *pattern,
  502. int32_t patternLength)
  503. {
  504. const UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
  505. UErrorCode status = U_ZERO_ERROR;
  506. verifyIsSimpleDateFormat(format, &status);
  507. if(U_FAILURE(status)) {
  508. return;
  509. }
  510. if(localized)
  511. ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status);
  512. else
  513. ((SimpleDateFormat*)format)->applyPattern(pat);
  514. }
  515. U_CAPI int32_t U_EXPORT2
  516. udat_getSymbols(const UDateFormat *fmt,
  517. UDateFormatSymbolType type,
  518. int32_t index,
  519. char16_t *result,
  520. int32_t resultLength,
  521. UErrorCode *status)
  522. {
  523. const DateFormatSymbols *syms;
  524. const SimpleDateFormat* sdtfmt;
  525. const RelativeDateFormat* rdtfmt;
  526. if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != nullptr) {
  527. syms = sdtfmt->getDateFormatSymbols();
  528. } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != nullptr) {
  529. syms = rdtfmt->getDateFormatSymbols();
  530. } else {
  531. return -1;
  532. }
  533. int32_t count = 0;
  534. const UnicodeString *res = nullptr;
  535. switch(type) {
  536. case UDAT_ERAS:
  537. res = syms->getEras(count);
  538. break;
  539. case UDAT_ERA_NAMES:
  540. res = syms->getEraNames(count);
  541. break;
  542. case UDAT_MONTHS:
  543. res = syms->getMonths(count);
  544. break;
  545. case UDAT_SHORT_MONTHS:
  546. res = syms->getShortMonths(count);
  547. break;
  548. case UDAT_WEEKDAYS:
  549. res = syms->getWeekdays(count);
  550. break;
  551. case UDAT_SHORT_WEEKDAYS:
  552. res = syms->getShortWeekdays(count);
  553. break;
  554. case UDAT_AM_PMS:
  555. res = syms->getAmPmStrings(count);
  556. break;
  557. case UDAT_LOCALIZED_CHARS:
  558. {
  559. UnicodeString res1;
  560. if(!(result==nullptr && resultLength==0)) {
  561. // nullptr destination for pure preflighting: empty dummy string
  562. // otherwise, alias the destination buffer
  563. res1.setTo(result, 0, resultLength);
  564. }
  565. syms->getLocalPatternChars(res1);
  566. return res1.extract(result, resultLength, *status);
  567. }
  568. case UDAT_NARROW_MONTHS:
  569. res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  570. break;
  571. case UDAT_SHORTER_WEEKDAYS:
  572. res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
  573. break;
  574. case UDAT_NARROW_WEEKDAYS:
  575. res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  576. break;
  577. case UDAT_STANDALONE_MONTHS:
  578. res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
  579. break;
  580. case UDAT_STANDALONE_SHORT_MONTHS:
  581. res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
  582. break;
  583. case UDAT_STANDALONE_NARROW_MONTHS:
  584. res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
  585. break;
  586. case UDAT_STANDALONE_WEEKDAYS:
  587. res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
  588. break;
  589. case UDAT_STANDALONE_SHORT_WEEKDAYS:
  590. res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
  591. break;
  592. case UDAT_STANDALONE_SHORTER_WEEKDAYS:
  593. res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
  594. break;
  595. case UDAT_STANDALONE_NARROW_WEEKDAYS:
  596. res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
  597. break;
  598. case UDAT_QUARTERS:
  599. res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
  600. break;
  601. case UDAT_SHORT_QUARTERS:
  602. res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
  603. break;
  604. case UDAT_NARROW_QUARTERS:
  605. res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  606. break;
  607. case UDAT_STANDALONE_QUARTERS:
  608. res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
  609. break;
  610. case UDAT_STANDALONE_SHORT_QUARTERS:
  611. res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
  612. break;
  613. case UDAT_STANDALONE_NARROW_QUARTERS:
  614. res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
  615. break;
  616. case UDAT_CYCLIC_YEARS_WIDE:
  617. res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
  618. break;
  619. case UDAT_CYCLIC_YEARS_ABBREVIATED:
  620. res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
  621. break;
  622. case UDAT_CYCLIC_YEARS_NARROW:
  623. res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  624. break;
  625. case UDAT_ZODIAC_NAMES_WIDE:
  626. res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
  627. break;
  628. case UDAT_ZODIAC_NAMES_ABBREVIATED:
  629. res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
  630. break;
  631. case UDAT_ZODIAC_NAMES_NARROW:
  632. res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  633. break;
  634. }
  635. if(index < count) {
  636. return res[index].extract(result, resultLength, *status);
  637. }
  638. return 0;
  639. }
  640. // TODO: also needs an errorCode.
  641. U_CAPI int32_t U_EXPORT2
  642. udat_countSymbols( const UDateFormat *fmt,
  643. UDateFormatSymbolType type)
  644. {
  645. const DateFormatSymbols *syms;
  646. const SimpleDateFormat* sdtfmt;
  647. const RelativeDateFormat* rdtfmt;
  648. if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != nullptr) {
  649. syms = sdtfmt->getDateFormatSymbols();
  650. } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != nullptr) {
  651. syms = rdtfmt->getDateFormatSymbols();
  652. } else {
  653. return 0;
  654. }
  655. int32_t count = 0;
  656. switch(type) {
  657. case UDAT_ERAS:
  658. syms->getEras(count);
  659. break;
  660. case UDAT_MONTHS:
  661. syms->getMonths(count);
  662. break;
  663. case UDAT_SHORT_MONTHS:
  664. syms->getShortMonths(count);
  665. break;
  666. case UDAT_WEEKDAYS:
  667. syms->getWeekdays(count);
  668. break;
  669. case UDAT_SHORT_WEEKDAYS:
  670. syms->getShortWeekdays(count);
  671. break;
  672. case UDAT_AM_PMS:
  673. syms->getAmPmStrings(count);
  674. break;
  675. case UDAT_LOCALIZED_CHARS:
  676. count = 1;
  677. break;
  678. case UDAT_ERA_NAMES:
  679. syms->getEraNames(count);
  680. break;
  681. case UDAT_NARROW_MONTHS:
  682. syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  683. break;
  684. case UDAT_SHORTER_WEEKDAYS:
  685. syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
  686. break;
  687. case UDAT_NARROW_WEEKDAYS:
  688. syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  689. break;
  690. case UDAT_STANDALONE_MONTHS:
  691. syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
  692. break;
  693. case UDAT_STANDALONE_SHORT_MONTHS:
  694. syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
  695. break;
  696. case UDAT_STANDALONE_NARROW_MONTHS:
  697. syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
  698. break;
  699. case UDAT_STANDALONE_WEEKDAYS:
  700. syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
  701. break;
  702. case UDAT_STANDALONE_SHORT_WEEKDAYS:
  703. syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
  704. break;
  705. case UDAT_STANDALONE_SHORTER_WEEKDAYS:
  706. syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
  707. break;
  708. case UDAT_STANDALONE_NARROW_WEEKDAYS:
  709. syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
  710. break;
  711. case UDAT_QUARTERS:
  712. syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
  713. break;
  714. case UDAT_SHORT_QUARTERS:
  715. syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
  716. break;
  717. case UDAT_NARROW_QUARTERS:
  718. syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  719. break;
  720. case UDAT_STANDALONE_QUARTERS:
  721. syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
  722. break;
  723. case UDAT_STANDALONE_SHORT_QUARTERS:
  724. syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
  725. break;
  726. case UDAT_STANDALONE_NARROW_QUARTERS:
  727. syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
  728. break;
  729. case UDAT_CYCLIC_YEARS_WIDE:
  730. syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
  731. break;
  732. case UDAT_CYCLIC_YEARS_ABBREVIATED:
  733. syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
  734. break;
  735. case UDAT_CYCLIC_YEARS_NARROW:
  736. syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  737. break;
  738. case UDAT_ZODIAC_NAMES_WIDE:
  739. syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
  740. break;
  741. case UDAT_ZODIAC_NAMES_ABBREVIATED:
  742. syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
  743. break;
  744. case UDAT_ZODIAC_NAMES_NARROW:
  745. syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
  746. break;
  747. }
  748. return count;
  749. }
  750. U_NAMESPACE_BEGIN
  751. /*
  752. * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols
  753. * solely for the purpose of avoiding to clone the array of strings
  754. * just to modify one of them and then setting all of them back.
  755. * For example, the old code looked like this:
  756. * case UDAT_MONTHS:
  757. * res = syms->getMonths(count);
  758. * array = new UnicodeString[count];
  759. * if(array == 0) {
  760. * *status = U_MEMORY_ALLOCATION_ERROR;
  761. * return;
  762. * }
  763. * uprv_arrayCopy(res, array, count);
  764. * if(index < count)
  765. * array[index] = val;
  766. * syms->setMonths(array, count);
  767. * break;
  768. *
  769. * Even worse, the old code actually cloned the entire DateFormatSymbols object,
  770. * cloned one value array, changed one value, and then made the SimpleDateFormat
  771. * replace its DateFormatSymbols object with the new one.
  772. *
  773. * markus 2002-oct-14
  774. */
  775. class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ {
  776. public:
  777. static void
  778. setSymbol(UnicodeString *array, int32_t count, int32_t index,
  779. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  780. {
  781. if(array!=nullptr) {
  782. if(index>=count) {
  783. errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
  784. } else if(value==nullptr) {
  785. errorCode=U_ILLEGAL_ARGUMENT_ERROR;
  786. } else {
  787. array[index].setTo(value, valueLength);
  788. }
  789. }
  790. }
  791. static void
  792. setEra(DateFormatSymbols *syms, int32_t index,
  793. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  794. {
  795. setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode);
  796. }
  797. static void
  798. setEraName(DateFormatSymbols *syms, int32_t index,
  799. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  800. {
  801. setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode);
  802. }
  803. static void
  804. setMonth(DateFormatSymbols *syms, int32_t index,
  805. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  806. {
  807. setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode);
  808. }
  809. static void
  810. setShortMonth(DateFormatSymbols *syms, int32_t index,
  811. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  812. {
  813. setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode);
  814. }
  815. static void
  816. setNarrowMonth(DateFormatSymbols *syms, int32_t index,
  817. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  818. {
  819. setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode);
  820. }
  821. static void
  822. setStandaloneMonth(DateFormatSymbols *syms, int32_t index,
  823. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  824. {
  825. setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode);
  826. }
  827. static void
  828. setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index,
  829. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  830. {
  831. setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode);
  832. }
  833. static void
  834. setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index,
  835. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  836. {
  837. setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode);
  838. }
  839. static void
  840. setWeekday(DateFormatSymbols *syms, int32_t index,
  841. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  842. {
  843. setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode);
  844. }
  845. static void
  846. setShortWeekday(DateFormatSymbols *syms, int32_t index,
  847. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  848. {
  849. setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode);
  850. }
  851. static void
  852. setShorterWeekday(DateFormatSymbols *syms, int32_t index,
  853. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  854. {
  855. setSymbol(syms->fShorterWeekdays, syms->fShorterWeekdaysCount, index, value, valueLength, errorCode);
  856. }
  857. static void
  858. setNarrowWeekday(DateFormatSymbols *syms, int32_t index,
  859. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  860. {
  861. setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode);
  862. }
  863. static void
  864. setStandaloneWeekday(DateFormatSymbols *syms, int32_t index,
  865. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  866. {
  867. setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode);
  868. }
  869. static void
  870. setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index,
  871. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  872. {
  873. setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode);
  874. }
  875. static void
  876. setStandaloneShorterWeekday(DateFormatSymbols *syms, int32_t index,
  877. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  878. {
  879. setSymbol(syms->fStandaloneShorterWeekdays, syms->fStandaloneShorterWeekdaysCount, index, value, valueLength, errorCode);
  880. }
  881. static void
  882. setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index,
  883. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  884. {
  885. setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode);
  886. }
  887. static void
  888. setQuarter(DateFormatSymbols *syms, int32_t index,
  889. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  890. {
  891. setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode);
  892. }
  893. static void
  894. setShortQuarter(DateFormatSymbols *syms, int32_t index,
  895. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  896. {
  897. setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode);
  898. }
  899. static void
  900. setNarrowQuarter(DateFormatSymbols *syms, int32_t index,
  901. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  902. {
  903. setSymbol(syms->fNarrowQuarters, syms->fNarrowQuartersCount, index, value, valueLength, errorCode);
  904. }
  905. static void
  906. setStandaloneQuarter(DateFormatSymbols *syms, int32_t index,
  907. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  908. {
  909. setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode);
  910. }
  911. static void
  912. setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index,
  913. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  914. {
  915. setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode);
  916. }
  917. static void
  918. setStandaloneNarrowQuarter(DateFormatSymbols *syms, int32_t index,
  919. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  920. {
  921. setSymbol(syms->fStandaloneNarrowQuarters, syms->fStandaloneNarrowQuartersCount, index, value, valueLength, errorCode);
  922. }
  923. static void
  924. setShortYearNames(DateFormatSymbols *syms, int32_t index,
  925. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  926. {
  927. setSymbol(syms->fShortYearNames, syms->fShortYearNamesCount, index, value, valueLength, errorCode);
  928. }
  929. static void
  930. setShortZodiacNames(DateFormatSymbols *syms, int32_t index,
  931. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  932. {
  933. setSymbol(syms->fShortZodiacNames, syms->fShortZodiacNamesCount, index, value, valueLength, errorCode);
  934. }
  935. static void
  936. setAmPm(DateFormatSymbols *syms, int32_t index,
  937. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  938. {
  939. setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode);
  940. }
  941. static void
  942. setLocalPatternChars(DateFormatSymbols *syms,
  943. const char16_t *value, int32_t valueLength, UErrorCode &errorCode)
  944. {
  945. setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode);
  946. }
  947. };
  948. U_NAMESPACE_END
  949. U_CAPI void U_EXPORT2
  950. udat_setSymbols( UDateFormat *format,
  951. UDateFormatSymbolType type,
  952. int32_t index,
  953. char16_t *value,
  954. int32_t valueLength,
  955. UErrorCode *status)
  956. {
  957. verifyIsSimpleDateFormat(format, status);
  958. if(U_FAILURE(*status)) return;
  959. DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols();
  960. switch(type) {
  961. case UDAT_ERAS:
  962. DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status);
  963. break;
  964. case UDAT_ERA_NAMES:
  965. DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status);
  966. break;
  967. case UDAT_MONTHS:
  968. DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status);
  969. break;
  970. case UDAT_SHORT_MONTHS:
  971. DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status);
  972. break;
  973. case UDAT_NARROW_MONTHS:
  974. DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status);
  975. break;
  976. case UDAT_STANDALONE_MONTHS:
  977. DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status);
  978. break;
  979. case UDAT_STANDALONE_SHORT_MONTHS:
  980. DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status);
  981. break;
  982. case UDAT_STANDALONE_NARROW_MONTHS:
  983. DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status);
  984. break;
  985. case UDAT_WEEKDAYS:
  986. DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status);
  987. break;
  988. case UDAT_SHORT_WEEKDAYS:
  989. DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status);
  990. break;
  991. case UDAT_SHORTER_WEEKDAYS:
  992. DateFormatSymbolsSingleSetter::setShorterWeekday(syms, index, value, valueLength, *status);
  993. break;
  994. case UDAT_NARROW_WEEKDAYS:
  995. DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status);
  996. break;
  997. case UDAT_STANDALONE_WEEKDAYS:
  998. DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status);
  999. break;
  1000. case UDAT_STANDALONE_SHORT_WEEKDAYS:
  1001. DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status);
  1002. break;
  1003. case UDAT_STANDALONE_SHORTER_WEEKDAYS:
  1004. DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms, index, value, valueLength, *status);
  1005. break;
  1006. case UDAT_STANDALONE_NARROW_WEEKDAYS:
  1007. DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status);
  1008. break;
  1009. case UDAT_QUARTERS:
  1010. DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status);
  1011. break;
  1012. case UDAT_SHORT_QUARTERS:
  1013. DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status);
  1014. break;
  1015. case UDAT_NARROW_QUARTERS:
  1016. DateFormatSymbolsSingleSetter::setNarrowQuarter(syms, index, value, valueLength, *status);
  1017. break;
  1018. case UDAT_STANDALONE_QUARTERS:
  1019. DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status);
  1020. break;
  1021. case UDAT_STANDALONE_SHORT_QUARTERS:
  1022. DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status);
  1023. break;
  1024. case UDAT_STANDALONE_NARROW_QUARTERS:
  1025. DateFormatSymbolsSingleSetter::setStandaloneNarrowQuarter(syms, index, value, valueLength, *status);
  1026. break;
  1027. case UDAT_CYCLIC_YEARS_ABBREVIATED:
  1028. DateFormatSymbolsSingleSetter::setShortYearNames(syms, index, value, valueLength, *status);
  1029. break;
  1030. case UDAT_ZODIAC_NAMES_ABBREVIATED:
  1031. DateFormatSymbolsSingleSetter::setShortZodiacNames(syms, index, value, valueLength, *status);
  1032. break;
  1033. case UDAT_AM_PMS:
  1034. DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status);
  1035. break;
  1036. case UDAT_LOCALIZED_CHARS:
  1037. DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status);
  1038. break;
  1039. default:
  1040. *status = U_UNSUPPORTED_ERROR;
  1041. break;
  1042. }
  1043. }
  1044. U_CAPI const char* U_EXPORT2
  1045. udat_getLocaleByType(const UDateFormat *fmt,
  1046. ULocDataLocaleType type,
  1047. UErrorCode* status)
  1048. {
  1049. if (fmt == nullptr) {
  1050. if (U_SUCCESS(*status)) {
  1051. *status = U_ILLEGAL_ARGUMENT_ERROR;
  1052. }
  1053. return nullptr;
  1054. }
  1055. return ((Format*)fmt)->getLocaleID(type, *status);
  1056. }
  1057. U_CAPI void U_EXPORT2
  1058. udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status)
  1059. {
  1060. if (U_FAILURE(*status)) {
  1061. return;
  1062. }
  1063. ((DateFormat*)fmt)->setContext(value, *status);
  1064. return;
  1065. }
  1066. U_CAPI UDisplayContext U_EXPORT2
  1067. udat_getContext(const UDateFormat* fmt, UDisplayContextType type, UErrorCode* status)
  1068. {
  1069. if (U_FAILURE(*status)) {
  1070. return (UDisplayContext)0;
  1071. }
  1072. return ((const DateFormat*)fmt)->getContext(type, *status);
  1073. }
  1074. /**
  1075. * Verify that fmt is a RelativeDateFormat. Invalid error if not.
  1076. * @param fmt the UDateFormat, definitely a DateFormat, maybe something else
  1077. * @param status error code, will be set to failure if there is a failure or the fmt is nullptr.
  1078. */
  1079. static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) {
  1080. if(U_SUCCESS(*status) &&
  1081. dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==nullptr) {
  1082. *status = U_ILLEGAL_ARGUMENT_ERROR;
  1083. }
  1084. }
  1085. U_CAPI int32_t U_EXPORT2
  1086. udat_toPatternRelativeDate(const UDateFormat *fmt,
  1087. char16_t *result,
  1088. int32_t resultLength,
  1089. UErrorCode *status)
  1090. {
  1091. verifyIsRelativeDateFormat(fmt, status);
  1092. if(U_FAILURE(*status)) {
  1093. return -1;
  1094. }
  1095. if (result == nullptr ? resultLength != 0 : resultLength < 0) {
  1096. *status = U_ILLEGAL_ARGUMENT_ERROR;
  1097. return -1;
  1098. }
  1099. UnicodeString datePattern;
  1100. if (result != nullptr) {
  1101. // nullptr destination for pure preflighting: empty dummy string
  1102. // otherwise, alias the destination buffer
  1103. datePattern.setTo(result, 0, resultLength);
  1104. }
  1105. ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status);
  1106. return datePattern.extract(result, resultLength, *status);
  1107. }
  1108. U_CAPI int32_t U_EXPORT2
  1109. udat_toPatternRelativeTime(const UDateFormat *fmt,
  1110. char16_t *result,
  1111. int32_t resultLength,
  1112. UErrorCode *status)
  1113. {
  1114. verifyIsRelativeDateFormat(fmt, status);
  1115. if(U_FAILURE(*status)) {
  1116. return -1;
  1117. }
  1118. if (result == nullptr ? resultLength != 0 : resultLength < 0) {
  1119. *status = U_ILLEGAL_ARGUMENT_ERROR;
  1120. return -1;
  1121. }
  1122. UnicodeString timePattern;
  1123. if (result != nullptr) {
  1124. // nullptr destination for pure preflighting: empty dummy string
  1125. // otherwise, alias the destination buffer
  1126. timePattern.setTo(result, 0, resultLength);
  1127. }
  1128. ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status);
  1129. return timePattern.extract(result, resultLength, *status);
  1130. }
  1131. U_CAPI void U_EXPORT2
  1132. udat_applyPatternRelative(UDateFormat *format,
  1133. const char16_t *datePattern,
  1134. int32_t datePatternLength,
  1135. const char16_t *timePattern,
  1136. int32_t timePatternLength,
  1137. UErrorCode *status)
  1138. {
  1139. verifyIsRelativeDateFormat(format, status);
  1140. if(U_FAILURE(*status)) return;
  1141. const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, datePatternLength);
  1142. const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, timePatternLength);
  1143. ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status);
  1144. }
  1145. #endif /* #if !UCONFIG_NO_FORMATTING */