# Introduction

DateTime structure is a representation of time in date and time format. Whereas TimeSpan structure helps you to deal with a time interval, which means it represents a length of time, in C#. This article covers some of the basic applications of  DateTime and TimeSpan. DateTime can accept at most 8 parameters in its constructor, which are as follows:
```	int year,
int month,
int day,
int hour,
int minute,
int second,
int millisecond,
DateTimeKind kind```

TimeSpan can accept at most 5 parameters in its constructor, which are as follows:
```	int days,
int hours,
int minutes,
int seconds,
int milliseconds```
Thus you can notice that we can use DateTime to represent any time in a date with time format and we can use TimeSpan to find interval between any DateTime very easily. Let's use TimeSpan structure to find the working day difference between two dates where we also take the weekend and bank holidays into consideration.

# Pre-requisite and Assumption

In this example we will be implementing a method, which returns the difference in another structure, which is named as DaySpan and only consists of properties: Days, Hour, Minutes and Seconds. In this example, we could have simply returned the TimeSpan from the method but in that case, we wouldn't be able to explore some access features of TimeSpan.

# The Code and It's Implementation

If we have to find the difference between two DateTimes then we can simply use the method Subtract() of DateTime, which returns TimeSpan and has a signature as follows:
`public` `TimeSpan Subtract(`
`    ``DateTime value`
`)`

But using Subtract() method returns the TimeSpan (time interval) between two days without taking weekends or holidays into account in case if you may want to build a custom method that gets the working time interval between two dates. Follow along and I will show how we can achieve this.

## The Algorithm

Before we proceed any further let's discuss the algorithm, which will be the heart of our custom method. The algorithm as follows:

`// Working Algorithm`
`If FromDate > ToDate Then:`
`    ``return` `0;`
`var timeDifference = ToDate.Subtract(FromDate)`
`while` `FromDate < ToDate:`
`    ``If FromDate == Saturday OR FromDate == Sunday Then:`
`        ``timeDifference = timeDifference.Subtract(timeSpanOfOneDay)`
`    ``If FromDate == BankHoliday`
`        ``timeDifference = timeDifference.Subtract(timeSpanOfOneDay)`
`    ``FromDate = FromDate.AddDays(1)`
`return` `timeDifference`

The aforementioned algorithm shows the working principle of our custom method but when we implement this algorithm in our C# code, it can look a bit different, which we will explore little later. But before we proceed to convert this algorithm into our live C# code, let's discuss few methods and properties of TimeSpan, which will be useful for us to accomplish this task.

We can use the AddDays(int) method of DateTime to add the specified number of days to a DateTime as follows:
`// A dummy date of 01/01/1900 00:00:00 is created`
`DateTime dummy = ``new` `DateTime(1900, 1, 1, 0, 0, 0);`
`DateTime nextDummyDay = dummy.AddDays(1); ``// AddDays() to add number of days`

We can also use the AddHours(int) method of DateTime to add the specified number of hours and can use AddMinutes(int) to add specified minutes to the DateTime, similar to what is shown above. Majority of the time you will be using these methods to add days, hours, minutes, but there are other provisions as well and you can check the full list of the available methods here.

Another common property which we use of DateTimis  Ticks. This property accesses the number of ticks that represent the date and time of this instance. Another important property of DateTime, which is noteworthy is Now, which gets the current local date and time of the computer. In our exampl, we will use another property namedDayOfWeek, which will get the day of the date between Monday to Sunday of a week. Other noteworthy properties of DateTime but not inclusive of all in the list are as follows:

 Day Gets the day of the month of the DateTime Hour Gets the hour of the month of the DateTime Today Gets the current date but the hour:minute:second is set to 12:00:00 AM of the current date and hence little different from Now property Year Gets the year component of the instance of the DateTime

These are some of the popular access properties, which most developers use but there are many more and the full list can be found from the link in the reference.

Now, few of the important access properties of TimeSpan, which developers use most of the time are as follows:
 TotalDays Gets the total days representation of TimeSpan, which means TimeSpan instance is represented as a fractional day TotalHours Gets the total hours representation of TimeSpan, which means TimeSpan instance is represented as a fractional hours Days Gets the number of whole days of the TimeSpan instance Hours Gets the number of whole hours of the TimeSpan instance Minutes Gets the number of whole minutes of the TimeSpan instance Ticks Get the total number of ticks that represents the TimeSpan instance

And some of the popular methods of TimeSpan, which developers use from time to time are as follows:
 Add(TimeSpan) Adds the specified TimeSpan to the current instance of TimeSpan and returns it Equals(TimeSpan) Checks if two instances of TimeSpan are equal or not Compare(TimeSpan) Compare the specified TimeSpan with the current TimeSpan instance and returns an integer to show the difference between the two FromTicks(Int64) Returns a time TimeSpan of specified time, which is represented as ticks Parse(String) Convert the String into a TimeSpan if possible TryParse(String, out TimeSpan) Try to convert the String into TimeSpan as the out parameter

