2009-07-30 Gonzalo Paniagua Javier <gonzalo@novell.com>
[mono.git] / mcs / class / corlib / System.Globalization / EastAsianLunisolarCalendar.cs
1 //
2 // System.Globalization.EastAsianLunisolarCalendar.cs
3 //
4 // Author
5 //      Ulrich Kunitz 2002
6 //      Atsushi Enomoto  <atsushi@ximian.com>
7 //
8 // (C) Ulrich Kunitz 2002
9 // Copyright (C) 2007 Novell, Inc.  http://www.novell.com
10 //
11
12 //
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:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
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.
31 //
32
33 #if NET_2_0
34
35 namespace System.Globalization {
36
37 using System;
38
39 [Serializable]
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;
46
47         internal EastAsianLunisolarCalendar (CCEastAsianLunisolarEraHandler eraHandler)
48         {
49                 M_EraHandler = eraHandler;
50         }
51
52         public override int TwoDigitYearMax 
53         {
54                 get {
55                         return twoDigitYearMax;
56                 }
57                 set {
58                         CheckReadOnly ();
59                         M_ArgumentInRange ("value", value, 100, M_MaxYear);
60
61                         twoDigitYearMax = value;
62                 }
63         }
64         
65         internal void M_CheckDateTime(DateTime time) {
66                 M_EraHandler.CheckDateTime(time);
67         }
68
69         internal virtual int ActualCurrentEra {
70                 get { return 1; }
71         }
72
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.");
78         }
79
80         internal int M_CheckYEG(int year, ref int era) {
81                 M_CheckEra(ref era);
82                 return M_EraHandler.GregorianYear(year, era);
83         }
84
85         internal override void M_CheckYE(int year, ref int era) {
86                 M_CheckYEG(year, ref era);
87         }
88
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.");
94                 return gregorianYear;
95         }
96
97         internal int M_CheckYMDEG(int year, int month, int day, ref int era)
98         {
99                 int gregorianYear = M_CheckYMEG(year, month, ref era);
100                 M_ArgumentInRange("day", day, 1, GetDaysInMonth(year, month, era));
101                 return gregorianYear;
102         }
103
104         [MonoTODO]
105         public override DateTime AddMonths(DateTime time, int months) {
106                 DateTime t = CCEastAsianLunisolarCalendar.AddMonths(time, months);
107                 M_CheckDateTime(t);
108                 return t;
109         }
110
111         [MonoTODO]
112         public override DateTime AddYears(DateTime time, int years) {
113                 DateTime t = CCEastAsianLunisolarCalendar.AddYears(time, years);
114                 M_CheckDateTime(t);
115                 return t;
116         }
117                 
118         [MonoTODO]
119         public override int GetDayOfMonth(DateTime time) {
120                 M_CheckDateTime(time);
121                 return CCEastAsianLunisolarCalendar.GetDayOfMonth(time);
122         }
123
124         [MonoTODO]
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);
129         }
130
131         [MonoTODO]
132         public override int GetDayOfYear(DateTime time) {
133                 M_CheckDateTime(time);
134                 return CCEastAsianLunisolarCalendar.GetDayOfYear(time);
135         }
136
137         [MonoTODO]
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);
141         }
142
143         [MonoTODO]
144         public override int GetDaysInYear(int year, int era) {
145                 int gregorianYear = M_CheckYEG(year, ref era);
146                 return CCEastAsianLunisolarCalendar.GetDaysInYear(gregorianYear);
147         }
148                 
149
150         [MonoTODO]
151         public override int GetLeapMonth(int year, int era)
152         {
153                 return base.GetLeapMonth(year, era);
154         }
155
156         [MonoTODO]
157         public override int GetMonth(DateTime time) {
158                 M_CheckDateTime(time);
159                 return CCEastAsianLunisolarCalendar.GetMonth(time);
160         }
161
162         [MonoTODO]
163         public override int GetMonthsInYear(int year, int era) {
164                 M_CheckYE(year, ref era);
165                 return IsLeapYear (year, era) ? 13: 12;
166         }
167
168         public override int GetYear(DateTime time) {
169                 // M_CheckDateTime not needed, because EraYeat does the
170                 // right thing.
171                 int rd = CCFixed.FromDateTime(time);
172                 int era;
173                 return M_EraHandler.EraYear(out era, rd);
174         }
175
176         public override bool IsLeapDay(int year, int month, int day, int era)
177         {
178                 int gregorianYear = M_CheckYMDEG(year, month, day, ref era);
179                 // every day in LeapMonth is a LeapDay.
180                 return CCEastAsianLunisolarCalendar.IsLeapMonth (gregorianYear, month);
181         }
182
183         [MonoTODO]
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);
187         }
188
189         public override bool IsLeapYear(int year, int era) {
190                 int gregorianYear = M_CheckYEG(year, ref era);
191                 return CCEastAsianLunisolarCalendar.IsLeapYear (gregorianYear);
192         }
193
194         [MonoTODO]
195         public override DateTime ToDateTime(int year, int month, int day,
196                 int hour, int minute, int second, int millisecond,
197                 int era)
198         {
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);
204         }
205
206         [MonoTODO]
207         public override int ToFourDigitYear(int year) {
208                 if (year < 0)
209                         throw new ArgumentOutOfRangeException(
210                                 "year", "Non-negative number required.");
211                 int era = CurrentEra;
212                 M_CheckYE(year, ref era);
213                 return year;
214         }
215
216         public override CalendarAlgorithmType AlgorithmType {
217                 get {
218                         return CalendarAlgorithmType.LunisolarCalendar;
219                 }
220         }
221
222
223         #region celestial/terrestial thingy
224         public int GetCelestialStem (int sexagenaryYear)
225         {
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;
229         }
230
231         public virtual int GetSexagenaryYear (DateTime time)
232         {
233                 return (GetYear (time) - 1900) % 60;
234         }
235
236         public int GetTerrestrialBranch (int sexagenaryYear)
237         {
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;
241         }
242         #endregion
243 }
244 }
245
246 #endif