1 // CalendarTest.cs
2 //
3 // (C) 2002 Ulrich Kunitz
4 //
5 
6 using System.Collections.Generic;
7 using NUnit.Framework;
8 using System;
9 using System.Globalization;
10 using System.IO;
11 
12 namespace MonoTests.System.Globalization
13 {
14 
15 sealed class Date {
16 	private int _day, _month, _year, _era;
17 
18 	public int Day {
19 		get {
20 			return _day;
21 		}
22 		set {
23 			if (value < 1 || value > 31)
24 				throw new ArgumentOutOfRangeException(
25 					"Day",
26 					"Day must be between 1 and 31.");
27 			_day = value;
28 		}
29 	}
30 
31 	public int Month {
32 		get {
33 			return _month;
34 		}
35 		set {
36 			if (value < 1 || value > 13)
37 				throw new ArgumentOutOfRangeException(
38 					"Month",
39 					"Month must be between 1 and 13.");
40 			_month = value;
41 		}
42 	}
43 
44 	public int Year {
45 		get {
46 			return _year;
47 		}
48 		set {
49 			_year = value;
50 		}
51 	}
52 
53 	public int Era {
54 		get {
55 			return _era;
56 		}
57 		set {
58 			if (value < 1 || value > 10)
59 				throw new ArgumentOutOfRangeException(
60 					"Era",
61 					"Era must be between 1 and 10.");
62 			_era = value;
63 		}
64 	}
65 
Date(int day, int month, int year, int era)66 	public Date(int day, int month, int year, int era) {
67 		Day = day;
68 		Month = month;
69 		Year = year;
70 		Era = era;
71 	}
Date(int day, int month, int year)72 	public Date(int day, int month, int year) : this(day,month,year,1) {}
Date()73 	public Date() : this(1,1,1,1) {}
74 
ToDateTime(Calendar cal)75 	public DateTime ToDateTime(Calendar cal) {
76 		return cal.ToDateTime(Year,Month,Day,0,0,0,0,Era);
77 	}
78 
FromDateTime(Calendar cal, DateTime time)79 	public void FromDateTime(Calendar cal, DateTime time) {
80 		Date dmy = new Date();
81 		dmy.Day = cal.GetDayOfMonth(time);
82 		dmy.Month = cal.GetMonth(time);
83 		dmy.Year = cal.GetYear(time);
84 		dmy.Era = cal.GetEra(time);
85 		Day = dmy.Day;
86 		Month = dmy.Month;
87 		Year = dmy.Year;
88 		Era = dmy.Era;
89 	}
90 
ToString()91 	public override string ToString() {
92 		StringWriter sw = new StringWriter();
93 		sw.Write("{0}.{1}.{2}", Day, Month, Year);
94 		if (Era != 1) {
95 			sw.Write(" era {0}", Era);
96 		}
97 		return sw.ToString();
98 	}
99 
Equals(Object b)100 	public override bool Equals(Object b) {
101 		if (b == null || GetType() != b.GetType())
102 			return false;
103 		return Equals(this, (Date)b);
104 	}
105 
Equals(Date a, Date b)106 	public static bool Equals(Date a, Date b) {
107 		if (a == b)
108 			return true;
109 		if (a.Year != b.Year)
110 			return false;
111 		if (a.Month != b.Month)
112 			return false;
113 		if (a.Day != b.Day)
114 			return false;
115 		if (a.Era != b.Era)
116 			return false;
117 		return true;
118 	}
119 
GetHashCode()120 	public override int GetHashCode() {
121 		return ToString().GetHashCode();
122 	}
123 } // class Date
124 
125 [TestFixture]
126 public class CalendarTest {
127 	private Calendar[] acal;
128 	private GregorianCalendar gcal;
129 	private JulianCalendar jucal;
130 	private HijriCalendar hical;
131 	private HebrewCalendar hecal;
132 	private JapaneseCalendar jacal;
133 	private TaiwanCalendar tacal;
134 	private KoreanCalendar kcal;
135 	private ThaiBuddhistCalendar tbcal;
136 	private ChineseLunisolarCalendar clcal;
137 	private TaiwanLunisolarCalendar tlcal;
138 	private JapaneseLunisolarCalendar jlcal;
139 	private KoreanLunisolarCalendar klcal;
140 
141 	[SetUp]
SetUp()142 	protected void SetUp() {
143 		gcal = new GregorianCalendar();
144 		jucal = new JulianCalendar();
145 		hical = new HijriCalendar();
146 		hecal = new HebrewCalendar();
147 		jacal = new JapaneseCalendar();
148 		tacal = new TaiwanCalendar();
149 		kcal = new KoreanCalendar();
150 		tbcal = new ThaiBuddhistCalendar();
151 		acal = new Calendar[] {
152 			gcal, jucal, hical, hecal, jacal,
153 			tacal, kcal, tbcal};
154 		clcal = new ChineseLunisolarCalendar ();
155 		tlcal = new TaiwanLunisolarCalendar ();
156 		jlcal = new JapaneseLunisolarCalendar ();
157 		klcal = new KoreanLunisolarCalendar ();
158 	}
159 
RowCheck(params Date[] adate)160 	private void RowCheck(params Date[] adate) {
161 		if (adate.Length != acal.Length)
162 			throw new ArgumentException(
163 				"Number of Date arguments doesn't match " +
164 				"length of calendar array.");
165 
166 		DateTime timeG = adate[0].ToDateTime(gcal);
167 		for (int i = 0; i < acal.Length; i++) {
168 			Date date = adate[i];
169 			if (date == null)
170 				continue;
171 			Calendar cal = acal[i];
172 
173 			DateTime time = date.ToDateTime(cal);
174 			StringWriter sw = new StringWriter();
175 			sw.Write("Calendar {0} computes wrong DateTime.",
176 				cal);
177 			Assert.AreEqual(timeG, time, sw.ToString());
178 
179 			sw = new StringWriter();
180 			Date ndate = new Date();
181 			ndate.FromDateTime(cal, time);
182 			sw.Write("Calendar {0} computes wrong date", cal);
183 			Assert.AreEqual(date, ndate, sw.ToString());
184 		}
185 	}
186 
187 	// We are testing the implementation against the reference dates in
188 	// Calendrical Calcualation. Please note that the CLR uses another
189 	// epoch for the HijriCalendar, which might be the perfect thing
190 	// to do.
191 	[Test]
TestCCTable()192 	public void TestCCTable() {
193 		// Gr Ju Hi He Ja Ta Ko TB
194 		RowCheck(new Date(24,9,70,1),
195 			new Date(26,9,70,1),
196 			null,
197 			null,
198 			null,
199 			null,
200 			new Date(24,9,2403,1),
201 			new Date(24,9,613,1));
202 		RowCheck(new Date(2,10,135,1),
203 			new Date(3,10,135,1),
204 			null,
205 			null,
206 			null,
207 			null,
208 			new Date(2,10,2468,1),
209 			new Date(2,10,678,1));
210 		RowCheck(new Date(8,1,470,1),
211 			new Date(7,1,470,1),
212 			null,
213 			null,
214 			null,
215 			null,
216 			new Date(8,1,2803,1),
217 			new Date(8,1,1013,1));
218 		RowCheck(new Date(20,5,576,1),
219 			new Date(18,5,576,1),
220 			null,
221 			null,
222 			null,
223 			null,
224 			new Date(20,5,2909,1),
225 			new Date(20,5,1119,1));
226 		RowCheck(new Date(10,11,694,1),
227 			new Date(7,11,694,1),
228 			new Date(14,7,75,1),
229 			null,
230 			null,
231 			null,
232 			new Date(10,11,3027,1),
233 			new Date(10,11,1237,1));
234 		RowCheck(new Date(25,4,1013,1),
235 			new Date(19,4,1013,1),
236 			new Date(6,10,403,1),
237 			null,
238 			null,
239 			null,
240 			new Date(25,4,3346,1),
241 			new Date(25,4,1556,1));
242 		RowCheck(new Date(24,5,1096,1),
243 			new Date(18,5,1096,1),
244 			new Date(23,5,489,1),
245 			null,
246 			null,
247 			null,
248 			new Date(24,5,3429,1),
249 			new Date(24,5,1639,1));
250 		RowCheck(new Date(23,3,1190,1),
251 			new Date(16,3,1190,1),
252 			new Date(8,2,586,1),
253 			null,
254 			null,
255 			null,
256 			new Date(23,3,3523,1),
257 			new Date(23,3,1733,1));
258 		RowCheck(new Date(10,3,1240,1),
259 			new Date(3,3,1240,1),
260 			new Date(8,8,637,1),
261 			null,
262 			null,
263 			null,
264 			new Date(10,3,3573,1),
265 			new Date(10,3,1783,1));
266 		RowCheck(new Date(2,4,1288,1),
267 			new Date(26,3,1288,1),
268 			new Date(21,2,687,1),
269 			null,
270 			null,
271 			null,
272 			new Date(2,4,3621,1),
273 			new Date(2,4,1831,1));
274 		RowCheck(new Date(27,4,1298,1),
275 			new Date(20,4,1298,1),
276 			new Date(8,7,697,1),
277 			null,
278 			null,
279 			null,
280 			new Date(27,4,3631,1),
281 			new Date(27,4,1841,1));
282 		RowCheck(new Date(12,6,1391,1),
283 			new Date(4,6,1391,1),
284 			new Date(2,7,793,1),
285 			null,
286 			null,
287 			null,
288 			new Date(12,6,3724,1),
289 			new Date(12,6,1934,1));
290 		RowCheck(new Date(3,2,1436,1),
291 			new Date(25,1,1436,1),
292 			new Date(7,7,839,1),
293 			null,
294 			null,
295 			null,
296 			new Date(3,2,3769,1),
297 			new Date(3,2,1979,1));
298 		RowCheck(new Date(9,4,1492,1),
299 			new Date(31,3,1492,1),
300 			new Date(2,6,897,1),
301 			null,
302 			null,
303 			null,
304 			new Date(9,4,3825,1),
305 			new Date(9,4,2035,1));
306 		RowCheck(new Date(19,9,1553,1),
307 			new Date(9,9,1553,1),
308 			new Date(1,10,960,1),
309 			null,
310 			null,
311 			null,
312 			new Date(19,9,3886,1),
313 			new Date(19,9,2096,1));
314 		RowCheck(new Date(5,3,1560,1),
315 			new Date(24,2,1560,1),
316 			new Date(28,5,967,1),
317 			null,
318 			null,
319 			null,
320 			new Date(5,3,3893,1),
321 			new Date(5,3,2103,1));
322 		RowCheck(new Date(10,6,1648,1),
323 			new Date(31,5,1648,1),
324 			new Date(19,5,1058,1),
325 			new Date(20,9,5408,1),
326 			null,
327 			null,
328 			new Date(10,6,3981,1),
329 			new Date(10,6,2191,1));
330 		RowCheck(new Date(30,6,1680,1),
331 			new Date(20,6,1680,1),
332 			new Date(3,6,1091,1),
333 			new Date(3,11,5440,1),
334 			null,
335 			null,
336 			new Date(30,6,4013,1),
337 			new Date(30,6,2223,1));
338 		RowCheck(new Date(24,7,1716,1),
339 			new Date(13,7,1716,1),
340 			new Date(5,8,1128,1),
341 			new Date(5,11,5476,1),
342 			null,
343 			null,
344 			new Date(24,7,4049,1),
345 			new Date(24,7,2259,1));
346 		RowCheck(new Date(19,6,1768,1),
347 			new Date(8,6,1768,1),
348 			new Date(4,2,1182,1),
349 			new Date(4,10,5528,1),
350 			null,
351 			null,
352 			new Date(19,6,4101,1),
353 			new Date(19,6,2311,1));
354 		RowCheck(new Date(2,8,1819,1),
355 			new Date(21,7,1819,1),
356 			new Date(11,10,1234,1),
357 			new Date(11,11,5579,1),
358 			null,
359 			null,
360 			new Date(2,8,4152,1),
361 			new Date(2,8,2362,1));
362 		RowCheck(new Date(27,3,1839,1),
363 			new Date(15,3,1839,1),
364 			new Date(12,1,1255,1),
365 			new Date(12,7,5599,1),
366 			null,
367 			null,
368 			new Date(27,3,4172,1),
369 			new Date(27,3,2382,1));
370 		RowCheck(new Date(19,4,1903,1),
371 			new Date(6,4,1903,1),
372 			new Date(22,1,1321,1),
373 			new Date(22,7,5663,1),
374 			new Date(19,4,36,1),
375 			null,
376 			new Date(19,4,4236,1),
377 			new Date(19,4,2446,1));
378 		RowCheck(new Date(25,8,1929,1),
379 			new Date(12,8,1929,1),
380 			new Date(20,3,1348,1),
381 			new Date(19,12,5689,1),
382 			new Date(25,8,4,3),
383 			new Date(25,8,18,1),
384 			new Date(25,8,4262,1),
385 			new Date(25,8,2472,1));
386 		RowCheck(new Date(29,9,1941,1),
387 			new Date(16,9,1941,1),
388 			new Date(9,9,1360,1),
389 			new Date(8,1,5702,1),
390 			new Date(29,9,16,3),
391 			new Date(29,9,30,1),
392 			new Date(29,9,4274,1),
393 			new Date(29,9,2484,1));
394 		RowCheck(new Date(19,4,1943,1),
395 			new Date(6,4,1943,1),
396 			new Date(14,4,1362,1),
397 			new Date(14,8,5703,1),
398 			new Date(19,4,18,3),
399 			new Date(19,4,32,1),
400 			new Date(19,4,4276,1),
401 			new Date(19,4,2486,1));
402 		RowCheck(new Date(7,10,1943,1),
403 			new Date(24,9,1943,1),
404 			new Date(8,10,1362,1),
405 			new Date(8,1,5704,1),
406 			new Date(7,10,18,3),
407 			new Date(7,10,32,1),
408 			new Date(7,10,4276,1),
409 			new Date(7,10,2486,1));
410 		RowCheck(new Date(17,3,1992,1),
411 			new Date(4,3,1992,1),
412 			new Date(14,9,1412,1),
413 			new Date(12,7,5752,1),
414 			new Date(17,3,4,4),
415 			new Date(17,3,81,1),
416 			new Date(17,3,4325,1),
417 			new Date(17,3,2535,1));
418 		RowCheck(new Date(25,5,1996,1),
419 			new Date(12,5,1996,1),
420 			new Date(8,1,1417,1),
421 			new Date(7,9,5756,1),
422 			new Date(25,5,8,4),
423 			new Date(25,5,85,1),
424 			new Date(25,5,4329,1),
425 			new Date(25,5,2539,1));
426 		RowCheck(new Date(10,11,2038,1),
427 			new Date(28,10,2038,1),
428 			new Date(13,10,1460,1),
429 			new Date(12,2,5799,1),
430 			new Date(10,11,50,4),
431 			new Date(10,11,127,1),
432 			new Date(10,11,4371,1),
433 			new Date(10,11,2581,1));
434 		RowCheck(new Date(18,7,2094,1),
435 			new Date(5,7,2094,1),
436 			new Date(6,3,1518,1),
437 			new Date(5,11,5854,1),
438 			new Date(18,7,106,4),
439 			new Date(18,7,183,1),
440 			new Date(18,7,4427,1),
441 			new Date(18,7,2637,1));
442 	}
443 
444 	[Test]
TestCalendarType()445 	public void TestCalendarType() {
446 		GregorianCalendar gc = new GregorianCalendar(
447 			GregorianCalendarTypes.Arabic);
448 		Assert.AreEqual(GregorianCalendarTypes.Arabic,
449 						gc.CalendarType,
450 						"A01 Gregorian ctor with GregorianCalendarTypes parameter");
451 		gc.CalendarType = GregorianCalendarTypes.MiddleEastFrench;
452 		Assert.AreEqual(GregorianCalendarTypes.MiddleEastFrench,
453 					 gc.CalendarType,
454 					 "A02 GregorianCalendar.CalendarType");
455 
456 	}
457 
458 	[Test]
TestStandardEras()459 	public void TestStandardEras() {
460 		Assert.AreEqual(1, GregorianCalendar.ADEra, "B01 ADEra");
461 		Assert.AreEqual(1, HebrewCalendar.HebrewEra, "B02 HebrewEra");
462 		Assert.AreEqual(1, HijriCalendar.HijriEra, "B03 HjriEra");
463 		Assert.AreEqual(1, JulianCalendar.JulianEra, "B04 JulianEra");
464 		Assert.AreEqual(1, KoreanCalendar.KoreanEra, "B05 KoreanEra");
465 		Assert.AreEqual(1, ThaiBuddhistCalendar.ThaiBuddhistEra, "B06 ThaiBuddhistEra");
466 
467 		Assert.AreEqual(1, ChineseLunisolarCalendar.ChineseEra, "CNLunisor");
468 		Assert.AreEqual(1, JapaneseLunisolarCalendar.JapaneseEra, "JPLunisor");
469 		Assert.AreEqual(1, KoreanLunisolarCalendar.GregorianEra, "KRLunisor");
470 	}
471 
472 	[Test]
TestCurrentEra()473 	public void TestCurrentEra() {
474 		Assert.AreEqual(0, GregorianCalendar.CurrentEra,
475 					 "C01 GregorianCalendar.CurrentEra");
476 		Assert.AreEqual(0, HebrewCalendar.CurrentEra,
477 					 "C02 HebrewCalendar.CurrentEra");
478 		Assert.AreEqual(0, HijriCalendar.CurrentEra,
479 					 "C03 HijriCalendar.CurrentEra");
480 		Assert.AreEqual(0, JapaneseCalendar.CurrentEra,
481 					 "C04 JapaneseCalendar.CurrentEra");
482 		Assert.AreEqual(0, JulianCalendar.CurrentEra,
483 					 "C05 JulianCalendar.CurrentEra");
484 		Assert.AreEqual(0, KoreanCalendar.CurrentEra,
485 					 "C06 KoreanCalendar.CurrentEra");
486 		Assert.AreEqual(0, TaiwanCalendar.CurrentEra,
487 					 "C07 TaiwanCalendar.CurrentEra");
488 		Assert.AreEqual(0, ThaiBuddhistCalendar.CurrentEra,
489 					 "C08 ThaiBuddhistCalendar.CurrentEra");
490 	}
491 
492 	[Test]
TestErasProperty()493 	public void TestErasProperty() {
494 		foreach (Calendar cal in acal) {
495 			int check = 1;
496 			if (cal is JapaneseCalendar)
497 				check = 4;
498 			Assert.AreEqual(check, cal.Eras.Length,
499 						 String.Format("D01 {0}.Eras.Length", cal));
500 			cal.Eras[0] = 29;
501 			Assert.IsTrue(cal.Eras[0] != 29, String.Format("D02 {0}.Eras readonly", cal));
502 		}
503 	}
504 
505 	[Test]
TestErasProperty2()506 	public void TestErasProperty2() {
507 		Assert.AreEqual(1, clcal.Eras.Length, "cn");
508 		Assert.AreEqual(1, tlcal.Eras.Length, "tw");
509 		Assert.AreEqual(2, jlcal.Eras.Length, "jp");
510 		Assert.AreEqual(1, klcal.Eras.Length, "kr");
511 
512 		Assert.AreEqual(4, jlcal.Eras [0], "jp.1");
513 		Assert.AreEqual(3, jlcal.Eras [1], "jp.2");
514 	}
515 
516 	[Test]
TestTwoDigitYearMax()517 	public void TestTwoDigitYearMax() {
518 		Assert.AreEqual(2029, gcal.TwoDigitYearMax,
519 					 "E01 TwoDigitYearMax GregorianCalendar");
520 		Assert.AreEqual(5790, hecal.TwoDigitYearMax,
521 					 "E02 TwoDigitYearMax HebrewCalendar");
522 		Assert.AreEqual(1451, hical.TwoDigitYearMax,
523 					 "E03 TwoDigitYearMax HijriCalendar");
524 		Assert.AreEqual(99, jacal.TwoDigitYearMax,
525 					 "E04 TwoDigitYearMax JapaneseCalendar");
526 		Assert.AreEqual(2029, jucal.TwoDigitYearMax,
527 					 "E05 TwoDigitYearMax JulianCalendar");
528 		Assert.AreEqual(4362, kcal.TwoDigitYearMax,
529 					 "E06 TwoDigitYearMax KoreanCalendar");
530 		Assert.AreEqual(99, tacal.TwoDigitYearMax,
531 					 "E07 TwoDigitYearMax TaiwanCalendar");
532 		Assert.AreEqual(2572, tbcal.TwoDigitYearMax,
533 					 "E08 TwoDigitYearMax ThaiBuddhistCalendar");
534 		foreach (Calendar cal in acal) {
535 			bool exception = false;
536 			try {
537 				cal.TwoDigitYearMax = 99;
538 			}
539 			catch (ArgumentOutOfRangeException) {
540 				exception = true;
541 			}
542 
543 			Assert.IsFalse(exception,
544 				   String.Format("E09 {0}.TwoDigitYearMax 99 " +
545 								 " out of range exception", cal));
546 
547 			exception = false;
548 			int m = 10000;
549 			try {
550 				m = cal.GetYear(DateTime.MaxValue)+1;
551 				cal.TwoDigitYearMax = m;
552 			}
553 			catch (ArgumentException) {
554 				exception = true;
555 			}
556 			Assert.IsTrue(exception,
557 				   String.Format("E10 {0}.TwoDigitYearMax out " +
558 								 " of range exception value {1}",
559 								 cal, m));
560 		}
561 	}
562 
563 	[Test] // wrt bug #76252.
HebrewCalendarGetDaysInMonth()564 	public void HebrewCalendarGetDaysInMonth ()
565 	{
566 		HebrewCalendar c = new HebrewCalendar ();
567 		int year = c.GetYear (new DateTime (2005, 9, 1));
568 		Assert.AreEqual (5765, year);
569 		int days = c.GetDaysInMonth (year, 13, 1);
570 		Assert.AreEqual (29, days);
571 	}
572 
573 	[Test] // bug #81783
GregorianAddMonth()574 	public void GregorianAddMonth ()
575 	{
576 		GregorianCalendar c = new GregorianCalendar ();
577 		DateTime d = new DateTime (2007, 5, 31);
578 		DateTime prev = c.AddMonths (d, -1);
579 		Assert.AreEqual (4, prev.Month, "prev");
580 		DateTime next = c.AddMonths (d, 1);
581 		Assert.AreEqual (6, next.Month, "next");
582 
583 		d = new DateTime (2003, 12, 5);
584 		prev = c.AddMonths (d, -13);
585 		Assert.AreEqual (new DateTime (2002, 11, 5), prev, "prev2");
586 		next = c.AddMonths (d, 6);
587 		Assert.AreEqual (new DateTime (2004, 6, 5), next, "next2");
588 	}
589 
590 	[Test]
AddYearOnLeapYear()591 	public void AddYearOnLeapYear ()
592 	{
593 		GregorianCalendar c = new GregorianCalendar ();
594 		DateTime d = new DateTime (2004, 2, 29);
595 		DateTime prev = c.AddYears (d, -1);
596 		Assert.AreEqual (2, prev.Month, "prev");
597 		DateTime next = c.AddYears (d, 1);
598 		Assert.AreEqual (2, next.Month, "next");
599 	}
600 
601 	[Test]
GetLeapMonth()602 	public void GetLeapMonth ()
603 	{
604 		GregorianCalendar gc = new GregorianCalendar ();
605 		Assert.AreEqual (0, gc.GetLeapMonth (2007), "#1-1");
606 		Assert.AreEqual (0, gc.GetLeapMonth (2008), "#1-2");
607 		Assert.AreEqual (0, gc.GetLeapMonth (2100), "#1-3");
608 		Assert.AreEqual (0, gc.GetLeapMonth (2000), "#1-4");
609 
610 		JulianCalendar jc = new JulianCalendar ();
611 		Assert.AreEqual (0, jc.GetLeapMonth (2007), "#2-1");
612 		Assert.AreEqual (0, jc.GetLeapMonth (2008), "#2-2");
613 		Assert.AreEqual (0, jc.GetLeapMonth (2100), "#2-3");
614 		Assert.AreEqual (0, jc.GetLeapMonth (2000), "#2-4");
615 		Assert.AreEqual (0, jc.GetLeapMonth (2009), "#2-5");
616 		Assert.AreEqual (0, jc.GetLeapMonth (2010), "#2-6");
617 
618 		HebrewCalendar hc = new HebrewCalendar ();
619 		// 3rd, 6th, 8th, 11th 14th and 17th year in every 19 are leap.
620 		// 5339 % 19 = 0.
621 		Assert.AreEqual (0, hc.GetLeapMonth (5343), "#3-1");
622 		Assert.AreEqual (0, hc.GetLeapMonth (5344), "#3-2");
623 		Assert.AreEqual (7, hc.GetLeapMonth (5345), "#3-3");
624 		Assert.AreEqual (0, hc.GetLeapMonth (5346), "#3-4");
625 		Assert.AreEqual (7, hc.GetLeapMonth (5347), "#3-5");
626 		Assert.AreEqual (0, hc.GetLeapMonth (5348), "#3-6");
627 		Assert.AreEqual (0, hc.GetLeapMonth (5349), "#3-7");
628 
629 		ThaiBuddhistCalendar tc = new ThaiBuddhistCalendar ();
630 		Assert.AreEqual (0, tc.GetLeapMonth (2520), "#4-1");
631 		Assert.AreEqual (0, tc.GetLeapMonth (2521), "#4-2");
632 		Assert.AreEqual (0, tc.GetLeapMonth (2522), "#4-3");
633 		Assert.AreEqual (0, tc.GetLeapMonth (2523), "#4-4");
634 
635 		ChineseLunisolarCalendar cc = new ChineseLunisolarCalendar ();
636 		Assert.AreEqual (0, cc.GetLeapMonth (2000), "#5-1");
637 		Assert.AreEqual (5, cc.GetLeapMonth (2001), "#5-2");
638 		Assert.AreEqual (0, cc.GetLeapMonth (2002), "#5-3");
639 		Assert.AreEqual (0, cc.GetLeapMonth (2003), "#5-4");
640 		Assert.AreEqual (3, cc.GetLeapMonth (2004), "#5-5");
641 		Assert.AreEqual (0, cc.GetLeapMonth (2005), "#5-6");
642 		Assert.AreEqual (8, cc.GetLeapMonth (2006), "#5-7");
643 		Assert.AreEqual (0, cc.GetLeapMonth (2007), "#5-8");
644 		Assert.AreEqual (0, cc.GetLeapMonth (2008), "#5-9");
645 		Assert.AreEqual (6, cc.GetLeapMonth (2009), "#5-10");
646 		Assert.AreEqual (0, cc.GetLeapMonth (2010), "#5-11");
647 		Assert.AreEqual (0, cc.GetLeapMonth (2011), "#5-12");
648 		Assert.AreEqual (5, cc.GetLeapMonth (2012), "#5-13");
649 		Assert.AreEqual (0, cc.GetLeapMonth (2013), "#5-14");
650 		Assert.AreEqual (10, cc.GetLeapMonth (2014), "#5-15");
651 		Assert.AreEqual (0, cc.GetLeapMonth (2015), "#5-16");
652 		Assert.AreEqual (0, cc.GetLeapMonth (2016), "#5-17");
653 		Assert.AreEqual (7, cc.GetLeapMonth (2017), "#5-18");
654 		Assert.AreEqual (0, cc.GetLeapMonth (2018), "#5-19");
655 		Assert.AreEqual (0, cc.GetLeapMonth (2019), "#5-20");
656 
657 		KoreanLunisolarCalendar kc = new KoreanLunisolarCalendar ();
658 		Assert.AreEqual (0, kc.GetLeapMonth (2000), "#6-1");
659 		Assert.AreEqual (5, kc.GetLeapMonth (2001), "#6-2");
660 		Assert.AreEqual (0, kc.GetLeapMonth (2002), "#6-3");
661 		Assert.AreEqual (0, kc.GetLeapMonth (2003), "#6-4");
662 		Assert.AreEqual (3, kc.GetLeapMonth (2004), "#6-5");
663 		Assert.AreEqual (0, kc.GetLeapMonth (2005), "#6-6");
664 		Assert.AreEqual (8, kc.GetLeapMonth (2006), "#6-7");
665 		Assert.AreEqual (0, kc.GetLeapMonth (2007), "#6-8");
666 		Assert.AreEqual (0, kc.GetLeapMonth (2008), "#6-9");
667 		Assert.AreEqual (6, kc.GetLeapMonth (2009), "#6-10");
668 		Assert.AreEqual (0, kc.GetLeapMonth (2010), "#6-11");
669 		Assert.AreEqual (0, kc.GetLeapMonth (2011), "#6-12");
670 		Assert.AreEqual (4, kc.GetLeapMonth (2012)); // off from cn by 1, "#6-13");
671 		Assert.AreEqual (0, kc.GetLeapMonth (2013), "#6-14");
672 		Assert.AreEqual (10, kc.GetLeapMonth (2014), "#6-15");
673 		Assert.AreEqual (0, kc.GetLeapMonth (2015), "#6-16");
674 		Assert.AreEqual (0, kc.GetLeapMonth (2016), "#6-17");
675 		Assert.AreEqual (6, kc.GetLeapMonth (2017)); // off from cn by 1, "#6-18");
676 		Assert.AreEqual (0, kc.GetLeapMonth (2018), "#6-19");
677 		Assert.AreEqual (0, kc.GetLeapMonth (2019), "#6-20");
678 	}
679 
680 	[Test]
GetWeekOfYear()681 	public void GetWeekOfYear ()
682 	{
683 		GregorianCalendar gc = new GregorianCalendar ();
684 		Assert.AreEqual (1, gc.GetWeekOfYear (new DateTime (2007, 1, 1), CalendarWeekRule.FirstDay, DayOfWeek.Sunday), "#1");
685 		//Assert.AreEqual (1, gc.GetWeekOfYear (new DateTime (2000, 1, 1), CalendarWeekRule.FirstDay, DayOfWeek.Sunday), "#2");
686 		Assert.AreEqual (3, gc.GetWeekOfYear (new DateTime (2000, 1, 10), CalendarWeekRule.FirstDay, DayOfWeek.Sunday), "#2");
687 		Assert.AreEqual (2, gc.GetWeekOfYear (new DateTime (2000, 1, 10), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday), "#3");
688 		Assert.AreEqual (2, gc.GetWeekOfYear (new DateTime (2000, 1, 10), CalendarWeekRule.FirstFullWeek, DayOfWeek.Sunday), "#4");
689 		Assert.AreEqual (52, gc.GetWeekOfYear (new DateTime (2000, 1, 1), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday), "#5");
690 		Assert.AreEqual (52, gc.GetWeekOfYear (new DateTime (2000, 1, 1), CalendarWeekRule.FirstFullWeek, DayOfWeek.Sunday), "#6");
691 	}
692 
693 	[Test]
TestToFourDigitYear()694 	public void TestToFourDigitYear() {
695 		foreach (Calendar cal in acal) {
696 			bool working = true;
697 			int mod = 2000;
698 			if (cal is HebrewCalendar)
699 				mod = 5500;
700 			if (cal is KoreanCalendar)
701 				mod = 3000;
702 			if (cal is JapaneseCalendar)
703 				working = false;
704 			if (cal is TaiwanCalendar)
705 				working = false;
706 			cal.TwoDigitYearMax = mod + 229;
707 			Assert.AreEqual(mod+229 , cal.TwoDigitYearMax,
708 						 String.Format("F01 {0}.TwoDigitYearMax", cal));
709 			Assert.AreEqual(working ? mod+229 : 29,
710 						 cal.ToFourDigitYear(29),
711 						 String.Format("F02 {0}.ToFourDigitYear(29)",cal));
712 			Assert.AreEqual(
713 				working ? mod+130 : 30,
714 				cal.ToFourDigitYear(30),
715 				String.Format("F03 {0}.ToFourDigitYear(30)",
716 							  cal));
717 			Assert.AreEqual(mod, cal.ToFourDigitYear(mod),
718 				String.Format("F04 {0}.ToFourDigitYear({1})",
719 							  cal, mod));
720 
721 			bool exception = false;
722 			try {
723 				cal.ToFourDigitYear(-1);
724 			}
725 			catch (ArgumentOutOfRangeException) {
726 				exception = true;
727 			}
728 			Assert.IsTrue(exception, String.Format(
729 				"F05 {0}.ToFourDigitYear(-1) exception",
730 				cal));
731 			exception = false;
732 			try {
733 				cal.ToFourDigitYear(15000);
734 			}
735 			catch (ArgumentOutOfRangeException) {
736 				exception = true;
737 			}
738 			Assert.IsTrue(exception, String.Format(
739 				"F05 {0}.ToFourDigitYear(15000) exception",
740 				cal));
741 		}
742 	}
743 
744 	[Test]
TestToFourDigitYear2()745 	public void TestToFourDigitYear2 ()
746 	{
747 		GregorianCalendar gc = new GregorianCalendar ();
748 		Assert.AreEqual (2029, gc.ToFourDigitYear (29), "#1-1");
749 		Assert.AreEqual (1930, gc.ToFourDigitYear (30), "#1-2");
750 		Assert.AreEqual (2029, gc.ToFourDigitYear (2029), "#1-3");
751 		Assert.AreEqual (2030, gc.ToFourDigitYear (2030), "#1-4");
752 
753 		HebrewCalendar hbc = new HebrewCalendar ();
754 		Assert.AreEqual (5790, hbc.ToFourDigitYear (90), "#2-1");
755 		Assert.AreEqual (5691, hbc.ToFourDigitYear (91), "#2-2");
756 		Assert.AreEqual (5790, hbc.ToFourDigitYear (5790), "#2-3");
757 		Assert.AreEqual (5691, hbc.ToFourDigitYear (5691), "#2-4");
758 		Assert.AreEqual (5999, hbc.ToFourDigitYear (5999), "#2-5");
759 		// LAMESPEC: .NET fails to throw an exception unlike documented
760 		/*
761 		try {
762 			hbc.ToFourDigitYear (6000);
763 			Assert.Fail ("#2-6");
764 		} catch (ArgumentOutOfRangeException) {
765 		}
766 		*/
767 
768 		ThaiBuddhistCalendar tc = new ThaiBuddhistCalendar ();
769 		Assert.AreEqual (2572, tc.ToFourDigitYear (72), "#3-1");
770 		Assert.AreEqual (2473, tc.ToFourDigitYear (73), "#3-2");
771 		Assert.AreEqual (2572, tc.ToFourDigitYear (2572), "#3-3");
772 		Assert.AreEqual (2573, tc.ToFourDigitYear (2573), "#3-4");
773 		Assert.AreEqual (9999, tc.ToFourDigitYear (9999), "#3-5");
774 		// LAMESPEC: .NET fails to throw an exception unlike documented
775 		/*
776 		try {
777 			tc.ToFourDigitYear (10000);
778 			Assert.Fail ("#3-6");
779 		} catch (ArgumentOutOfRangeException) {
780 		}
781 		*/
782 
783 		KoreanCalendar kc = new KoreanCalendar ();
784 		Assert.AreEqual (4362, kc.ToFourDigitYear (62), "#4-1");
785 		Assert.AreEqual (4263, kc.ToFourDigitYear (63), "#4-2");
786 		Assert.AreEqual (4362, kc.ToFourDigitYear (4362), "#4-3");
787 		Assert.AreEqual (4363, kc.ToFourDigitYear (4363), "#4-4");
788 	}
789 
TestDaysInYear(Calendar calendar, int year)790 	public void TestDaysInYear (Calendar calendar, int year)
791 	{
792 		var daysInYear = calendar.GetDaysInYear (year);
793 		var daysInMonths = 0;
794 		var monthInYear = calendar.GetMonthsInYear (year);
795 		for (var m = 1; m <= monthInYear; m++)
796 			daysInMonths += calendar.GetDaysInMonth (year, m);
797 
798 		Assert.AreEqual (daysInYear, daysInMonths, string.Format("Calendar:{0} Year:{1}",calendar.GetType(), year));
799 	}
800 
801 	[Test]
DaysInYear()802 	public void DaysInYear ()
803 	{
804 		var calendars = new List<Calendar> (acal) {
805 			new UmAlQuraCalendar ()
806 		};
807 
808 		foreach (var calendar in calendars) {
809 			var minYear = calendar.GetYear (calendar.MinSupportedDateTime);
810 			var maxYear = calendar.GetYear (calendar.MaxSupportedDateTime) - 1 ;
811 			var midYear = calendar.GetYear (DateTime.Now);
812 			var yearsTested = Math.Min (1000, (maxYear - minYear) / 2);
813 
814 			midYear -= yearsTested / 2;
815 
816 			int y1 = minYear, y2 = maxYear, y3 = midYear;
817 			for (var i = 0; i < yearsTested; i++) {
818 				TestDaysInYear (calendar, y1);
819 				TestDaysInYear (calendar, y2);
820 				if (y3 > minYear && y3 < maxYear)
821 					TestDaysInYear (calendar, y3);
822 
823 				y1++; y2--; y3++;
824 			}
825 		}
826 	}
827 
828 	// TODO: more tests :-)
829 } // class CalendarTest
830 
831 } // namespace MonoTests.System.Globalization
832