CLI tool
joaomatossilva/DateTimeExtensions avatar
joaomatossilva/DateTimeExtensions

DateTimeExtensions: working days, holidays and natural date text for C#

This project is a merge of several common DateTime operations on the form of extensions to System.DateTime, including natural date difference text (precise and human rounded), holidays and working days calculations on several culture locales.

903 stars419 forksC#NOASSERTION

At a glance

What is it?
DateTimeExtensions adds extension methods to System.DateTime and System.DateTimeOffset so that working day arithmetic, holiday lookups and human readable date differences become one-line calls. It ships holiday definitions for a long list of cultures, it can export those holidays to calendar formats, and the licence is stated one way in the README and another way by the repository.
Who is it for?
DateTimeExtensions suits a C# team that has to reason about working days and public holidays for several countries, and that would rather express that in one call than in a hand-rolled calendar service, and it suits a team that wants its own holiday rules via the IWorkingDayCultureInfo interface. It does not suit a project that needs country-specific calendars the library does not ship, since those have to be written by hand.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 25 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Extension methods on DateTime, not a new date type

The library's approach is to extend the framework's own types rather than introduce a wrapper, which is why it is described as extending the functionality of System.DateTime and System.DateTimeOffset. That decision has visible consequences. The methods are called on a date instance, so a working day calculation reads as an operation on the date rather than as a call to a service you have to configure, and the result is a plain DateTime that flows on into the rest of your code without conversion. The stated goal is to make the code more expressive and easier to read, and the six features the project lists are working day calculations that consider regional holidays, holiday support for multiple cultures and regions, natural language date differences, time of day operations, calendar export of holidays, and SourceLink support for debugging into the source code. The project describes itself as a merge of several common DateTime operations, which is a fair summary of a library that grew by accretion rather than around a single idea.

Four calls cover the common cases

The quick start section is short enough to read as the documentation, and it shows the shape of the API. Adding working days to a date, checking whether a date is a working day, getting a natural language difference, and testing whether a time falls between two others:

csharp
using DateTimeExtensions;

// Add 5 working days to a date
DateTime futureDate = DateTime.Now.AddWorkingDays(5);

// Check if a date is a working day
bool isWorkingDay = DateTime.Now.IsWorkingDay();

// Get the difference between dates in natural language
string dateDiff = DateTime.Now.ToNaturalText(DateTime.Now.AddDays(45));

// Check if a time is between two other times
bool isBetween = DateTime.Now.IsBetween(new Time("09:00"), new Time("17:00"));

The Time type in the last example is the one worth noticing, since it takes a string in that constructor and gives the library a way to talk about points in the day without you constructing a TimeSpan by hand. The natural language difference method is the other one that saves the most code, because replacing that with a hand-written description of a forty five day gap is exactly the kind of fiddly work that ends up inconsistent between screens. The using statement is the only setup the examples need beyond the package reference itself.

The culture list is the part you have to check first

Working day arithmetic is only as correct as the calendar behind it, and the calendars come from culture definitions. The project lists the cultures it supports for working day and holiday calculations, and the named ones are United States en-US, United Kingdom en-GB, France fr-FR, Germany de-DE, Spain es-ES, Brazil pt-BR and Portugal pt-PT, with many more beyond the list. That list covers a spread of regions, but it stops there: if your country is not in the set, working day calculations will silently use whatever default the library applies rather than the holidays you expect. The project says so directly, with an invitation to contribute if your culture is missing, and it gives a naming rule for new holiday definitions, requiring that culture specific holidays be prefixed with the country name, with USA_IndependenceDay as the example. That convention is worth respecting if you contribute, because it is what keeps the country specific entries separable from the general ones in a file that holds all of them.

Exporting holidays and defining your own working days

The advanced section covers two extension points. The first is export. Rather than hard-coding a list of holidays into a scheduler, you can ask the library for a culture's holidays for a year and write them to a calendar format, and the example shows a format locator picking an exporter and then writing into a text writer:

csharp
var exporter = ExportHolidayFormatLocator.LocateByType(ExportType.OfficeHolidays);
exporter.Export(new WorkingDayCultureInfo("en-US"), 2024, textWriter);

The OfficeHolidays export type is the example, and the shape suggests a small set of named formats, with a locator that resolves a type to the exporter that handles it. The second extension point is custom working day rules. The project says to implement IWorkingDayCultureInfo to define custom working day rules for specific needs, which is the documented way to handle a country the library does not know about, or a company calendar that is not the standard one. A WorkingDayCultureInfo instance, as used in the export example, is the concrete type you work with, so the interface is the seam and that class is the default implementation.

The licence is described two different ways

