Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
EastAsianLunisolarCalendar.cs
Go to the documentation of this file.
2
3public abstract class EastAsianLunisolarCalendar : Calendar
4{
5 private static readonly int[] s_daysToMonth365 = new int[12]
6 {
7 0, 31, 59, 90, 120, 151, 181, 212, 243, 273,
8 304, 334
9 };
10
11 private static readonly int[] s_daysToMonth366 = new int[12]
12 {
13 0, 31, 60, 91, 121, 152, 182, 213, 244, 274,
14 305, 335
15 };
16
17 public override CalendarAlgorithmType AlgorithmType => CalendarAlgorithmType.LunisolarCalendar;
18
19 internal abstract int MinCalendarYear { get; }
20
21 internal abstract int MaxCalendarYear { get; }
22
23 internal abstract EraInfo[]? CalEraInfo { get; }
24
25 internal abstract DateTime MinDate { get; }
26
27 internal abstract DateTime MaxDate { get; }
28
29 public override int TwoDigitYearMax
30 {
31 get
32 {
33 if (_twoDigitYearMax == -1)
34 {
36 }
37 return _twoDigitYearMax;
38 }
39 set
40 {
42 if (value < 99 || value > MaxCalendarYear)
43 {
45 }
47 }
48 }
49
50 public virtual int GetSexagenaryYear(DateTime time)
51 {
53 TimeToLunar(time, out var year, out var _, out var _);
54 return (year - 4) % 60 + 1;
55 }
56
57 public int GetCelestialStem(int sexagenaryYear)
58 {
59 if (sexagenaryYear < 1 || sexagenaryYear > 60)
60 {
61 throw new ArgumentOutOfRangeException("sexagenaryYear", sexagenaryYear, SR.Format(SR.ArgumentOutOfRange_Range, 1, 60));
62 }
63 return (sexagenaryYear - 1) % 10 + 1;
64 }
65
66 public int GetTerrestrialBranch(int sexagenaryYear)
67 {
68 if (sexagenaryYear < 1 || sexagenaryYear > 60)
69 {
70 throw new ArgumentOutOfRangeException("sexagenaryYear", sexagenaryYear, SR.Format(SR.ArgumentOutOfRange_Range, 1, 60));
71 }
72 return (sexagenaryYear - 1) % 12 + 1;
73 }
74
75 internal abstract int GetYearInfo(int LunarYear, int Index);
76
77 internal abstract int GetYear(int year, DateTime time);
78
79 internal abstract int GetGregorianYear(int year, int era);
80
81 internal int MinEraCalendarYear(int era)
82 {
83 EraInfo[] calEraInfo = CalEraInfo;
84 if (calEraInfo == null)
85 {
86 return MinCalendarYear;
87 }
88 if (era == 0)
89 {
90 era = CurrentEraValue;
91 }
92 if (era == GetEra(MinDate))
93 {
95 }
96 for (int i = 0; i < calEraInfo.Length; i++)
97 {
98 if (era == calEraInfo[i].era)
99 {
100 return calEraInfo[i].minEraYear;
101 }
102 }
104 }
105
106 internal int MaxEraCalendarYear(int era)
107 {
108 EraInfo[] calEraInfo = CalEraInfo;
109 if (calEraInfo == null)
110 {
111 return MaxCalendarYear;
112 }
113 if (era == 0)
114 {
115 era = CurrentEraValue;
116 }
117 if (era == GetEra(MaxDate))
118 {
120 }
121 for (int i = 0; i < calEraInfo.Length; i++)
122 {
123 if (era == calEraInfo[i].era)
124 {
125 return calEraInfo[i].maxEraYear;
126 }
127 }
129 }
130
132 {
133 }
134
135 internal void CheckTicksRange(long ticks)
136 {
137 if (ticks < MinSupportedDateTime.Ticks || ticks > MaxSupportedDateTime.Ticks)
138 {
140 }
141 }
142
143 internal void CheckEraRange(int era)
144 {
145 if (era == 0)
146 {
147 era = CurrentEraValue;
148 }
149 if (era < GetEra(MinDate) || era > GetEra(MaxDate))
150 {
152 }
153 }
154
155 internal int CheckYearRange(int year, int era)
156 {
157 CheckEraRange(era);
158 year = GetGregorianYear(year, era);
159 if (year < MinCalendarYear || year > MaxCalendarYear)
160 {
162 }
163 return year;
164 }
165
166 internal int CheckYearMonthRange(int year, int month, int era)
167 {
168 year = CheckYearRange(year, era);
169 if (month == 13 && GetYearInfo(year, 0) == 0)
170 {
172 }
173 if (month < 1 || month > 13)
174 {
176 }
177 return year;
178 }
179
180 internal int InternalGetDaysInMonth(int year, int month)
181 {
182 int num = 32768;
183 num >>= month - 1;
184 if ((GetYearInfo(year, 3) & num) == 0)
185 {
186 return 29;
187 }
188 return 30;
189 }
190
191 public override int GetDaysInMonth(int year, int month, int era)
192 {
193 year = CheckYearMonthRange(year, month, era);
194 return InternalGetDaysInMonth(year, month);
195 }
196
197 private static bool GregorianIsLeapYear(int y)
198 {
199 if (y % 4 != 0)
200 {
201 return false;
202 }
203 if (y % 100 != 0)
204 {
205 return true;
206 }
207 return y % 400 == 0;
208 }
209
210 public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
211 {
212 year = CheckYearMonthRange(year, month, era);
213 int num = InternalGetDaysInMonth(year, month);
214 if (day < 1 || day > num)
215 {
216 throw new ArgumentOutOfRangeException("day", day, SR.Format(SR.ArgumentOutOfRange_Day, num, month));
217 }
218 if (!LunarToGregorian(year, month, day, out var solarYear, out var solarMonth, out var solarDay))
219 {
221 }
222 return new DateTime(solarYear, solarMonth, solarDay, hour, minute, second, millisecond);
223 }
224
225 private void GregorianToLunar(int solarYear, int solarMonth, int solarDate, out int lunarYear, out int lunarMonth, out int lunarDate)
226 {
227 int num = (GregorianIsLeapYear(solarYear) ? s_daysToMonth366[solarMonth - 1] : s_daysToMonth365[solarMonth - 1]);
228 num += solarDate;
229 int num2 = num;
230 lunarYear = solarYear;
231 int yearInfo;
232 int yearInfo2;
233 if (lunarYear == MaxCalendarYear + 1)
234 {
235 lunarYear--;
236 num2 += (GregorianIsLeapYear(lunarYear) ? 366 : 365);
237 yearInfo = GetYearInfo(lunarYear, 1);
238 yearInfo2 = GetYearInfo(lunarYear, 2);
239 }
240 else
241 {
242 yearInfo = GetYearInfo(lunarYear, 1);
243 yearInfo2 = GetYearInfo(lunarYear, 2);
244 if (solarMonth < yearInfo || (solarMonth == yearInfo && solarDate < yearInfo2))
245 {
246 lunarYear--;
247 num2 += (GregorianIsLeapYear(lunarYear) ? 366 : 365);
248 yearInfo = GetYearInfo(lunarYear, 1);
249 yearInfo2 = GetYearInfo(lunarYear, 2);
250 }
251 }
252 num2 -= s_daysToMonth365[yearInfo - 1];
253 num2 -= yearInfo2 - 1;
254 int num3 = 32768;
255 int yearInfo3 = GetYearInfo(lunarYear, 3);
256 int num4 = (((yearInfo3 & num3) != 0) ? 30 : 29);
257 lunarMonth = 1;
258 while (num2 > num4)
259 {
260 num2 -= num4;
261 lunarMonth++;
262 num3 >>= 1;
263 num4 = (((yearInfo3 & num3) != 0) ? 30 : 29);
264 }
265 lunarDate = num2;
266 }
267
268 private bool LunarToGregorian(int lunarYear, int lunarMonth, int lunarDate, out int solarYear, out int solarMonth, out int solarDay)
269 {
270 if (lunarDate < 1 || lunarDate > 30)
271 {
272 solarYear = 0;
273 solarMonth = 0;
274 solarDay = 0;
275 return false;
276 }
277 int num = lunarDate - 1;
278 for (int i = 1; i < lunarMonth; i++)
279 {
280 num += InternalGetDaysInMonth(lunarYear, i);
281 }
282 int yearInfo = GetYearInfo(lunarYear, 1);
283 int yearInfo2 = GetYearInfo(lunarYear, 2);
284 bool flag = GregorianIsLeapYear(lunarYear);
285 int[] array = (flag ? s_daysToMonth366 : s_daysToMonth365);
286 solarDay = yearInfo2;
287 if (yearInfo > 1)
288 {
289 solarDay += array[yearInfo - 1];
290 }
291 solarDay += num;
292 if (solarDay > 365 + (flag ? 1 : 0))
293 {
294 solarYear = lunarYear + 1;
295 solarDay -= 365 + (flag ? 1 : 0);
296 }
297 else
298 {
299 solarYear = lunarYear;
300 }
301 solarMonth = 1;
302 while (solarMonth < 12 && array[solarMonth] < solarDay)
303 {
304 solarMonth++;
305 }
306 solarDay -= array[solarMonth - 1];
307 return true;
308 }
309
310 private DateTime LunarToTime(DateTime time, int year, int month, int day)
311 {
312 LunarToGregorian(year, month, day, out var solarYear, out var solarMonth, out var solarDay);
313 time.GetTime(out var hour, out var minute, out var second, out var millisecond);
314 return GregorianCalendar.GetDefaultInstance().ToDateTime(solarYear, solarMonth, solarDay, hour, minute, second, millisecond);
315 }
316
317 private void TimeToLunar(DateTime time, out int year, out int month, out int day)
318 {
320 int year2 = defaultInstance.GetYear(time);
321 int month2 = defaultInstance.GetMonth(time);
322 int dayOfMonth = defaultInstance.GetDayOfMonth(time);
323 GregorianToLunar(year2, month2, dayOfMonth, out year, out month, out day);
324 }
325
326 public override DateTime AddMonths(DateTime time, int months)
327 {
328 if (months < -120000 || months > 120000)
329 {
330 throw new ArgumentOutOfRangeException("months", months, SR.Format(SR.ArgumentOutOfRange_Range, -120000, 120000));
331 }
333 TimeToLunar(time, out var year, out var month, out var day);
334 int num = month + months;
335 if (num > 0)
336 {
337 int num2 = (InternalIsLeapYear(year) ? 13 : 12);
338 while (num - num2 > 0)
339 {
340 num -= num2;
341 year++;
342 num2 = (InternalIsLeapYear(year) ? 13 : 12);
343 }
344 month = num;
345 }
346 else
347 {
348 while (num <= 0)
349 {
350 int num3 = (InternalIsLeapYear(year - 1) ? 13 : 12);
351 num += num3;
352 year--;
353 }
354 month = num;
355 }
356 int num4 = InternalGetDaysInMonth(year, month);
357 if (day > num4)
358 {
359 day = num4;
360 }
361 DateTime result = LunarToTime(time, year, month, day);
363 return result;
364 }
365
366 public override DateTime AddYears(DateTime time, int years)
367 {
369 TimeToLunar(time, out var year, out var month, out var day);
370 year += years;
371 if (month == 13 && !InternalIsLeapYear(year))
372 {
373 month = 12;
374 day = InternalGetDaysInMonth(year, month);
375 }
376 int num = InternalGetDaysInMonth(year, month);
377 if (day > num)
378 {
379 day = num;
380 }
381 DateTime result = LunarToTime(time, year, month, day);
383 return result;
384 }
385
386 public override int GetDayOfYear(DateTime time)
387 {
389 TimeToLunar(time, out var year, out var month, out var day);
390 for (int i = 1; i < month; i++)
391 {
392 day += InternalGetDaysInMonth(year, i);
393 }
394 return day;
395 }
396
397 public override int GetDayOfMonth(DateTime time)
398 {
400 TimeToLunar(time, out var _, out var _, out var day);
401 return day;
402 }
403
404 public override int GetDaysInYear(int year, int era)
405 {
406 year = CheckYearRange(year, era);
407 int num = 0;
408 int num2 = (InternalIsLeapYear(year) ? 13 : 12);
409 while (num2 != 0)
410 {
411 num += InternalGetDaysInMonth(year, num2--);
412 }
413 return num;
414 }
415
416 public override int GetMonth(DateTime time)
417 {
419 TimeToLunar(time, out var _, out var month, out var _);
420 return month;
421 }
422
423 public override int GetYear(DateTime time)
424 {
426 TimeToLunar(time, out var year, out var _, out var _);
427 return GetYear(year, time);
428 }
429
430 public override DayOfWeek GetDayOfWeek(DateTime time)
431 {
433 return (DayOfWeek)((int)(time.Ticks / 864000000000L + 1) % 7);
434 }
435
436 public override int GetMonthsInYear(int year, int era)
437 {
438 year = CheckYearRange(year, era);
440 {
441 return 12;
442 }
443 return 13;
444 }
445
446 public override bool IsLeapDay(int year, int month, int day, int era)
447 {
448 year = CheckYearMonthRange(year, month, era);
449 int num = InternalGetDaysInMonth(year, month);
450 if (day < 1 || day > num)
451 {
452 throw new ArgumentOutOfRangeException("day", day, SR.Format(SR.ArgumentOutOfRange_Day, num, month));
453 }
454 int yearInfo = GetYearInfo(year, 0);
455 if (yearInfo != 0)
456 {
457 return month == yearInfo + 1;
458 }
459 return false;
460 }
461
462 public override bool IsLeapMonth(int year, int month, int era)
463 {
464 year = CheckYearMonthRange(year, month, era);
465 int yearInfo = GetYearInfo(year, 0);
466 if (yearInfo != 0)
467 {
468 return month == yearInfo + 1;
469 }
470 return false;
471 }
472
473 public override int GetLeapMonth(int year, int era)
474 {
475 year = CheckYearRange(year, era);
476 int yearInfo = GetYearInfo(year, 0);
477 if (yearInfo <= 0)
478 {
479 return 0;
480 }
481 return yearInfo + 1;
482 }
483
484 internal bool InternalIsLeapYear(int year)
485 {
486 return GetYearInfo(year, 0) != 0;
487 }
488
489 public override bool IsLeapYear(int year, int era)
490 {
491 year = CheckYearRange(year, era);
492 return InternalIsLeapYear(year);
493 }
494
495 public override int ToFourDigitYear(int year)
496 {
497 if (year < 0)
498 {
500 }
501 year = base.ToFourDigitYear(year);
503 return year;
504 }
505}
virtual DateTime MaxSupportedDateTime
Definition Calendar.cs:15
int GetYear(DateTime time)
virtual DateTime MinSupportedDateTime
Definition Calendar.cs:13
int GetDayOfMonth(DateTime time)
static void CheckAddResult(long ticks, DateTime minValue, DateTime maxValue)
Definition Calendar.cs:89
int GetMonth(DateTime time)
virtual CalendarId BaseCalendarID
Definition Calendar.cs:21
int GetEra(DateTime time)
static int GetSystemTwoDigitYearSetting(CalendarId CalID, int defaultYearValue)
Definition Calendar.cs:378
static CultureInfo InvariantCulture
override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
bool LunarToGregorian(int lunarYear, int lunarMonth, int lunarDate, out int solarYear, out int solarMonth, out int solarDay)
DateTime LunarToTime(DateTime time, int year, int month, int day)
override int GetDaysInMonth(int year, int month, int era)
void TimeToLunar(DateTime time, out int year, out int month, out int day)
override DateTime AddYears(DateTime time, int years)
override bool IsLeapDay(int year, int month, int day, int era)
override DateTime AddMonths(DateTime time, int months)
void GregorianToLunar(int solarYear, int solarMonth, int solarDate, out int lunarYear, out int lunarMonth, out int lunarDate)
int GetYearInfo(int LunarYear, int Index)
override bool IsLeapMonth(int year, int month, int era)
static string ArgumentOutOfRange_Range
Definition SR.cs:1096
static string ArgumentOutOfRange_BadYearMonthDay
Definition SR.cs:974
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string ArgumentOutOfRange_CalendarRange
Definition SR.cs:982
static string ArgumentOutOfRange_Day
Definition SR.cs:998
static string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
static string ArgumentOutOfRange_InvalidEraValue
Definition SR.cs:1040
Definition SR.cs:7
static void ThrowArgumentOutOfRange_Month(int month)
DayOfWeek
Definition DayOfWeek.cs:4
void GetTime(out int hour, out int minute, out int second)
Definition DateTime.cs:850