1/*
2 ******************************************************************************
3 * Copyright (C) 2003-2013, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ******************************************************************************
6 *
7 * File PERSNCAL.H
8 *
9 * Modification History:
10 *
11 *   Date        Name        Description
12 *   9/23/2003 mehran        posted to icu-design
13 *****************************************************************************
14 */
15
16#ifndef PERSNCAL_H
17#define PERSNCAL_H
18
19#include "unicode/utypes.h"
20
21#if !UCONFIG_NO_FORMATTING
22
23#include "unicode/calendar.h"
24
25U_NAMESPACE_BEGIN
26
27/**
28 * <code>PersianCalendar</code> is a subclass of <code>Calendar</code>
29 * that implements the Persian calendar.  It is used as the official
30 * calendar in Iran.  This calendar is also known as the "Hijri Shamsi"
31 * calendar, since it starts at the time of Mohammed's emigration (or
32 * "hijra") to Medinah on Thursday, July 15, 622 AD (Julian) and is a
33 * solar calendar system (or "shamsi").
34 * <p>
35 * The Persian calendar is strictly solar, and thus a Persian year has twelve
36 * solar months. A Persian year is about 365 days long, except in leap years
37 * which is 366 days long.
38 * <p>
39 * The six first months of Persian Calendar are 31 days long. The next five
40 * months are 30 days long. The last month is 29 days long in normal years,
41 * and 30 days long in leap years.
42 *
43 * @see GregorianCalendar
44 *
45 * @author Mehran Mehr
46 * @internal
47 */
48class PersianCalendar : public Calendar {
49 public:
50  //-------------------------------------------------------------------------
51  // Constants...
52  //-------------------------------------------------------------------------
53  /**
54   * Constants for the months
55   * @internal
56   */
57  enum EMonths {
58    /**
59     * Constant for Farvardin, the 1st month of the Persian year.
60     * @internal
61     */
62    FARVARDIN = 0,
63
64    /**
65     * Constant for Ordibehesht, the 2nd month of the Persian year.
66     * @internal
67     */
68    ORDIBEHESHT = 1,
69
70    /**
71     * Constant for Khordad, the 3rd month of the Persian year.
72     * @internal
73     */
74    KHORDAD = 2,
75
76    /**
77     * Constant for Tir, the 4th month of the Persian year.
78     * @internal
79     */
80    TIR = 3,
81
82    /**
83     * Constant for Mordad, the 5th month of the Persian year.
84     * @internal
85     */
86    MORDAD = 4,
87
88    /**
89     * Constant for Shahrivar, the 6th month of the Persian year.
90     * @internal
91     */
92    SHAHRIVAR = 5,
93
94    /**
95     * Constant for Mehr, the 7th month of the Persian year.
96     * @internal
97     */
98    MEHR = 6,
99
100    /**
101     * Constant for Aban, the 8th month of the Persian year.
102     * @internal
103     */
104    ABAN = 7,
105
106    /**
107     * Constant for Azar, the 9th month of the Persian year.
108     * @internal
109     */
110    AZAR = 8,
111
112    /**
113     * Constant for Dei, the 10th month of the Persian year.
114     * @internal
115     */
116    DEI = 9,
117
118    /**
119     * Constant for Bahman, the 11th month of the Persian year.
120     * @internal
121     */
122    BAHMAN = 10,
123
124    /**
125     * Constant for Esfand, the 12th month of the Persian year.
126     * @internal
127     */
128    ESFAND = 11,
129
130    PERSIAN_MONTH_MAX
131  };
132
133
134
135  //-------------------------------------------------------------------------
136  // Constructors...
137  //-------------------------------------------------------------------------
138
139  /**
140   * Constructs a PersianCalendar based on the current time in the default time zone
141   * with the given locale.
142   *
143   * @param aLocale  The given locale.
144   * @param success  Indicates the status of PersianCalendar object construction.
145   *                 Returns U_ZERO_ERROR if constructed successfully.
146   * @internal
147   */
148  PersianCalendar(const Locale& aLocale, UErrorCode &success);
149
150  /**
151   * Copy Constructor
152   * @internal
153   */
154  PersianCalendar(const PersianCalendar& other);
155
156  /**
157   * Destructor.
158   * @internal
159   */
160  virtual ~PersianCalendar();
161
162  // TODO: copy c'tor, etc
163
164  // clone
165  virtual Calendar* clone() const;
166
167 private:
168  /**
169   * Determine whether a year is a leap year in the Persian calendar
170   */
171  static UBool isLeapYear(int32_t year);
172
173  /**
174   * Return the day # on which the given year starts.  Days are counted
175   * from the Hijri epoch, origin 0.
176   */
177  int32_t yearStart(int32_t year);
178
179  /**
180   * Return the day # on which the given month starts.  Days are counted
181   * from the Hijri epoch, origin 0.
182   *
183   * @param year  The hijri shamsi year
184   * @param year  The hijri shamsi month, 0-based
185   */
186  int32_t monthStart(int32_t year, int32_t month) const;
187
188  //----------------------------------------------------------------------
189  // Calendar framework
190  //----------------------------------------------------------------------
191 protected:
192  /**
193   * @internal
194   */
195  virtual int32_t handleGetLimit(UCalendarDateFields field, ELimitType limitType) const;
196
197  /**
198   * Return the length (in days) of the given month.
199   *
200   * @param year  The hijri shamsi year
201   * @param year  The hijri shamsi month, 0-based
202   * @internal
203   */
204  virtual int32_t handleGetMonthLength(int32_t extendedYear, int32_t month) const;
205
206  /**
207   * Return the number of days in the given Persian year
208   * @internal
209   */
210  virtual int32_t handleGetYearLength(int32_t extendedYear) const;
211
212  //-------------------------------------------------------------------------
213  // Functions for converting from field values to milliseconds....
214  //-------------------------------------------------------------------------
215
216  // Return JD of start of given month/year
217  /**
218   * @internal
219   */
220  virtual int32_t handleComputeMonthStart(int32_t eyear, int32_t month, UBool useMonth) const;
221
222  //-------------------------------------------------------------------------
223  // Functions for converting from milliseconds to field values
224  //-------------------------------------------------------------------------
225
226  /**
227   * @internal
228   */
229  virtual int32_t handleGetExtendedYear();
230
231  /**
232   * Override Calendar to compute several fields specific to the Persian
233   * calendar system.  These are:
234   *
235   * <ul><li>ERA
236   * <li>YEAR
237   * <li>MONTH
238   * <li>DAY_OF_MONTH
239   * <li>DAY_OF_YEAR
240   * <li>EXTENDED_YEAR</ul>
241   *
242   * The DAY_OF_WEEK and DOW_LOCAL fields are already set when this
243   * method is called. The getGregorianXxx() methods return Gregorian
244   * calendar equivalents for the given Julian day.
245   * @internal
246   */
247  virtual void handleComputeFields(int32_t julianDay, UErrorCode &status);
248
249  // UObject stuff
250 public:
251  /**
252   * @return   The class ID for this object. All objects of a given class have the
253   *           same class ID. Objects of other classes have different class IDs.
254   * @internal
255   */
256  virtual UClassID getDynamicClassID(void) const;
257
258  /**
259   * Return the class ID for this class. This is useful only for comparing to a return
260   * value from getDynamicClassID(). For example:
261   *
262   *      Base* polymorphic_pointer = createPolymorphicObject();
263   *      if (polymorphic_pointer->getDynamicClassID() ==
264   *          Derived::getStaticClassID()) ...
265   *
266   * @return   The class ID for all objects of this class.
267   * @internal
268   */
269  U_I18N_API static UClassID U_EXPORT2 getStaticClassID(void);
270
271  /**
272   * return the calendar type, "persian".
273   *
274   * @return calendar type
275   * @internal
276   */
277  virtual const char * getType() const;
278
279 private:
280  PersianCalendar(); // default constructor not implemented
281
282 protected:
283
284  /**
285   * (Overrides Calendar) Return true if the current date for this Calendar is in
286   * Daylight Savings Time. Recognizes DST_OFFSET, if it is set.
287   *
288   * @param status Fill-in parameter which receives the status of this operation.
289   * @return   True if the current date for this Calendar is in Daylight Savings Time,
290   *           false, otherwise.
291   * @internal
292   */
293  virtual UBool inDaylightTime(UErrorCode& status) const;
294
295  /**
296   * Returns TRUE because the Persian Calendar does have a default century
297   * @internal
298   */
299  virtual UBool haveDefaultCentury() const;
300
301  /**
302   * Returns the date of the start of the default century
303   * @return start of century - in milliseconds since epoch, 1970
304   * @internal
305   */
306  virtual UDate defaultCenturyStart() const;
307
308  /**
309   * Returns the year in which the default century begins
310   * @internal
311   */
312  virtual int32_t defaultCenturyStartYear() const;
313};
314
315U_NAMESPACE_END
316
317#endif
318#endif
319
320
321
322