coptccal.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. *******************************************************************************
  5. * Copyright (C) 2003 - 2013, International Business Machines Corporation and
  6. * others. All Rights Reserved.
  7. *******************************************************************************
  8. */
  9. #include "unicode/utypes.h"
  10. #if !UCONFIG_NO_FORMATTING
  11. #include "umutex.h"
  12. #include "coptccal.h"
  13. #include "cecal.h"
  14. #include <float.h>
  15. U_NAMESPACE_BEGIN
  16. UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CopticCalendar)
  17. static const int32_t COPTIC_JD_EPOCH_OFFSET = 1824665;
  18. //-------------------------------------------------------------------------
  19. // Constructors...
  20. //-------------------------------------------------------------------------
  21. CopticCalendar::CopticCalendar(const Locale& aLocale, UErrorCode& success)
  22. : CECalendar(aLocale, success)
  23. {
  24. }
  25. CopticCalendar::CopticCalendar (const CopticCalendar& other)
  26. : CECalendar(other)
  27. {
  28. }
  29. CopticCalendar::~CopticCalendar()
  30. {
  31. }
  32. CopticCalendar*
  33. CopticCalendar::clone() const
  34. {
  35. return new CopticCalendar(*this);
  36. }
  37. const char*
  38. CopticCalendar::getType() const
  39. {
  40. return "coptic";
  41. }
  42. //-------------------------------------------------------------------------
  43. // Calendar framework
  44. //-------------------------------------------------------------------------
  45. int32_t
  46. CopticCalendar::handleGetExtendedYear()
  47. {
  48. int32_t eyear;
  49. if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) {
  50. eyear = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1
  51. } else {
  52. // The year defaults to the epoch start, the era to CE
  53. int32_t era = internalGet(UCAL_ERA, CE);
  54. if (era == BCE) {
  55. eyear = 1 - internalGet(UCAL_YEAR, 1); // Convert to extended year
  56. } else {
  57. eyear = internalGet(UCAL_YEAR, 1); // Default to year 1
  58. }
  59. }
  60. return eyear;
  61. }
  62. void
  63. CopticCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/)
  64. {
  65. int32_t eyear, month, day, era, year;
  66. jdToCE(julianDay, getJDEpochOffset(), eyear, month, day);
  67. if (eyear <= 0) {
  68. era = BCE;
  69. year = 1 - eyear;
  70. } else {
  71. era = CE;
  72. year = eyear;
  73. }
  74. internalSet(UCAL_EXTENDED_YEAR, eyear);
  75. internalSet(UCAL_ERA, era);
  76. internalSet(UCAL_YEAR, year);
  77. internalSet(UCAL_MONTH, month);
  78. internalSet(UCAL_ORDINAL_MONTH, month);
  79. internalSet(UCAL_DATE, day);
  80. internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
  81. }
  82. constexpr uint32_t kCopticRelatedYearDiff = 284;
  83. int32_t CopticCalendar::getRelatedYear(UErrorCode &status) const
  84. {
  85. int32_t year = get(UCAL_EXTENDED_YEAR, status);
  86. if (U_FAILURE(status)) {
  87. return 0;
  88. }
  89. return year + kCopticRelatedYearDiff;
  90. }
  91. void CopticCalendar::setRelatedYear(int32_t year)
  92. {
  93. // set extended year
  94. set(UCAL_EXTENDED_YEAR, year - kCopticRelatedYearDiff);
  95. }
  96. /**
  97. * The system maintains a static default century start date and Year. They are
  98. * initialized the first time they are used. Once the system default century date
  99. * and year are set, they do not change.
  100. */
  101. static UDate gSystemDefaultCenturyStart = DBL_MIN;
  102. static int32_t gSystemDefaultCenturyStartYear = -1;
  103. static icu::UInitOnce gSystemDefaultCenturyInit {};
  104. static void U_CALLCONV initializeSystemDefaultCentury() {
  105. UErrorCode status = U_ZERO_ERROR;
  106. CopticCalendar calendar(Locale("@calendar=coptic"), status);
  107. if (U_SUCCESS(status)) {
  108. calendar.setTime(Calendar::getNow(), status);
  109. calendar.add(UCAL_YEAR, -80, status);
  110. gSystemDefaultCenturyStart = calendar.getTime(status);
  111. gSystemDefaultCenturyStartYear = calendar.get(UCAL_YEAR, status);
  112. }
  113. // We have no recourse upon failure unless we want to propagate the failure
  114. // out.
  115. }
  116. UDate
  117. CopticCalendar::defaultCenturyStart() const
  118. {
  119. // lazy-evaluate systemDefaultCenturyStart
  120. umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury);
  121. return gSystemDefaultCenturyStart;
  122. }
  123. int32_t
  124. CopticCalendar::defaultCenturyStartYear() const
  125. {
  126. // lazy-evaluate systemDefaultCenturyStart
  127. umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury);
  128. return gSystemDefaultCenturyStartYear;
  129. }
  130. int32_t
  131. CopticCalendar::getJDEpochOffset() const
  132. {
  133. return COPTIC_JD_EPOCH_OFFSET;
  134. }
  135. #if 0
  136. // We do not want to introduce this API in ICU4C.
  137. // It was accidentally introduced in ICU4J as a public API.
  138. //-------------------------------------------------------------------------
  139. // Calendar system Conversion methods...
  140. //-------------------------------------------------------------------------
  141. int32_t
  142. CopticCalendar::copticToJD(int32_t year, int32_t month, int32_t day)
  143. {
  144. return CECalendar::ceToJD(year, month, day, COPTIC_JD_EPOCH_OFFSET);
  145. }
  146. #endif
  147. U_NAMESPACE_END
  148. #endif /* #if !UCONFIG_NO_FORMATTING */
  149. //eof