Click here to Skip to main content
15,881,281 members
Articles / Programming Languages / C#

A TimeZone Aware DateTime Implementation

Rate me:
Please Sign up or sign in to vote.
3.56/5 (10 votes)
24 Feb 2010CPOL6 min read 70K   466   37  
An implementation that wraps DateTime to allow for keeping track of TimeZone state
using System;
using System.Globalization;
using System.Threading;
using NUnit.Framework;
using DateTimeZone;

namespace TestDateTimeZone
{
    /// <summary>
    /// Class summary...
    /// </summary>	
    [TestFixture]
    public class LocalDateTimeTest
    {
        LocalDateTime _01_NOV_07__1600_ = new LocalDateTime(2007, 11, 1, 16, 0, 0);

        /// <summary>
        /// A test sample method.
        /// </summary>
        [Test]
        public void TestIdentifyingLocalTimeZone()
        {
            LocalDateTime ldt = new LocalDateTime();
            Assert.IsNotNull(ldt);
        }

        /// <summary>
        /// A test sample method.
        /// </summary>
        [Test]
        public void TestConvertingLocalTimeZoneToAnotherTimeZone()
        {
            // Date time values captured from 15:55 to 16:10 from this web site:
            // http://twiki.org/cgi-bin/xtra/tzdatepick.htlm

            LocalDateTime ldt = new LocalDateTime();
            Assert.IsNotNull(ldt);
        }

