Click here to Skip to main content
15,887,383 members
Articles / Programming Languages / C#

MoreDateTime - ExtendedDateTime Extension Library for .NET

Rate me:
Please Sign up or sign in to vote.
4.97/5 (9 votes)
13 Feb 2024MIT4 min read 22.2K   165   22   5
An extension library to simplify dealing with .NET's DateTime, DateOnly, TimeOnly and TimeSpan objects, also includes support for the ISO 8601 EDTF profile.
"MoreDateTime" is a feature-rich .NET date and time library that extends the standard DateTime functionality, offering over 300 methods for managing dates, times, and date ranges, including support for ISO 8601-2 2019 Extended Date Time Format Profile (EDTF). It simplifies common date and time tasks, supports conversions between various date types, and is designed as an extension to the .NET standard library, making it a powerful tool for working with dates and times in .NET applications.

Build status NuGet Version

📅 MoreDateTime - Github / Docs

⭐ News v1.3 ⭐

Just included now: ISO 8601-2 2019 Extended Date Time Format Profile (EDTF) support.

You can use the new ExtendedDateTime class just as you would use the .NET DateTime class, with most of the conversions between ExtendedDateTime, DateTime and DateOnly supported. All formats specified in the standard are supported. The implementation is based on the EDTF.NET implementation which was based on the draft of the ISO standard.

Example:

var someWhenInThe60s = new ExtendedDateTime("1960S2");
var longAgo = new ExtendedDateTime("Y-3388E2S3"); // yes, thats some year between 338000 and 338999, estimated to be 338800
var fourYearsIn1670 = new ExtendedDateTime("1670..1673");
var someDayInSpring = new ExtendedDateTime("2021-21");
var aRange = new ExtendedDateTime("..1983-12-31,1984-10-10..1984-11-01,1984-11-05.."); // somewhen before 1983 and between 1984-10-10 and 1984-11-01 and after 1984-11-05

You see, there are many possibilities to specify dates and date ranges.

Documentation is lacking a bit still, but this will be remedied soon. Some minor code cleanups are to be done still too.

PS: I would love to include full ISO 8601-2 2019 support, but thats a big chunk to bite off, maybe some day. Volunteers are welcome though.

Description

This library is built from the ground up to be a simple, easy to use, and intuitive date and time library for .NET, that simplifies common tasks and provides a consistent API for working with dates and times, throughout the DateTime, DateOnly, TimeOnly and TimeSpan .NET objects. It adds many operations that one expects to find in a date and time library, but are missing from the .NET standard library. Currently it features over 300 methods to deal with dates and times and ranges (periods) thereof.

It is however not intended to be a replacement for any part of the standard .NET library, but rather an extension to it. It is built upon the existing .NET standard library and does not replace any of the existing functionality. It is also not intended to be a replacement for the NodaTime library, but it can be used in conjunction.

Conversions between the types or operations with mixed types (use DateTime and DateOnly for example without converting one into the other manually) are possible.

For example: NextWeek() to advance a DateTime or DateOnly to the same weekday in the next week, NextYear() to add a year to a DateTime or DateOlnly object (yes, of course you can use the existing .AddYears(1) method, but it does not look as clear), NextWorkday() to advance the DateTime or DateOnly object to the next working day on the given Calendar.

Or things like IsWeekend() which of course you can also do with myDate.DayOfWeek == DayOfWeek.Saturday || myDate.DayOfWeek == DayOfWeek.Sunday, but it just aint as nice to read. Then we also have IsWorkday() which is the opposite of IsWeekend() and also IsHoliday() which checks if the given date is a holiday on the given calendar.

Not to mention the IsBetween() method which is a very useful method to check if a date is between two other dates. It also supports the DateOnly and TimeOnly objects.

For more elaborate operations we have the Enumerations, like EnumerateDaysUntil, EnumerateMonthsUntil, EnumerateYearsUntil, EnumerateWeeksUntil, EnumerateWorkdaysUntil, EnumerateWeekendsUntil, EnumerateHolidaysUntil.

