Merge pull request #3389 from lambdageek/bug-43099
[mono.git] / mcs / class / referencesource / mscorlib / system / globalization / taiwancalendar.cs
1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 //
5 // ==--==
6 namespace System.Globalization {
7
8     using System;
9     using System.Diagnostics.CodeAnalysis;
10     using System.Diagnostics.Contracts;
11     /* 
12
13     **
14     ** Taiwan calendar is based on the Gregorian calendar.  And the year is an offset to Gregorian calendar.
15     ** That is,
16     **      Taiwan year = Gregorian year - 1911.  So 1912/01/01 A.D. is Taiwan 1/01/01
17     **
18     **  Calendar support range:
19     **      Calendar    Minimum     Maximum
20     **      ==========  ==========  ==========
21     **      Gregorian   1912/01/01  9999/12/31
22     **      Taiwan      01/01/01    8088/12/31
23     ============================================================================*/
24   
25
26     [System.Runtime.InteropServices.ComVisible(true)]
27     [Serializable] public class TaiwanCalendar: Calendar {
28         //
29         // The era value for the current era.
30         //
31
32         // Since
33         //    Gregorian Year = Era Year + yearOffset
34         // When Gregorian Year 1912 is year 1, so that
35         //    1912 = 1 + yearOffset
36         //  So yearOffset = 1911
37         //m_EraInfo[0] = new EraInfo(1, new DateTime(1912, 1, 1).Ticks, 1911, 1, GregorianCalendar.MaxYear - 1911);
38
39         // Initialize our era info.
40         static internal EraInfo[] taiwanEraInfo = new EraInfo[] {
41             new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911)    // era #, start year/month/day, yearOffset, minEraYear 
42         };
43
44         internal static volatile Calendar s_defaultInstance;
45
46         internal GregorianCalendarHelper helper;
47
48         /*=================================GetDefaultInstance==========================
49         **Action: Internal method to provide a default intance of TaiwanCalendar.  Used by NLS+ implementation
50         **       and other calendars.
51         **Returns:
52         **Arguments:
53         **Exceptions:
54         ============================================================================*/
55
56         internal static Calendar GetDefaultInstance() {
57             if (s_defaultInstance == null) {
58                 s_defaultInstance = new TaiwanCalendar();
59             }
60             return (s_defaultInstance);
61         }
62
63         internal static readonly DateTime calendarMinValue = new DateTime(1912, 1, 1);
64
65
66         [System.Runtime.InteropServices.ComVisible(false)]
67         public override DateTime MinSupportedDateTime
68         {
69             get
70             {
71                 return (calendarMinValue);
72             }
73         }
74
75         [System.Runtime.InteropServices.ComVisible(false)]
76         public override DateTime MaxSupportedDateTime
77         {
78             get
79             {
80                 return (DateTime.MaxValue);
81             }
82         }
83
84         // Return the type of the Taiwan calendar.
85         //
86
87         [System.Runtime.InteropServices.ComVisible(false)]
88         public override CalendarAlgorithmType AlgorithmType
89         {
90             get
91             {
92                 return CalendarAlgorithmType.SolarCalendar;
93             }
94         }
95
96
97         public TaiwanCalendar() {
98             try {
99                 new CultureInfo("zh-TW");
100             } catch (ArgumentException e) {
101                 throw new TypeInitializationException(this.GetType().FullName, e);
102             }
103             helper = new GregorianCalendarHelper(this, taiwanEraInfo);
104         }
105
106         internal override int ID {
107             get {
108                 return (CAL_TAIWAN);
109             }
110         }
111
112
113         public override DateTime AddMonths(DateTime time, int months) {
114             return (helper.AddMonths(time, months));
115         }
116
117
118         public override DateTime AddYears(DateTime time, int years) {
119             return (helper.AddYears(time, years));
120         }
121
122
123         public override int GetDaysInMonth(int year, int month, int era) {
124             return (helper.GetDaysInMonth(year, month, era));
125         }
126
127
128         public override int GetDaysInYear(int year, int era) {
129             return (helper.GetDaysInYear(year, era));
130         }
131
132
133         public override int GetDayOfMonth(DateTime time) {
134             return (helper.GetDayOfMonth(time));
135         }
136
137
138         public override DayOfWeek GetDayOfWeek(DateTime time)  {
139             return (helper.GetDayOfWeek(time));
140         }
141
142
143         public override int GetDayOfYear(DateTime time)
144         {
145             return (helper.GetDayOfYear(time));
146         }
147
148
149         public override int GetMonthsInYear(int year, int era) {
150             return (helper.GetMonthsInYear(year, era));
151         }
152
153
154         [SuppressMessage("Microsoft.Contracts", "CC1055")]  // Skip extra error checking to avoid *potential* AppCompat problems.
155         [System.Runtime.InteropServices.ComVisible(false)]
156         public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
157         {
158             return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
159         }
160
161
162         public override int GetEra(DateTime time) {
163             return (helper.GetEra(time));
164         }
165
166         public override int GetMonth(DateTime time) {
167             return (helper.GetMonth(time));
168         }
169
170
171         public override int GetYear(DateTime time) {
172             return (helper.GetYear(time));
173         }
174
175
176         public override bool IsLeapDay(int year, int month, int day, int era)
177         {
178             return (helper.IsLeapDay(year, month, day, era));
179         }
180
181
182         public override bool IsLeapYear(int year, int era) {
183             return (helper.IsLeapYear(year, era));
184         }
185
186         // Returns  the leap month in a calendar year of the specified era. This method returns 0
187         // if this calendar does not have leap month, or this year is not a leap year.
188         //
189
190         [System.Runtime.InteropServices.ComVisible(false)]
191         public override int GetLeapMonth(int year, int era)
192         {
193             return (helper.GetLeapMonth(year, era));
194         }
195
196
197         public override bool IsLeapMonth(int year, int month, int era) {
198             return (helper.IsLeapMonth(year, month, era));
199         }
200
201
202         public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
203             return (helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era));
204         }
205
206
207         public override int[] Eras {
208             get {
209                 return (helper.Eras);
210             }
211         }
212
213         private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 99;
214
215         public override int TwoDigitYearMax {
216             get {
217                 if (twoDigitYearMax == -1) {
218                     twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
219                 }
220                 return (twoDigitYearMax);
221             }
222
223             set {
224                 VerifyWritable();
225                 if (value < 99 || value > helper.MaxYear)
226                 {
227                     throw new ArgumentOutOfRangeException(
228                                 "year",
229                                 String.Format(
230                                     CultureInfo.CurrentCulture,
231                                     Environment.GetResourceString("ArgumentOutOfRange_Range"),
232                                     99,
233                                     helper.MaxYear));
234
235                 }
236                 twoDigitYearMax = value;
237             }
238         }
239
240         // For Taiwan calendar, four digit year is not used.
241         // Therefore, for any two digit number, we just return the original number.
242
243         public override int ToFourDigitYear(int year) {
244             if (year <= 0) {
245                 throw new ArgumentOutOfRangeException("year",
246                     Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
247             }
248             Contract.EndContractBlock();
249
250             if (year > helper.MaxYear) {
251                 throw new ArgumentOutOfRangeException(
252                             "year",
253                             String.Format(
254                                 CultureInfo.CurrentCulture,
255                                 Environment.GetResourceString("ArgumentOutOfRange_Range"),
256                                 1,
257                                 helper.MaxYear));
258             }
259             return (year);
260         }
261     }
262 }
263