2 // System.Globalization.EastAsianLunisolarCalendar.cs
6 // Atsushi Enomoto <atsushi@ximian.com>
8 // (C) Ulrich Kunitz 2002
9 // Copyright (C) 2007 Novell, Inc. http://www.novell.com
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 namespace System.Globalization {
40 [System.Runtime.InteropServices.ComVisible (true)]
41 public abstract class EastAsianLunisolarCalendar : Calendar {
42 // FIXME: This is ok and it does not have to be something like
43 // CCEastAsianLunisolarEraHandler since it does not depend on
44 // any lunisolar stuff.
45 internal readonly CCEastAsianLunisolarEraHandler M_EraHandler;
47 internal EastAsianLunisolarCalendar (CCEastAsianLunisolarEraHandler eraHandler)
49 M_EraHandler = eraHandler;
52 public override int TwoDigitYearMax
55 return twoDigitYearMax;
59 M_ArgumentInRange ("value", value, 100, M_MaxYear);
61 twoDigitYearMax = value;
65 internal void M_CheckDateTime(DateTime time) {
66 M_EraHandler.CheckDateTime(time);
69 internal virtual int ActualCurrentEra {
73 internal void M_CheckEra(ref int era) {
74 if (era == CurrentEra)
75 era = ActualCurrentEra;
76 if (!M_EraHandler.ValidEra(era))
77 throw new ArgumentException("Era value was not valid.");
80 internal int M_CheckYEG(int year, ref int era) {
82 return M_EraHandler.GregorianYear(year, era);
85 internal override void M_CheckYE(int year, ref int era) {
86 M_CheckYEG(year, ref era);
89 internal int M_CheckYMEG(int year, int month, ref int era) {
90 int gregorianYear = M_CheckYEG(year, ref era);
91 if (month < 1 || month > 12)
92 throw new ArgumentOutOfRangeException("month",
93 "Month must be between one and twelve.");
97 internal int M_CheckYMDEG(int year, int month, int day, ref int era)
99 int gregorianYear = M_CheckYMEG(year, month, ref era);
100 M_ArgumentInRange("day", day, 1, GetDaysInMonth(year, month, era));
101 return gregorianYear;
105 public override DateTime AddMonths(DateTime time, int months) {
106 DateTime t = CCEastAsianLunisolarCalendar.AddMonths(time, months);
112 public override DateTime AddYears(DateTime time, int years) {
113 DateTime t = CCEastAsianLunisolarCalendar.AddYears(time, years);
119 public override int GetDayOfMonth(DateTime time) {
120 M_CheckDateTime(time);
121 return CCEastAsianLunisolarCalendar.GetDayOfMonth(time);
125 public override DayOfWeek GetDayOfWeek(DateTime time) {
126 M_CheckDateTime(time);
127 int rd = CCFixed.FromDateTime(time);
128 return (DayOfWeek)CCFixed.day_of_week(rd);
132 public override int GetDayOfYear(DateTime time) {
133 M_CheckDateTime(time);
134 return CCEastAsianLunisolarCalendar.GetDayOfYear(time);
138 public override int GetDaysInMonth(int year, int month, int era) {
139 int gregorianYear = M_CheckYMEG(year, month, ref era);
140 return CCEastAsianLunisolarCalendar.GetDaysInMonth(gregorianYear, month);
144 public override int GetDaysInYear(int year, int era) {
145 int gregorianYear = M_CheckYEG(year, ref era);
146 return CCEastAsianLunisolarCalendar.GetDaysInYear(gregorianYear);
151 public override int GetLeapMonth(int year, int era)
153 return base.GetLeapMonth(year, era);
157 public override int GetMonth(DateTime time) {
158 M_CheckDateTime(time);
159 return CCEastAsianLunisolarCalendar.GetMonth(time);
163 public override int GetMonthsInYear(int year, int era) {
164 M_CheckYE(year, ref era);
165 return IsLeapYear (year, era) ? 13: 12;
168 public override int GetYear(DateTime time) {
169 // M_CheckDateTime not needed, because EraYeat does the
171 int rd = CCFixed.FromDateTime(time);
173 return M_EraHandler.EraYear(out era, rd);
176 public override bool IsLeapDay(int year, int month, int day, int era)
178 int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
179 // every day in LeapMonth is a LeapDay.
180 return CCEastAsianLunisolarCalendar.IsLeapMonth (gregorianYear, month);
184 public override bool IsLeapMonth(int year, int month, int era) {
185 int gregorianYear = M_CheckYMEG(year, month, ref era);
186 return CCEastAsianLunisolarCalendar.IsLeapMonth(gregorianYear, month);
189 public override bool IsLeapYear(int year, int era) {
190 int gregorianYear = M_CheckYEG(year, ref era);
191 return CCEastAsianLunisolarCalendar.IsLeapYear (gregorianYear);
195 public override DateTime ToDateTime(int year, int month, int day,
196 int hour, int minute, int second, int millisecond,
199 int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
200 M_CheckHMSM(hour, minute, second, millisecond);
201 return CCGregorianCalendar.ToDateTime(
202 gregorianYear, month, day,
203 hour, minute, second, millisecond);
207 public override int ToFourDigitYear(int year) {
209 throw new ArgumentOutOfRangeException(
210 "year", "Non-negative number required.");
211 int era = CurrentEra;
212 M_CheckYE(year, ref era);
216 public override CalendarAlgorithmType AlgorithmType {
218 return CalendarAlgorithmType.LunisolarCalendar;
223 #region celestial/terrestial thingy
224 public int GetCelestialStem (int sexagenaryYear)
226 if (sexagenaryYear < 1 || 60 < sexagenaryYear)
227 throw new ArgumentOutOfRangeException ("sexagendaryYear is less than 0 or greater than 60");
228 return (sexagenaryYear - 1) % 10 + 1;
231 public virtual int GetSexagenaryYear (DateTime time)
233 return (GetYear (time) - 1900) % 60;
236 public int GetTerrestrialBranch (int sexagenaryYear)
238 if (sexagenaryYear < 1 || 60 < sexagenaryYear)
239 throw new ArgumentOutOfRangeException ("sexagendaryYear is less than 0 or greater than 60");
240 return (sexagenaryYear - 1) % 12 + 1;