A collection of extension methods for DateTime data type in .Net
dotnet add package Wolfgang.Extensions.DateTimeNuGet Package: Wolfgang.Extensions.DateTime
This project is licensed under the MIT License. See the LICENSE file for details.
- GitHub Repository: https://github.com/Chris-Wolfgang/DateTime-Extensions
- API Documentation: https://Chris-Wolfgang.github.io/DateTime-Extensions/
- CHANGELOG: CHANGELOG.md
- Contributing Guide: CONTRIBUTING.md
- Formatting Guide: docs/README-FORMATTING.md
- DocFX Version Picker Troubleshooting: docs/DOCFX-VERSION-PICKER.md
- Release Workflow Setup: docs/RELEASE-WORKFLOW-SETUP.md
- Workflow Security: docs/WORKFLOW_SECURITY.md
using System; // DateTime, DayOfWeek
using Wolfgang.Extensions.DateTime;
var now = DateTime.UtcNow;
now.TruncateMilliseconds(); // strips fractional seconds
now.TruncateSeconds(); // rounds down to the minute
now.FirstOfMonth(); // β first day of this month, 00:00:00
now.EndOfMonth(); // β last tick of this month
now.FirstOfYear(); // β January 1 of this year, 00:00:00
now.EndOfYear(); // β last tick of this year
now.FirstOfWeek(); // β first day of the week (current culture)
now.FirstOfWeek(DayOfWeek.Monday); // β first day of the week (explicit)
now.EndOfWeek(); // β last tick of the week (current culture)
now.EndOfWeek(DayOfWeek.Monday); // β last tick of the week (explicit)
now.FirstOfQuarter(); // β first day of this calendar quarter
now.EndOfQuarter(); // β last tick of this calendar quarter
now.FirstOfHalf(); // β first day of this calendar half-year
now.EndOfHalf(); // β last tick of this calendar half-yearAll methods are pure: they return a new DateTime and never mutate the input. The
returned value preserves the original's DateTimeKind (Utc / Local / Unspecified)
unless explicitly noted.
The table below is a snapshot of the public API at the time of writing. For the authoritative list (kept in sync with source on every release), see the API documentation.
| Method | Description |
|---|---|
TruncateMilliseconds |
Removes fractional seconds, returning a DateTime accurate to the whole second. |
TruncateSeconds |
Strips seconds and smaller units, yielding a DateTime rounded down to the minute. |
FirstOfMonth |
Produces a new DateTime set to the first day of the month at midnight of the specified DateTime. |
EndOfMonth |
Computes the final tick of the month for the specified DateTime. |
FirstOfYear |
Creates a DateTime corresponding to January 1 of the same year as the specified DateTime. |
EndOfYear |
Returns the final tick of the year of the specified DateTime. |
FirstOfWeek() |
Uses the current cultureβs first day of the week to locate the weekβs starting DateTime. |
FirstOfWeek(DayOfWeek firstDayOfWeek) |
Uses the specified first day of the week to locate the weekβs starting DateTime. |
EndOfWeek() |
Uses the current cultureβs first day, calculates the final tick of the week. |
EndOfWeek(DayOfWeek firstDayOfWeek) |
Uses the specified first day, calculates the final tick of the week. |
FirstOfQuarter |
Returns the first day of the calendar quarter (Q1 Jan-Mar, Q2 Apr-Jun, Q3 Jul-Sep, Q4 Oct-Dec) at 00:00. |
EndOfQuarter |
Returns the final tick of the calendar quarter. Clamps at DateTime.MaxValue for Q4 of year 9999. |
FirstOfHalf |
Returns the first day of the calendar half-year (H1 Jan-Jun, H2 Jul-Dec) at 00:00. |
EndOfHalf |
Returns the final tick of the calendar half-year. Clamps at DateTime.MaxValue for H2 of year 9999. |
using System; // DateTime, DateTimeKind, DayOfWeek
using Wolfgang.Extensions.DateTime;
var ts = new DateTime(2026, 5, 26, 13, 45, 30, 123, DateTimeKind.Utc);
ts.TruncateMilliseconds(); // 2026-05-26 13:45:30.000 Utc
ts.TruncateSeconds(); // 2026-05-26 13:45:00.000 Utc
ts.FirstOfMonth(); // 2026-05-01 00:00:00.000 Utc
ts.EndOfMonth(); // 2026-05-31 23:59:59.9999999 Utc
ts.FirstOfYear(); // 2026-01-01 00:00:00.000 Utc
ts.EndOfYear(); // 2026-12-31 23:59:59.9999999 Utc
ts.FirstOfWeek(DayOfWeek.Sunday); // 2026-05-24 00:00:00.000 Utc
ts.EndOfWeek(DayOfWeek.Sunday); // 2026-05-30 23:59:59.9999999 Utc
ts.FirstOfQuarter(); // 2026-04-01 00:00:00.000 Utc (Q2: Apr-Jun)
ts.EndOfQuarter(); // 2026-06-30 23:59:59.9999999 Utc
ts.FirstOfHalf(); // 2026-01-01 00:00:00.000 Utc (H1: Jan-Jun)
ts.EndOfHalf(); // 2026-06-30 23:59:59.9999999 UtcBoundary safety: EndOfMonth / EndOfYear / EndOfWeek /
EndOfQuarter / EndOfHalf all clamp at DateTime.MaxValue instead
of throwing; FirstOfWeek clamps at DateTime.MinValue. See
CHANGELOG.md v1.2.0 for the month / year / week
boundary fixes and v1.3.0 for the quarter / half clamping added
with the new methods.
This library targets:
- .NET Framework: 4.6.2
- .NET Standard: 2.0
- .NET: 8.0, 10.0
See the NuGet package page for the authoritative per-TFM compatibility matrix.
This project enforces strict code quality standards through 8 specialized analyzers, an <TreatWarningsAsErrors>true</TreatWarningsAsErrors> Release gate, and custom async-first rules:
- Microsoft.CodeAnalysis.NetAnalyzers β Built-in .NET analyzers for correctness and performance
- Roslynator.Analyzers β Advanced refactoring and code quality rules
- AsyncFixer β Async/await best practices and anti-pattern detection
- Microsoft.VisualStudio.Threading.Analyzers β Thread safety and async patterns
- Microsoft.CodeAnalysis.BannedApiAnalyzers β Prevents usage of banned synchronous APIs (see
BannedSymbols.txt) - Meziantou.Analyzer β Comprehensive code quality rules
- SonarAnalyzer.CSharp β Industry-standard code analysis
- Microsoft.CodeAnalysis.PublicApiAnalyzers β Tracks the public API surface via
PublicAPI.Shipped.txt/PublicAPI.Unshipped.txt; surfaces additions/removals at compile time as a breaking-change review gate
- .NET 10.0 SDK β required for the modern build / test / pack flow used by CI
- Optional: PowerShell Core for formatting scripts
# Clone the repository
git clone https://github.com/Chris-Wolfgang/DateTime-Extensions.git
cd DateTime-Extensions
# Restore dependencies
dotnet restore
# Build the solution
dotnet build --configuration Release
# Run tests
dotnet test --configuration Release
# Run code formatting (PowerShell Core)
pwsh ./format.ps1This project uses .editorconfig and dotnet format:
# Format code
dotnet format
# Verify formatting (as CI does)
dotnet format --verify-no-changesSee docs/README-FORMATTING.md for detailed formatting guidelines.
This project uses DocFX to generate API documentation:
# Install DocFX (one-time setup)
dotnet tool install -g docfx
# Generate API metadata and build documentation
cd docfx_project
docfx metadata # Extract API metadata from source code
docfx build # Build HTML documentation
# Documentation is generated in the docs/ folder at the repository rootThe documentation is automatically built and deployed to GitHub Pages when changes are pushed to the main branch.
Local Preview:
# Serve documentation locally (with live reload)
cd docfx_project
docfx build --serve
# Open http://localhost:8080 in your browserDocumentation Structure:
docfx_project/- DocFX configuration and source filesdocs/- Generated HTML documentation (published to GitHub Pages)docfx_project/index.md- Main landing page contentdocfx_project/docs/- Additional documentation articlesdocfx_project/api/- Auto-generated API reference YAML files
Contributions are welcome! Please see CONTRIBUTING.md for:
- Code quality standards
- Build and test instructions
- Pull request guidelines
- Analyzer configuration details