The aforementioned properties and methods of TimeSpan structure are only tip of the iceberg and you can refer to this link to check all the available features of TimeSpan.

Now, that we know quite of bit of both DateTime and TimeSpan, lets covert our aforementioned algorithm into our live C# code as follows:

`public` `DaySpan ComputeDaysDifference(DateTime ToDate, DateTime FromDate, DateTime[] BankHolidays, ``bool` ```WorkOnSaturday = ````false``,``bool` `WorkOnSunday = ``false``)`
`        ``{`
`            ``DateTime TDate = ``new` ```DateTime(FromDate.Year, FromDate.Month, FromDate.Day, FromDate.Hour, FromDate.Minute, FromDate.Second, FromDate.Millisecond);```
`            ``if` `(ToDate.Year == 1900)`
`            ``{`
`                ``ToDate = DateTime.Now;`
`            ``}`
`            ``int` `DaysOverdue = 0;`
`            ``int` `HoursOverdue = 0;`
`            ``int` `MinsOverdue = 0;`
`            ``int` `SecsOverdue = 0;`
`            ``// Time Difference between FromDate and ToDate in TimeSpan format`
`            ``TimeSpan difference = ToDate.Subtract(FromDate);`

`            ``// subtract the bank holidays`
`            ``DateTime dummy = ``new` ```DateTime(1900, 1, 1, 0, 0, 0);```
`            ``DateTime nextDummyDay = dummy.AddDays(1); ``// AddDays() to add number of days`
`            ``DateTime nextDummyHour = dummy.AddHours(1); ``// AddHours() to add number of hours`
`            ``TimeSpan timespanOfOneDay = nextDummyDay.Subtract(dummy);`
`            ``TimeSpan timespanOfOneHour = nextDummyHour.Subtract(dummy);`

`            ``try`
`            ``{`
`                ``if` `(FromDate > ToDate)`
`                    ``return` `new` `DaySpan(); ````// not overdue```

`                ``DateTime intermediate = ``new` ```DateTime(FromDate.Year, FromDate.Month, FromDate.Day);```

`                ``while` `(intermediate < ToDate)`
`                ``{`
`                    ``if` `(intermediate.DayOfWeek == DayOfWeek.Saturday)`
`                    ``{`
`                        ``if` `(!WorkOnSaturday)`
`                        ``{`
`                            ``difference = difference - timespanOfOneDay;`
`                        ``}`
`                    ``}`

`                    ``if` `(intermediate.DayOfWeek == DayOfWeek.Sunday)`
`                    ``{`
`                        ``if` `(!WorkOnSunday)`
`                        ``{`
`                            ``difference = difference - timespanOfOneDay;`
`                        ``}`
`                    ``}`

`                    ``intermediate = intermediate.AddDays(1);`
`                ``}`

`                ``if` `(BankHolidays != ``null` ```&& BankHolidays.Length > 0)```
`                ``{`
`                    ``for` `(``int` ```i = 0; i < BankHolidays.Length; i++)```
`                    ``{`
`                        ``if` ```(BankHolidays[i].Ticks > FromDate.Ticks && BankHolidays[i].Ticks < ToDate.Ticks)```
`                        ``{`
`                            ``// Bank holidays is in between FromDate and ToDate`
`                            ``difference = difference - timespanOfOneDay;`
`                        ``}`
`                    ``}`
`                ``}`

`            ``}`
`            ``catch` `(Exception ex)`
`            ``{`
`                ``string` `error = ````"Failed to compute difference in days for Completion Date "``` `+ ToDate.ToString() + ``" and Target "` `+ FromDate.ToString()`
`                                                ``+ ``".  Error:"` `+ ex.Message.ToString();`
`                ``throw` `new` `Exception(error);`
`            ``}`
`            ``finally`
`            ``{`
`                ``DaysOverdue = difference.Days;`
`                ``HoursOverdue = difference.Hours;`
`                ``MinsOverdue = difference.Minutes;`
`                ``SecsOverdue = difference.Seconds;`
`            ``}`
`            ``return` `new` ```DaySpan { Days = DaysOverdue, Hours = HoursOverdue, Minutes = MinsOverdue, Seconds = SecsOverdue };```
`        ``}`
``` // Custom DaySpan to be returned by ComputeDaysDifference()```
`public` `struct` `DaySpan`
`{`
`    ``public` `int` `Days;`
`    ``public` `int` `Hours;`
`    ``public` `int` `Minutes;`
`    ``public` `int` `Seconds;`
`}`

## Testing Our Custom C# Method

To test our custom method we run the following program and we check for validation as follows:

