132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2005 John Chapman. All rights reserved
|
|
4
|
|
5 license: BSD style: $(LICENSE)
|
|
6
|
|
7 version: Mid 2005: Initial release
|
|
8 Apr 2007: reshaped
|
|
9
|
|
10 author: John Chapman, Kris
|
|
11
|
|
12 ******************************************************************************/
|
|
13
|
|
14 module tango.time.chrono.Hijri;
|
|
15
|
|
16 private import tango.time.chrono.Calendar;
|
|
17
|
|
18
|
|
19 /**
|
|
20 * $(ANCHOR _Hijri)
|
|
21 * Represents the Hijri calendar.
|
|
22 */
|
|
23 public class Hijri : Calendar {
|
|
24
|
|
25 private static const uint[] DAYS_TO_MONTH = [ 0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325, 355 ];
|
|
26
|
|
27 /**
|
|
28 * Represents the current era.
|
|
29 */
|
|
30 public const uint HIJRI_ERA = 1;
|
|
31
|
|
32 /**
|
|
33 * Overridden. Returns a Time value set to the specified date and time in the specified _era.
|
|
34 * Params:
|
|
35 * year = An integer representing the _year.
|
|
36 * month = An integer representing the _month.
|
|
37 * day = An integer representing the _day.
|
|
38 * hour = An integer representing the _hour.
|
|
39 * minute = An integer representing the _minute.
|
|
40 * second = An integer representing the _second.
|
|
41 * millisecond = An integer representing the _millisecond.
|
|
42 * era = An integer representing the _era.
|
|
43 * Returns: A Time set to the specified date and time.
|
|
44 */
|
|
45 public override Time toTime(uint year, uint month, uint day, uint hour, uint minute, uint second, uint millisecond, uint era) {
|
|
46 return Time((daysSinceJan1(year, month, day) - 1) * TimeSpan.TicksPerDay + getTimeTicks(hour, minute, second)) + TimeSpan.millis(millisecond);
|
|
47 }
|
|
48
|
|
49 /**
|
|
50 * Overridden. Returns the day of the week in the specified Time.
|
|
51 * Params: time = A Time value.
|
|
52 * Returns: A DayOfWeek value representing the day of the week of time.
|
|
53 */
|
|
54 public override DayOfWeek getDayOfWeek(Time time) {
|
|
55 return cast(DayOfWeek) (cast(uint) (time.ticks / TimeSpan.TicksPerDay + 1) % 7);
|
|
56 }
|
|
57
|
|
58 /**
|
|
59 * Overridden. Returns the day of the month in the specified Time.
|
|
60 * Params: time = A Time value.
|
|
61 * Returns: An integer representing the day of the month of time.
|
|
62 */
|
|
63 public override uint getDayOfMonth(Time time) {
|
|
64 return extractPart(time.ticks, DatePart.Day);
|
|
65 }
|
|
66
|
|
67 /**
|
|
68 * Overridden. Returns the day of the year in the specified Time.
|
|
69 * Params: time = A Time value.
|
|
70 * Returns: An integer representing the day of the year of time.
|
|
71 */
|
|
72 public override uint getDayOfYear(Time time) {
|
|
73 return extractPart(time.ticks, DatePart.DayOfYear);
|
|
74 }
|
|
75
|
|
76 /**
|
|
77 * Overridden. Returns the day of the year in the specified Time.
|
|
78 * Params: time = A Time value.
|
|
79 * Returns: An integer representing the day of the year of time.
|
|
80 */
|
|
81 public override uint getMonth(Time time) {
|
|
82 return extractPart(time.ticks, DatePart.Month);
|
|
83 }
|
|
84
|
|
85 /**
|
|
86 * Overridden. Returns the year in the specified Time.
|
|
87 * Params: time = A Time value.
|
|
88 * Returns: An integer representing the year in time.
|
|
89 */
|
|
90 public override uint getYear(Time time) {
|
|
91 return extractPart(time.ticks, DatePart.Year);
|
|
92 }
|
|
93
|
|
94 /**
|
|
95 * Overridden. Returns the era in the specified Time.
|
|
96 * Params: time = A Time value.
|
|
97 * Returns: An integer representing the ear in time.
|
|
98 */
|
|
99 public override uint getEra(Time time) {
|
|
100 return HIJRI_ERA;
|
|
101 }
|
|
102
|
|
103 /**
|
|
104 * Overridden. Returns the number of days in the specified _year and _month of the specified _era.
|
|
105 * Params:
|
|
106 * year = An integer representing the _year.
|
|
107 * month = An integer representing the _month.
|
|
108 * era = An integer representing the _era.
|
|
109 * Returns: The number of days in the specified _year and _month of the specified _era.
|
|
110 */
|
|
111 public override uint getDaysInMonth(uint year, uint month, uint era) {
|
|
112 if (month == 12)
|
|
113 return isLeapYear(year, CURRENT_ERA) ? 30 : 29;
|
|
114 return (month % 2 == 1) ? 30 : 29;
|
|
115 }
|
|
116
|
|
117 /**
|
|
118 * Overridden. Returns the number of days in the specified _year of the specified _era.
|
|
119 * Params:
|
|
120 * year = An integer representing the _year.
|
|
121 * era = An integer representing the _era.
|
|
122 * Returns: The number of days in the specified _year in the specified _era.
|
|
123 */
|
|
124 public override uint getDaysInYear(uint year, uint era) {
|
|
125 return isLeapYear(year, era) ? 355 : 354;
|
|
126 }
|
|
127
|
|
128 /**
|
|
129 * Overridden. Returns the number of months in the specified _year of the specified _era.
|
|
130 * Params:
|
|
131 * year = An integer representing the _year.
|
|
132 * era = An integer representing the _era.
|
|
133 * Returns: The number of months in the specified _year in the specified _era.
|
|
134 */
|
|
135 public override uint getMonthsInYear(uint year, uint era) {
|
|
136 return 12;
|
|
137 }
|
|
138
|
|
139 /**
|
|
140 * Overridden. Indicates whether the specified _year in the specified _era is a leap _year.
|
|
141 * Params: year = An integer representing the _year.
|
|
142 * Params: era = An integer representing the _era.
|
|
143 * Returns: true is the specified _year is a leap _year; otherwise, false.
|
|
144 */
|
|
145 public override bool isLeapYear(uint year, uint era) {
|
|
146 return (14 + 11 * year) % 30 < 11;
|
|
147 }
|
|
148
|
|
149 /**
|
|
150 * $(I Property.) Overridden. Retrieves the list of eras in the current calendar.
|
|
151 * Returns: An integer array representing the eras in the current calendar.
|
|
152 */
|
|
153 public override uint[] eras() {
|
|
154 auto tmp = [HIJRI_ERA];
|
|
155 return tmp.dup;
|
|
156 }
|
|
157
|
|
158 /**
|
|
159 * $(I Property.) Overridden. Retrieves the identifier associated with the current calendar.
|
|
160 * Returns: An integer representing the identifier of the current calendar.
|
|
161 */
|
|
162 public override uint id() {
|
|
163 return HIJRI;
|
|
164 }
|
|
165
|
|
166 private long daysToYear(uint year) {
|
|
167 int cycle = ((year - 1) / 30) * 30;
|
|
168 int remaining = year - cycle - 1;
|
|
169 long days = ((cycle * 10631L) / 30L) + 227013L;
|
|
170 while (remaining > 0) {
|
|
171 days += 354 + (isLeapYear(remaining, CURRENT_ERA) ? 1 : 0);
|
|
172 remaining--;
|
|
173 }
|
|
174 return days;
|
|
175 }
|
|
176
|
|
177 private long daysSinceJan1(uint year, uint month, uint day) {
|
|
178 return cast(long)(daysToYear(year) + DAYS_TO_MONTH[month - 1] + day);
|
|
179 }
|
|
180
|
|
181 private int extractPart(long ticks, DatePart part) {
|
|
182 long days = TimeSpan(ticks).days + 1;
|
|
183 int year = cast(int)(((days - 227013) * 30) / 10631) + 1;
|
|
184 long daysUpToYear = daysToYear(year);
|
|
185 long daysInYear = getDaysInYear(year, CURRENT_ERA);
|
|
186 if (days < daysUpToYear) {
|
|
187 daysUpToYear -= daysInYear;
|
|
188 year--;
|
|
189 }
|
|
190 else if (days == daysUpToYear) {
|
|
191 year--;
|
|
192 daysUpToYear -= getDaysInYear(year, CURRENT_ERA);
|
|
193 }
|
|
194 else if (days > daysUpToYear + daysInYear) {
|
|
195 daysUpToYear += daysInYear;
|
|
196 year++;
|
|
197 }
|
|
198
|
|
199 if (part == DatePart.Year)
|
|
200 return year;
|
|
201
|
|
202 days -= daysUpToYear;
|
|
203 if (part == DatePart.DayOfYear)
|
|
204 return cast(int)days;
|
|
205
|
|
206 int month = 1;
|
|
207 while (month <= 12 && days > DAYS_TO_MONTH[month - 1])
|
|
208 month++;
|
|
209 month--;
|
|
210 if (part == DatePart.Month)
|
|
211 return month;
|
|
212
|
|
213 return cast(int)(days - DAYS_TO_MONTH[month - 1]);
|
|
214 }
|
|
215
|
|
216 }
|
|
217
|