        [Test]
        public void TestConvertLocalDateTimeToCanberraLDT()
        {
            // Timezone: Australia/Canberra Date&time: Fri, 02 Nov 2007 02:08:25 +1100 (EST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Australia__Sydney);
            Assert.AreEqual(2, ldt.GetDateTime().Hour);
            Assert.AreEqual(2, ldt.GetDateTime().Day);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToBrisbaneLDT()
        {
            /*
            Location							Local time									Time zone
            Oslo (Norway)						torsdag 1. november 2007 kl. 16:00:00		UTC+1 hour CET
            Brisbane (Australia - Queensland)	fredag 2. november 2007 kl. 01:00:00		UTC+10 hours EST
            Corresponding UTC (GMT)				torsdag 1. november 2007 kl. 15:00:00
            */
            // Timezone: Australia/Brisbane Date&time: Fri, 02 Nov 2007 01:08:05 +1000 (EST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Australia__Brisbane);
            Assert.AreEqual(1, ldt.GetDateTime().Hour);
            Assert.AreEqual(2, ldt.GetDateTime().Day);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToAdelaideLDT()
        {
            // Timezone: Australia/Adelaide Date&time: Fri, 02 Nov 2007 01:37:44 +1030 (CST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Australia__Adelaide);
            Assert.AreEqual(1, ldt.GetDateTime().Hour);
            Assert.AreEqual(30, ldt.GetDateTime().Minute);
            Assert.AreEqual(2, ldt.GetDateTime().Day);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToPerthLDT()
        {
            // Timezone: Australia/Perth Date&time: Thu, 01 Nov 2007 23:09:25 +0800 (WST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Australia__Perth);
            Assert.AreEqual(23, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToVladivostokLDT()
        {
            // Timezone: Asia/Vladivostok Date&time: Fri, 02 Nov 2007 01:06:16 +1000 (VLAT)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Asia__Vladivostok);
            Assert.AreEqual(1, ldt.GetDateTime().Hour);
            Assert.AreEqual(2, ldt.GetDateTime().Day);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToTokyoLDT()
        {
            // Timezone: Asia/Tokyo Date&time: Fri, 02 Nov 2007 00:06:48 +0900 (JST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Asia__Tokyo);
            Assert.AreEqual(00, ldt.GetDateTime().Hour);
            Assert.AreEqual(2, ldt.GetDateTime().Day);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToSingaporeLDT()
        {
            // Timezone: Asia/Singapore Date&time: Thu, 01 Nov 2007 23:07:17 +0800 (SGT)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Asia__Singapore);
            Assert.AreEqual(23, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToBangkokLDT()
        {
            // Timezone: Asia/Bangkok Date&time: Thu, 01 Nov 2007 22:03:58 +0700 (ICT)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Asia__Bangkok);
            Assert.AreEqual(22, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToGMT()
        {
            // Timezone: Europe/Dublin Date&time: Thu, 01 Nov 2007 15:10:11 +0000 (GMT)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Europe__Dublin);
            Assert.AreEqual(15, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToDamascusLDT()
        {
            //Timezone: Asia/Damascus Date&time: Thu, 01 Nov 2007 17:04:52 +0200 (EET)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Asia__Damascus);
            Assert.AreEqual(17, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToTahitiLDT()
        {
            //Timezone: Pacific/Tahiti Date&time: Thu, 01 Nov 2007 05:10:49 -1000 (TAHT)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Pacific__Tahiti);
            Assert.AreEqual(5, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToLos_AngelesLDT()
        {
            /*
            Location							Local time								Time zone
            Oslo (Norway)						torsdag 1. november 2007 kl. 16:00:00	UTC+1 hour CET
            Los Angeles (U.S.A. - California)	torsdag 1. november 2007 kl. 08:00:00	UTC-7 hours PDT
            Corresponding UTC (GMT)				torsdag 1. november 2007 kl. 15:00:00
            */
            //Timezone: America/Los_Angeles Date&time: Thu, 01 Nov 2007 08:00:53 -0700 (PDT)
            // Normally -8 so it is DST in LA.
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.America__Los_Angeles);
            Assert.AreEqual(8, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToWinnipegLDT()
        {
            //Timezone: America/Winnipeg Date&time: Thu, 01 Nov 2007 09:02:13 -0600 (CST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.America__Winnipeg);
            Assert.AreEqual(9, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToJamaicaLDT()
        {
            // Timezone: America/Jamaica Date&time: Thu, 01 Nov 2007 10:01:28 -0500 (EST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.America__Jamaica);
            Assert.AreEqual(10, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToIndiana_KnoxLDT()
        {
            // Timezone: America/Indiana/Knox Date&time: Thu, 01 Nov 2007 10:59:58 -0400 (EDT)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.America__Indiana__Knox);
            Assert.AreEqual(11, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToBuenos_AiresLDT()
        {
            // Timezone: America/Buenos_Aires Date&time: Thu, 01 Nov 2007 11:58:29 -0300 (ART)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.America__Argentina__Buenos_Aires);
            Assert.AreEqual(12, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToTunisLDT()
        {
            // Timezone: Africa/Tunis Date&time: Thu, 01 Nov 2007 15:58:03 +0100 (CET)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Africa__Tunis);
            Assert.AreEqual(16, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToJohannesburgLDT()
        {
            // Timezone: Africa/Johannesburg Date&time: Thu, 01 Nov 2007 16:57:05 +0200 (SAST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Africa__Johannesburg);
            Assert.AreEqual(17, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToCairoLDT()
        {
            // Cairo Date&time: Thu, 01 Nov 2007 16:56:06 +0200 (EET)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Africa__Cairo);
            Assert.AreEqual(17, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToHelsinkiLDT()
        {
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Europe__Helsinki);
            Assert.AreEqual(17, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToDubaiLDT()
        {
            // Timezone: Asia/Dubai Date&time: Thu, 01 Nov 2007 19:05:15 +0400 (GST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Asia__Dubai);
            Assert.AreEqual(19, ldt.GetDateTime().Hour);
			//Console.WriteLine(ldt.ToString());
        }

        [Test]
        public void TestConvertLocalDateTimeToCalcuttaLDT()
        {
            // Timezone: Asia/Calcutta Date&time: Thu, 01 Nov 2007 20:34:28 +0530 (IST)
            LocalDateTime ldt = LocalDateTime.ConvertTo(_01_NOV_07__1600_, TimeZones.Asia__Calcutta);
            Assert.AreEqual(20, ldt.GetDateTime().Hour);
            Assert.AreEqual(30, ldt.GetDateTime().Minute);
			//Console.WriteLine(ldt.ToString());
        }

		[Test]
		public void TestLocalMin()
		{
			LocalDateTime oct1st2300 = new LocalDateTime(2009, 10, 1, 23, 0, 0);
			LocalDateTime oct1st2200 = new LocalDateTime(2009, 10, 1, 22, 0, 0);

			LocalDateTime minLocalDateTime = LocalDateTime.Min(oct1st2300, oct1st2200);
			Assert.IsTrue(minLocalDateTime.GetDateTime() == oct1st2200.GetDateTime());
		}

		[Test]
		public void TestLocalMax()
		{
			LocalDateTime oct1st2300 = new LocalDateTime(2009, 10, 1, 23, 0, 0);
			LocalDateTime oct1st2200 = new LocalDateTime(2009, 10, 1, 22, 0, 0);

			LocalDateTime maxLocalDateTime = LocalDateTime.Max(oct1st2300, oct1st2200);
			Assert.IsTrue(maxLocalDateTime.GetDateTime() == oct1st2300.GetDateTime());
		}

		[Test]
		public void TestAddHoursOctoberDst()
		{
			LocalDateTime oct24th09 = new LocalDateTime(2009, 10, 24, TimeZones.CET);	// Saturday 24-Oct-09, DST ends on Sunday 25th
			LocalDateTime oct26th09 = oct24th09.AddHours(49);
			Assert.AreEqual(2009, oct26th09.Year);
			Assert.AreEqual(10, oct26th09.Month);
			Assert.AreEqual(26, oct26th09.Day);
			Assert.AreEqual(0, oct26th09.Hour);

			LocalDateTime midDayOct24th09 = new LocalDateTime(2009, 10, 24, 12, 0, 0, TimeZones.CET, true);	// Saturday 24-Oct-09 12:00, DST ends on Sunday 25th
			LocalDateTime midDayOct26th09 = midDayOct24th09.AddHours(49);
			Assert.AreEqual(2009, midDayOct26th09.Year);
			Assert.AreEqual(10, midDayOct26th09.Month);
			Assert.AreEqual(26, midDayOct26th09.Day);
			Assert.AreEqual(12, midDayOct26th09.Hour);
		}

		[Test]
		public void TestAddHoursMarchDst()
		{
			LocalDateTime mar28th09 = new LocalDateTime(2009, 3, 28, TimeZones.CET); // Saturday 28-Mar-09, DST starts on Sunday 29th
			LocalDateTime mar30th09 = mar28th09.AddHours(47);
			Assert.AreEqual(2009, mar30th09.Year);
			Assert.AreEqual(3, mar30th09.Month);
			Assert.AreEqual(30, mar30th09.Day);
			Assert.AreEqual(0, mar30th09.Hour);

			LocalDateTime eveningMar28th09 = new LocalDateTime(2009, 3, 28, 22, 0, 0, TimeZones.CET, false); // Saturday 28-Mar-09 22:00, DST starts on Sunday 29th
			LocalDateTime morningMar29th09 = eveningMar28th09.AddHours(7);
			Assert.AreEqual(2009, morningMar29th09.Year);
			Assert.AreEqual(3, morningMar29th09.Month);
			Assert.AreEqual(29, morningMar29th09.Day);
			Assert.AreEqual(6, morningMar29th09.Hour);
		}

		[Test]
		public void TestAddHalfYearOfHours()
		{
			LocalDateTime jan1_09 = new LocalDateTime(2009, 1, 1, TimeZones.CET);
			LocalDateTime jul1_09 = new LocalDateTime(2009, 7, 1, TimeZones.CET);

			//4319 - spring 09
			//4393 - autumn 09
			LocalDateTime current = jan1_09;
			int hours = 0;
			int expectedHours = 4343;
			while(current.GetDateTime() < jul1_09.GetDateTime())
			{
				current = current.AddHoursToLocalDateTime(1);
				hours++;
			}

			Assert.AreEqual(expectedHours, hours);
			LocalDateTime result = jan1_09.AddHoursToLocalDateTime(hours);
			Assert.AreEqual(jul1_09, result);
		}

		[Test]
		public void TestCetDateTimeAddHours()
		{
			LocalDateTime jun18_2009 = new CetDateTime(2009, 06, 18).AsLocalDateTime();
			LocalDateTime jan01_2012 = new CetDateTime(2012, 01, 01).AsLocalDateTime();
			int hoursFromjun18_2009ToJan01_2012 = (int)jan01_2012.Subtract(jun18_2009).TotalHours;
			const int expectedHoursFromjun18_2009ToJan01_2012 = 22249;
			Assert.AreEqual(expectedHoursFromjun18_2009ToJan01_2012, hoursFromjun18_2009ToJan01_2012);

			LocalDateTime generatedJan01_2012 = jun18_2009.AddHours(expectedHoursFromjun18_2009ToJan01_2012);
			// Use LocalDateTime.CompareTo() instead of Assert.AreEqual(LocalDateTime expected, LocalDateTime actual)
			// because the latter one fails if e.g. expected is of type CetDateTime and actual is of
			// type LocalDateTime even when they both represent the exact same date time point.
			Assert.AreEqual(0, jan01_2012.CompareTo(generatedJan01_2012));
		}

		[Test]
		public void TestLocalDateTimeAddHours()
		{
			LocalDateTime jun18_2009 = new LocalDateTime(2009, 06, 18, TimeZones.CET);
			LocalDateTime jan01_2012 = new LocalDateTime(2012, 01, 01, TimeZones.CET);
			int hoursFromjun18_2009ToJan01_2012 = (int)jan01_2012.Subtract(jun18_2009).TotalHours;
			const int expectedHoursFromjun18_2009ToJan01_2012 = 22249;
			Assert.AreEqual(expectedHoursFromjun18_2009ToJan01_2012, hoursFromjun18_2009ToJan01_2012);

			LocalDateTime generatedJan01_2012 = jun18_2009.AddHours(expectedHoursFromjun18_2009ToJan01_2012);
			// Use LocalDateTime.CompareTo() instead of Assert.AreEqual(LocalDateTime expected, LocalDateTime actual)
			// because the latter one fails if e.g. expected is of type CetDateTime and actual is of
			// type LocalDateTime even when they both represent the exact same date time point.
			Assert.AreEqual(0, jan01_2012.CompareTo(generatedJan01_2012));
		}

		[Test]
		public void TestCetDateTimeAddDays()
		{
			LocalDateTime oct24th09 = new CetDateTime(2009, 10, 24).AsLocalDateTime();	// Saturday 24-Oct-09, DST ends on Sunday 25th
			LocalDateTime oct26th09 = new CetDateTime(2009, 10, 26).AsLocalDateTime();
			int hoursBetween = (int)oct26th09.Subtract(oct24th09).TotalHours;
			const int expectedHoursBetween = 24 + 25;
			Assert.AreEqual(expectedHoursBetween, hoursBetween);

			LocalDateTime generatedOct26th09 = oct24th09.AddDays(2);
			Assert.AreEqual(0, oct26th09.CompareTo(generatedOct26th09));

			LocalDateTime midDayOct24th09 = new CetDateTime(2009, 10, 24, 12, 0, 0).AsLocalDateTime();	// Saturday 24-Oct-09 12:00, DST ends on Sunday 25th
			LocalDateTime midDayOct26th09 = new CetDateTime(2009, 10, 26, 12, 0, 0).AsLocalDateTime();
			hoursBetween = (int)midDayOct26th09.Subtract(midDayOct24th09).TotalHours;
			Assert.AreEqual(expectedHoursBetween, hoursBetween);

			LocalDateTime generatedMidDayOct26th09 = midDayOct24th09.AddDays(2);
			Assert.AreEqual(0, midDayOct26th09.CompareTo(generatedMidDayOct26th09));
		}

		[Test]
		public void TestLocalDateTimeAddMinutes()
		{
			LocalDateTime oct24th09 = new LocalDateTime(2009, 10, 24, TimeZones.CET); // Saturday 24-Oct-09, DST ends on Sunday 25th
			LocalDateTime oct26th09 = new LocalDateTime(2009, 10, 26, TimeZones.CET);
			int minutesBetween = (int)oct26th09.Subtract(oct24th09).TotalMinutes;
			const int expectedMinutesBetween = (24 + 25) * 60;
			Assert.AreEqual(expectedMinutesBetween, minutesBetween);

			LocalDateTime generatedOct26th09 = oct24th09.AddMinutes(expectedMinutesBetween);
			Assert.AreEqual(0, oct26th09.CompareTo(generatedOct26th09));
		}

		[Test]
		public void TestCetDateTimeAddMinutes()
		{
			LocalDateTime oct24th09 = new CetDateTime(2009, 10, 24).AsLocalDateTime(); // Saturday 24-Oct-09, DST ends on Sunday 25th
			LocalDateTime oct26th09 = new CetDateTime(2009, 10, 26).AsLocalDateTime();
			int minutesBetween = (int)oct26th09.Subtract(oct24th09).TotalMinutes;
			const int expectedMinutesBetween = (24 + 25) * 60;
			Assert.AreEqual(expectedMinutesBetween, minutesBetween);

			LocalDateTime generatedOct26th09 = oct24th09.AddMinutes(expectedMinutesBetween);
			Assert.AreEqual(0, oct26th09.CompareTo(generatedOct26th09));
		}

		[Test]
		public void TestLocalDateTimeAddSeconds()
		{
			LocalDateTime oct24th09 = new LocalDateTime(2009, 10, 24); // Saturday 24-Oct-09, DST ends on Sunday 25th
			LocalDateTime oct26th09 = new LocalDateTime(2009, 10, 26);
			int secondsBetween = (int)oct26th09.Subtract(oct24th09).TotalSeconds;
			const int expectedSecondsBetween = (24 + 25) * 60 * 60;
			Assert.AreEqual(expectedSecondsBetween, secondsBetween);

			LocalDateTime generatedOct26th09 = oct24th09.AddSeconds(expectedSecondsBetween);
			Assert.AreEqual(0, oct26th09.CompareTo(generatedOct26th09));
		}

		[Test]
		public void TestCetDateTimeAddSeconds()
		{
			LocalDateTime oct24th09 = new CetDateTime(2009, 10, 24).AsLocalDateTime(); // Saturday 24-Oct-09, DST ends on Sunday 25th
			LocalDateTime oct26th09 = new CetDateTime(2009, 10, 26).AsLocalDateTime();
			int secondsBetween = (int)oct26th09.Subtract(oct24th09).TotalSeconds;
			const int expectedSecondsBetween = (24 + 25) * 60 * 60;
			Assert.AreEqual(expectedSecondsBetween, secondsBetween);

			LocalDateTime generatedOct26th09 = oct24th09.AddSeconds(expectedSecondsBetween);
			Assert.AreEqual(0, oct26th09.CompareTo(generatedOct26th09));
		}

		[Test]
		public void TestCetDateTimeGetDate()
		{
			DateTime time = DateTime.SpecifyKind(new DateTime(2009, 07, 27), DateTimeKind.Unspecified);	// 27-Jul-09, unspecified kind
			LocalDateTime aCetDateTime = new CetDateTime(time).AsLocalDateTime();
			LocalDateTime aCetDate = aCetDateTime.Date;
			Assert.AreEqual(aCetDate.GetDateTime(), time);
		}

		[Test]
		public void TestCetDateTimeNowGetDate()
		{
			LocalDateTime aCetDateTime = CetDateTime.CetNow.AsLocalDateTime();
			LocalDateTime aCetDate = aCetDateTime.Date;
			Assert.AreEqual(aCetDate.GetDateTime().Date, DateTime.Now.Date);
		}

		[Test]
		public void TestDateTimeDaySubtraction()
		{
			DateTime reportDate = new DateTime(2008, 6, 5); // 05-Jun-2008
			DateTime start = new DateTime(2008, 10, 1); // 01-Oct-2008
			DateTime end = new DateTime(2009, 1, 1); // 01-Jan-2009
			DateTime expiry = new DateTime(2008, 9, 18); // 18-Sep-2008
			double daysToExpiry = expiry.Subtract(reportDate).TotalDays; // 105.0
			double expectedDaysToExpiry = 105.0;
			double daysToStart = start.Subtract(reportDate).TotalDays; // 118.0
			double expectedDaysToStart = 118.0;
			Assert.AreEqual(expectedDaysToExpiry, daysToExpiry);
			Assert.AreEqual(expectedDaysToStart, daysToStart);

			double expectedDaysToEnd = 210.0;
			double daysToEnd = end.Subtract(reportDate).TotalDays; // 210.04166666666666 vs 210			
			Assert.AreEqual(expectedDaysToEnd, daysToEnd);

			expectedDaysToEnd = 210.04166666666666;
			daysToEnd = end.ToUniversalTime().Subtract(reportDate.ToUniversalTime()).TotalDays; // 210.04166666666666 vs 210
			Assert.AreEqual(expectedDaysToEnd, daysToEnd);
		}

		[Test]
		public void TestLocalDateTimeDaySubtraction()
		{
			LocalDateTime reportDate = new LocalDateTime(2008, 6, 5);	// 05-Jun-2008
			LocalDateTime start = new LocalDateTime(2008, 10, 1);		// 01-Oct-2008
			LocalDateTime end = new LocalDateTime(2009, 1, 1);		// 01-Jan-2009
			LocalDateTime expiry = new LocalDateTime(2008, 9, 18);	// 18-Sep-2008
			double daysToExpiry = expiry.Subtract(reportDate).TotalDays;// 105.0
			double expectedDaysToExpiry = 105.0;
			double daysToStart = start.Subtract(reportDate).TotalDays;	// 118.0
			double expectedDaysToStart = 118.0;
			double daysToEnd = end.Subtract(reportDate).TotalDays;	// 210.04166666666666 vs 210
			double expectedDaysToEnd = 210.04166666666666;

			Assert.AreEqual(expectedDaysToExpiry, daysToExpiry);
			Assert.AreEqual(expectedDaysToStart, daysToStart);
			Assert.AreEqual(expectedDaysToEnd, daysToEnd);
		}

		[Test]
		public void TestNull()
		{
			LocalDateTime nullDateTime = LocalDateTime.Null;
			Assert.IsTrue(nullDateTime.IsNull);
			Assert.IsTrue(nullDateTime.TimeZone.IsNull);
		}

		[Test]
		public void TestSydneySummerChange()
		{
			LocalDateTime winter = new LocalDateTime(2009, 10, 4, 0, 0, 0, TimeZones.Australia__Sydney, false);
			LocalDateTime summer = winter.AddHours(3);
			LocalDateTime expected = new LocalDateTime(2009, 10, 4, 4, 0, 0, TimeZones.Australia__Sydney, true);

			Assert.AreEqual(expected, summer);
		}

		[Test]
		public void TestSydneyWinterChangeAddHour1From12AmTo1Am()
		{
			LocalDateTime summer = new LocalDateTime(2009, 4, 5, 0, 0, 0, TimeZones.Australia__Sydney, true);
			LocalDateTime am1 = summer.AddHours(1);
			Assert.IsTrue(am1.IsDST);
		}

    	[Test]
		public void TestSydneyWinterChangeAddHour1()
		{
			LocalDateTime summer = new LocalDateTime(2009, 4, 5, 0, 0, 0, TimeZones.Australia__Sydney, true);
			LocalDateTime until = new LocalDateTime(2009, 4, 6, 0, 0, 0, TimeZones.Australia__Sydney, false);
			LocalDateTime current = summer;
			int limit = 30;
			for (int i = 0; (current < until) && (i < limit); current = current.AddHours(1), i++)
			{
				//Console.WriteLine(current);
			}
		}


		[Test]
		public void TestSydneyWinterChange()
		{
			
			LocalDateTime summer = new LocalDateTime(2009, 4, 5, 0, 0, 0, TimeZones.Australia__Sydney, true);
			LocalDateTime winter = summer.AddHours(3);
			LocalDateTime expected = new LocalDateTime(2009, 4, 5, 2, 0, 0, TimeZones.Australia__Sydney, false);

			Assert.AreEqual(expected, winter);
		}

		[Test]
		public void AddHalfHourToTimeOfDSTChange()
		{
			LocalDateTime timeOfDSTChange = new LocalDateTime(2009, 10, 25, 2, 0, 0, TimeZones.CET, false);
			LocalDateTime nextHour = timeOfDSTChange.AddHours(.5);
			LocalDateTime expected = new LocalDateTime(2009, 10, 25, 2, 30, 0, TimeZones.CET, false);
			
			Assert.AreEqual(expected, nextHour);
		}

		/*[Test]
		public void TestSydneyWinterChange_AddHours_767()
		{

			LocalDateTime summer = new LocalDateTime(2009, 3, 5, 0, 0, 0, TimeZones.Australia__Sydney, true);
			LocalDateTime winter = summer.AddHours(767);
			LocalDateTime winter2 = summer.AddDays(32);
			LocalDateTime expected = new LocalDateTime(2009, 4, 5, 2, 0, 0, TimeZones.Australia__Sydney, false);

			Assert.AreEqual(winter2, winter);
		}*/

		[Test]
		public void TestSydneyWinterChange_AddHours_48()
		{

			LocalDateTime summer = new LocalDateTime(2009, 4, 4, 0, 0, 0, TimeZones.Australia__Sydney, true);
			LocalDateTime winter = summer.AddHours(48);
			LocalDateTime expected = new LocalDateTime(2009, 4, 5, 23, 0, 0, TimeZones.Australia__Sydney, false);

			Assert.AreEqual(expected, winter);
		}

		[Test]
		public void TestLocalDateTime_TimeZoneResolvementInInvariantCulture()
		{
			Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
			LocalDateTime summer = new LocalDateTime(2009, 4, 4);
			Assert.IsTrue(summer.TimeZone.CanonicalID.Equals("CET"));
		}

		[Test]
		public void TestCompareToOnOctDst()
		{
			// Create timepoint Sunday 25-Oct-09 02:00 IsDST = true, i.e. one hour before adjusting the clock back from 03:00 to 02:00
			LocalDateTime twoOClockBeforeAdjustingClock = new LocalDateTime(2009, 10, 25, 2, 0, 0, TimeZones.CET);
			// Convert the timepoint to UTC and create a new UTC timepoint by adding one hour
			UtcDateTime twoOClockUtc = twoOClockBeforeAdjustingClock.ConvertToUTC();
			UtcDateTime threeOClockUtc = twoOClockUtc.AddHours(1);
			// Convert the one-hour-later UTC timepoint back to CET, it will be Sunday 25-Oct-09 02:00 IsDST = false, i.e. immediately after adjusting the clock back from 03:00 to 02:00
			LocalDateTime twoOClockAfterAdjustingClock = threeOClockUtc.ConvertTo(TimeZones.CET);
			// The native DateTime instances of our LocalDateTime instances are now equal, but the IsDST properties of our LocalDateTime instances
			// are different, so comparing them to each other should not give 0.
			Assert.IsTrue(twoOClockBeforeAdjustingClock < twoOClockAfterAdjustingClock);
			Assert.IsTrue(twoOClockAfterAdjustingClock > twoOClockBeforeAdjustingClock);
		}

		[Test]
		public void TestDateOnOctDst()
		{
			// Create timepoint Sunday 25-Oct-09 12:00, it will have IsDST = false
			LocalDateTime midDay25Oct = new LocalDateTime(2009, 10, 25, 12, 0, 0, TimeZones.CET);
			// Get the date of part of 25-Oct-09 12:00 (using the Date property), it should be 25-Oct-09 00:00 and thus have IsDST = true.
			// There was earlier a DateAsLocalDateTime property in addition to the Date property, it didn't work properly.
			// The two properties should be equal, so the DateAsLocalDateTime property has simply been removed as it's not necessary.
			LocalDateTime datePartOfMidDay25Oct = midDay25Oct.Date;
			LocalDateTime expectedDatePartOfMidDay25Oct = new LocalDateTime(2009, 10, 25, TimeZones.CET);
			Assert.AreEqual(expectedDatePartOfMidDay25Oct, datePartOfMidDay25Oct);
		}

		[Test]
    	public void TestSubtract2HoursOnSummerDstChange2010()
    	{
			LocalDateTime _28March2010_0000 = new LocalDateTime(2010, 3, 28, 0, 0, 0, TimeZones.CET, false);
			LocalDateTime _28March2010_0300 = new LocalDateTime(2010, 3, 28, 3, 0, 0, TimeZones.CET, true);
			LocalDateTime calc_28March2010_0000 = _28March2010_0300.Subtract(new TimeSpan(2, 0, 0));
			
			Assert.AreEqual(_28March2010_0000, calc_28March2010_0000);

			TimeSpan expectedSpan = new TimeSpan(2,0,0);
			TimeSpan span = _28March2010_0300.Subtract(_28March2010_0000);

			Assert.AreEqual(expectedSpan, span);
    	}

		[Test]
		public void TestSubtract1HourOnWinterDstChange2010()
		{
			LocalDateTime _31Oct2010_0200 = new LocalDateTime(2010, 10, 31, 2, 0, 0, TimeZones.CET, false);
			LocalDateTime _31Oct2010_0200Dst = new LocalDateTime(2010, 10, 31, 2, 0, 0, TimeZones.CET, true);
			LocalDateTime calc_31Oct2010_0200 = _31Oct2010_0200.Subtract(new TimeSpan(1, 0, 0));

			Assert.AreEqual(_31Oct2010_0200Dst, calc_31Oct2010_0200);

			TimeSpan expectedSpan = new TimeSpan(1, 0, 0);
			TimeSpan span = _31Oct2010_0200.Subtract(_31Oct2010_0200Dst);

			Assert.AreEqual(expectedSpan, span);
		}

		[Test]
		public void TestSubtractOnTimeSpan_TotalDays()
		{
			LocalDateTime _31Oct2010_0200 = new LocalDateTime(2010, 10, 31, 0, 0, 0, TimeZones.CET, true);
			LocalDateTime _24Oct2010_0200 = new LocalDateTime(2010, 10, 24, 0, 0, 0, TimeZones.CET, true);
			Assert.AreEqual(7, _31Oct2010_0200.Subtract(_24Oct2010_0200).TotalDays);
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Norway Norway
http://www.linkedin.com/in/steinardragsnes

Comments and Discussions