`    ``public` `static` `void` `Main(``string````[] args)```
`    ``{`
`        ``TimeDifference td = ``new` `TimeDifference();`
`        ``DateTime fromDate = ``new` ```DateTime(1990, 12, 13);```
`        ``DateTime toDate = ``new` ```DateTime(1990, 12, 14);```

`        ``// Difference of one day`
`        ``var dayDifference = td.ComputeDaysDifference(toDate, fromDate, ``null``);`
`        ``Console.WriteLine(``"Case 1"``);`
`        ``Console.WriteLine(``"Day Difference: "` `+ dayDifference.Days);`
`        ``Console.WriteLine(``"Hour Difference: "` `+ dayDifference.Hours);`
`        ``Console.WriteLine(``"Minute Difference: "` `+ dayDifference.Minutes);`
`        ``Console.WriteLine(``"Seconds Difference: "` `+ dayDifference.Seconds);`
`        ``Console.WriteLine(``"\n"``);`

`        ``// Difference of one day and seven hours`
`        ``fromDate = ``new` ```DateTime(1990, 12, 13, 6, 0, 0);```
`        ``toDate = ``new` ```DateTime(1990, 12, 14, 13, 0, 0);```
`        ``dayDifference = td.ComputeDaysDifference(toDate, fromDate, ``null``);`
`        ``Console.WriteLine(``"Case 2"``);`
`        ``Console.WriteLine(``"Day Difference: "` `+ dayDifference.Days);`
`        ``Console.WriteLine(``"Hour Difference: "` `+ dayDifference.Hours);`
`        ``Console.WriteLine(``"Minute Difference: "` `+ dayDifference.Minutes);`
`        ``Console.WriteLine(``"Seconds Difference: "` `+ dayDifference.Seconds);`
`        ``Console.WriteLine(``"\n"``);`

`        ``// Difference of two days and seven hours. There's one Saturday and Sunday in between`
`        ``fromDate = ``new` ```DateTime(1990, 12, 13, 6, 0, 0);```
`        ``toDate = ``new` ```DateTime(1990, 12, 17, 13, 0, 0);```
`        ``dayDifference = td.ComputeDaysDifference(toDate, fromDate, ``null``);`
`        ``Console.WriteLine(``"Case 3"``);`
`        ``Console.WriteLine(``"Day Difference: "` `+ dayDifference.Days);`
`        ``Console.WriteLine(``"Hour Difference: "` `+ dayDifference.Hours);`
`        ``Console.WriteLine(``"Minute Difference: "` `+ dayDifference.Minutes);`
`        ``Console.WriteLine(``"Seconds Difference: "` `+ dayDifference.Seconds);`
`        ``Console.WriteLine(``"\n"``);`

`        ``// Difference of three days and seven hours. There's one Saturday and Sunday in between.`
`        ``// We work on Saturday and hence it is true.`
`        ``fromDate = ``new` ```DateTime(1990, 12, 13, 6, 0, 0);```
`        ``toDate = ``new` ```DateTime(1990, 12, 17, 13, 0, 0);```
`        ``dayDifference = td.ComputeDaysDifference(toDate, fromDate, ``null``, ``true``, ``false``);`
`        ``Console.WriteLine(``"Case 4"``);`
`        ``Console.WriteLine(``"Day Difference: "` `+ dayDifference.Days);`
`        ``Console.WriteLine(``"Hour Difference: "` `+ dayDifference.Hours);`
`        ``Console.WriteLine(``"Minute Difference: "` `+ dayDifference.Minutes);`
`        ``Console.WriteLine(``"Seconds Difference: "` `+ dayDifference.Seconds);`
`        ``Console.WriteLine(``"\n"``);`

`        ``// Difference of one day and seven hours. There's one Saturday and Sunday in between.`
`        ``// We work on Saturday and hence it is true. And 14th and 17th are holidays.`
`        ``fromDate = ``new` ```DateTime(1990, 12, 13, 6, 0, 0);```
`        ``toDate = ``new` ```DateTime(1990, 12, 17, 13, 0, 0);```
`        ``DateTime[] holidays = { ``new` ```DateTime(1990, 12, 14), ````new`  `DateTime(1990, 12, 17)};`
`        ``dayDifference = td.ComputeDaysDifference(toDate, fromDate, holidays, ``true``, ``false``);`
`        ``Console.WriteLine(``"Case 5"``);`
`        ``Console.WriteLine(``"Day Difference: "` `+ dayDifference.Days);`
`        ``Console.WriteLine(``"Hour Difference: "` `+ dayDifference.Hours);`
`        ``Console.WriteLine(``"Minute Difference: "` `+ dayDifference.Minutes);`
`        ``Console.WriteLine(``"Seconds Difference: "` `+ dayDifference.Seconds);`
`        ``Console.WriteLine(``"\n"``);`
`    ``}`
`}`

### Result 