Finally you can add minutes to a DateOnly object (given its more than a day) -> myDate.AddMinutes(525600); // thats a year in minutes or even hours or seconds if you wish so.

Want to know the FirstMondayOfTheMonth? -> myDate.FirstMondayOfTheMonth() or the LastFridayOfTheMonth? -> myDate.LastFridayOfTheMonth(). How often did you need already to know the first or last day of the month? -> myDate.FirstDayOfTheMonth() or myDate.LastDayOfTheMonth().

Need to know the number of workdays in a period? -> myDate.NumberOfDaysUntil() or the number of holidays in a period? -> myDate.NumberOfHolidaysUntil().

You can also create custom enumerations with EnumerateInStepsUntil which allows you to create enumerations from a start date or time until a end date or time in steps specified by a TimeSpan. Like in

void ListAllDaysNotHolidays(DateOnly startDate)
{
	// you can provide also a Calendar object to the EnumerateInStepsUntil method if the current Culture is not adequate
	var myEnum = startDate.EnumerateInStepsUntil(startDate.AddMonths(6), TimeSpan.FromDays(1), SkipHolidays);

	foreach (var item in myEnum)
	{
		Console.WriteLine(item);
	}

	bool SkipHolidays(DateOnly date) => return !date.IsHoliday();
}

Another sample, create 10 minute spans over a week, but skip midnight

void Get10MinuteSpans(DateTime startDate)
{
	var myEnum = startDate.EnumerateInStepsUntil(startDate.NextWeek(), TimeSpan.FromMinutes(10), SkipMidnight);

	foreach (var item in myEnum)
	{
		Console.WriteLine(item);
	}

	bool SkipMidnight(DateTime date)
	{
		return !date.IsMidnight();
	}
}

You got your own IDateTimeProvider through which you can inject your own date and time and supports mocking directly. Instead of DateTime.Utcnow you can use DateTimeProvider.Current.UtcNow and always get the date and time you expect.

How to use it?

Just install the NuGet package and you are ready to go! It's mostly built upon common sense when using Date and Time objects in .NET.

Dependencies

For Holiday calculations it uses the Nager.Date library, but you need to bring your own license key. There is also a DefaultHolidayProvider() which knows only the very few international holidays and is the default. Optionally you can use your own provider through the IHolidayProvider interface and the DateTimeProvider.SetHolidayProvider() method.

Note

Documentation is mostly complete, although there may be some missing or even wrong descriptions (copy paste errors usually). If you find something missing or wrong, please let me know.

Unit tests cover ~98%, a few edge cases are not covered yet. So there is a high confidence that the code is working correctly.

Examples

NuGet

The NuGet package is available via NuGet

PM> install-package MoreDateTime
Code Examples (click to expand)

Examples for .NET (NuGet package)

coming soon

Example 1 - tbd

--> code sample here, coming asap
This article was originally posted at https://github.com/Hefaistos68/MoreDateTime

License

This article, along with any associated source code and files, is licensed under The MIT License



Comments and Discussions

 
QuestionPersistence support Pin
DerekT-P14-Dec-23 10:16
professionalDerekT-P14-Dec-23 10:16 
AnswerRe: Persistence support Pin
Andreas Saurwein15-Dec-23 0:01
Andreas Saurwein15-Dec-23 0:01 
QuestionThanks Pin
Danilo Gozzola 202114-Dec-23 0:29
Danilo Gozzola 202114-Dec-23 0:29 
AnswerRe: Thanks Pin
Andreas Saurwein14-Dec-23 1:22
Andreas Saurwein14-Dec-23 1:22 
GeneralMy vote of 5 Pin
Ștefan-Mihai MOGA11-Oct-23 19:45
professionalȘtefan-Mihai MOGA11-Oct-23 19:45 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.