Here is a small inconsistency worth resolving before you put this in a product. The README states that the project is licensed under the Apache License and points to the LICENSE file for the details, and the file is named LICENSE.md at the repository root. The licence field on the repository itself, however, says other, a custom licence that GitHub cannot classify, with the terms in the LICENSE file. Those two statements do not obviously agree, and the Apache License is one of the standard texts GitHub recognises, so if the repository were genuinely Apache-2.0 the field would say so. The acknowledgements note that the open source license provided came from JetBrains, which is a reference to the standard Apache 2.0 text, so the intent is probably the standard licence, but the licence field shown on the repository is what a compliance check will read. Read the LICENSE.md file and decide for yourself, particularly if you intend to redistribute the library inside a closed source product. The rest of the legal picture is simple: MIT and Apache-2.0 are both permissive, and neither obliges you to publish anything of your own.

Version 6 is a reset point, and the notes are in the repository

The release history is dense on the minor version numbers, with v6.0.1, v6.0.2 and v6.0.3 published in the first week of July 2026, and v6.0.3 dated 2026-07-09. Between those there is a gap back to the 6.0.0 release, and the repository root holds a file named v6.md, which is the kind of document a maintainer writes when a major version changes the shape of the API. The presence of that file in the root of the tree, next to the solution file and the CHANGELOG, means the migration notes for the version jump are in the repository rather than only in release descriptions. The repository also has a solution file with a DotSettings file beside it, a src directory and a tests directory, and the acknowledgements credit the build script assistance to a contributor using Nuke, which tells you the build is driven by a C# build tool rather than by a shell script. The last push was on 2026-09-28, so work continued after the 6.0.3 release rather than stopping at it.

Where this is the wrong tool

Two situations argue against pulling the library in. The first is a domain where working days do not follow the standard five day week and no public holiday calendar exists, such as a business with a rotating shift pattern, a six day operation or a region the culture list does not cover and that you have no intention of contributing. In that case the interface is still useful, because implementing IWorkingDayCultureInfo is the documented path, but you are writing the calendar yourself and the library is only the arithmetic around it. The second is a project that has already standardised on a date library or on its own calendar service, where adding a second source of holiday truth is a liability rather than a convenience. A library that owns working day and holiday knowledge is only a good idea if you want it to be the single source of that knowledge, and that decision has to be made at the level of the codebase, not per project. For everything else, the natural language difference and the time of day helpers are small enough to be worth having.

Contributing means following a specific naming rule

The contribution guidance is short and concrete, which is usually a good sign for a project with a working review process. The sequence is the standard one: fork the repository, create a feature branch, implement the feature or fix the bug, add or update the tests as necessary, and submit a pull request. There is a tests directory in the tree, and the instruction to add or update tests as necessary is a real requirement rather than a suggestion, which matters for a library where a mistake in a holiday table is invisible until somebody's payroll is wrong. The specific rule for holiday definitions is the country name prefix, with the example given for the United States. The repository also has a CODE_OF_CONDUCT file, a CHANGELOG, and a documentation site, with the README pointing at kspace.pt for the detailed documentation and a separate hosted demo at the Azure websites address. Two documentation locations, one being an old Azure deployment and the other a personal domain, is a small sign of a project with a long history and a few stale links.

Editorial conclusion

DateTimeExtensions suits a C# team that has to reason about working days and public holidays for several countries, and that would rather express that in one call than in a hand-rolled calendar service, and it suits a team that wants its own holiday rules via the IWorkingDayCultureInfo interface. It does not suit a project that needs country-specific calendars the library does not ship, since those have to be written by hand. Before adopting it, check the culture list for the regions you operate in, read the v6 migration notes in the repository root because the version jump from 5 to 6 exists, and settle the licence question by reading the LICENSE.md file, since the README names the Apache License while the repository licence field is a custom one GitHub cannot classify.

Frequently asked questions

How do I install DateTimeExtensions?

Install it as a NuGet package with the Install-Package DateTimeExtensions command in the Package Manager Console, or through the standard NuGet tooling. The package is also published as a pre-release on a MyGet feed.

How do I add working days to a date in C#?

Call AddWorkingDays on the date, for example DateTime.Now.AddWorkingDays(5). The calculation takes regional holidays into account for the culture it is applied to, and IsWorkingDay checks whether a given date is a working day.

How do I add holidays for a country DateTimeExtensions does not know?

Implement IWorkingDayCultureInfo to define custom working day rules, and prefix culture specific holiday definitions with the country name, following the convention the project uses, for example USA_IndependenceDay. The project also welcomes contributions of new holiday definitions.

Can I export the holiday definitions to a calendar format?

Yes. The example uses ExportHolidayFormatLocator.LocateByType with the OfficeHolidays export type, then calls Export on the result with a WorkingDayCultureInfo for the culture and a year, writing to a text writer.

Official sources

  1. Issues
  2. joaomatossilva/DateTimeExtensions on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/joaomatossilva-datetimeextensions.svg)](https://hysenlabs.com/projects/joaomatossilva-datetimeextensions)

Was this useful?