< Summary

Information
Class: MyNet.Primitives.DateTimeExtensions
Assembly: MyNet.Primitives
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/Temporal/Extensions/DateTimeExtensions.cs
Tag: 323_28699572109
Line coverage
59%
Covered lines: 134
Uncovered lines: 93
Coverable lines: 227
Total lines: 974
Line coverage: 59%
Branch coverage
41%
Covered branches: 51
Total branches: 122
Branch coverage: 41.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
IsConsecutiveDays(...)100%210%
ToTimeZone(...)100%11100%
ToLocalTime(...)100%210%
ToUniversalTime(...)100%210%
ToDate(...)100%210%
ToTime(...)100%210%
ToPeriod(...)100%210%
ToInclusivePeriod(...)50%22100%
ToPeriod(...)100%11100%
IsBefore(...)100%11100%
IsAfter(...)100%11100%
IsBefore(...)100%210%
IsAfter(...)100%210%
Between(...)0%620%
Between(...)0%620%
Add(...)100%11100%
AddFluentTimeSpan(...)100%11100%
SubtractFluentTimeSpan(...)100%11100%
EndOfHour(...)100%210%
EndOfDay(...)100%11100%
EndOfDay(...)100%11100%
EndOfWeek(...)100%11100%
EndOfWeek(...)100%210%
EndOfMonth(...)100%11100%
EndOfMonth(...)100%210%
EndOfQuarter(...)100%11100%
EndOfQuarter(...)100%210%
EndOfYear(...)100%11100%
EndOfYear(...)100%210%
EndOfDecade(...)100%11100%
BeginningOfHour(...)100%210%
BeginningOfDay(...)100%11100%
BeginningOfDay(...)100%11100%
BeginningOfWeek(...)100%11100%
BeginningOfWeek(...)100%210%
BeginningOfMonth(...)100%11100%
BeginningOfMonth(...)100%210%
BeginningOfQuarter(...)100%11100%
BeginningOfQuarter(...)100%210%
BeginningOfYear(...)100%11100%
BeginningOfYear(...)100%210%
BeginningOfDecade(...)100%11100%
NextYear(...)100%22100%
PreviousYear(...)100%22100%
NextDay(...)100%11100%
PreviousDay(...)100%11100%
Next(...)100%22100%
Next(...)0%2040%
Previous(...)100%22100%
Previous(...)0%2040%
WeekAfter(...)100%11100%
WeekEarlier(...)100%11100%
IncreaseTime(...)100%210%
DecreaseTime(...)100%210%
At(...)100%210%
At(...)100%210%
At(...)100%11100%
At(...)100%11100%
At(...)100%11100%
SetHour(...)100%11100%
SetMinute(...)100%11100%
SetSecond(...)100%11100%
SetMillisecond(...)100%11100%
Midnight(...)100%11100%
Noon(...)100%11100%
SetDate(...)100%210%
SetDate(...)100%210%
SetDate(...)100%11100%
SetYear(...)100%11100%
SetMonth(...)100%11100%
SetDay(...)100%11100%
FirstDayOfQuarter(...)100%11100%
FirstDayOfMonth(...)100%11100%
LastDayOfQuarter(...)100%11100%
LastDayOfMonth(...)100%11100%
AddBusinessDays(...)100%88100%
SubtractBusinessDays(...)100%11100%
IsInFuture(...)100%11100%
IsInPast(...)100%11100%
Round(...)0%182130%
FirstDayOfWeek(...)75%44100%
FirstDayOfYear(...)100%11100%
LastDayOfWeek(...)100%11100%
LastDayOfYear(...)100%11100%
IsLastDayOfWeek(...)100%210%
IsFirstDayOfWeek(...)100%210%
IsWeekend(...)0%2040%
PreviousMonth(...)100%66100%
NextMonth(...)100%66100%
IsToday(...)0%620%
SameMilliSecond(...)0%620%
SameSecond(...)0%620%
SameMinute(...)0%620%
SameHour(...)0%620%
SameDay(...)100%11100%
SameWeek(...)0%620%
SameMonth(...)100%22100%
SameYear(...)100%11100%
SameDecade(...)100%210%
NumberOfDays(...)100%11100%
CompareWeek(...)100%11100%
NumberOfWeeks(...)100%11100%
CompareMonth(...)100%11100%
NumberOfMonths(...)100%11100%
CompareYear(...)100%11100%
NumberOfYears(...)100%11100%
DiscardDayTime(...)100%210%
DiscardTime(...)100%11100%
InRange(...)83.33%66100%
Normalize(...)50%22100%
Age(...)0%4260%
Range()0%240150%
OrMinValue(...)50%22100%
OrMaxValue(...)0%620%
MinOrNull(...)83.33%6685.71%
MaxOrNull(...)83.33%6685.71%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/Temporal/Extensions/DateTimeExtensions.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="DateTimeExtensions.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Collections.Generic;
 9using System.Globalization;
 10using System.Linq;
 11using MyNet.Primitives.Intervals;
 12using MyNet.Primitives.Temporal;
 13
 14#pragma warning disable IDE0130 // Namespace does not match folder structure
 15namespace MyNet.Primitives;
 16#pragma warning restore IDE0130 // Namespace does not match folder structure
 17
 18public static class DateTimeExtensions
 19{
 20    /// <summary>
 21    /// Determines if a collection of DateTime values represents consecutive days. The method first converts the input c
 22    /// </summary>
 23    /// <param name="dates">The collection of DateTime values to check.</param>
 24    /// <returns>True if the dates are consecutive; otherwise, false.</returns>
 25    public static bool IsConsecutiveDays(this IEnumerable<DateTime> dates)
 26    {
 027        var dateList = dates.ToList();
 028        return dateList.Order().Zip(dateList.Order().Skip(1), (a, b) => (a, b)).All(pair => (pair.b - pair.a).TotalDays.
 29    }
 30
 31    extension(DateTime dateTime)
 32    {
 33        /// <summary>
 34        /// Converts the specified <see cref="DateTime"/> to the given time zone.
 35        /// </summary>
 36        /// <param name="timeZoneInfo">The target time zone.</param>
 37        /// <returns>The converted <see cref="DateTime"/> in the specified time zone.</returns>
 1238        public DateTime ToTimeZone(TimeZoneInfo timeZoneInfo) => TimeZoneInfo.ConvertTime(dateTime, timeZoneInfo);
 39
 40        /// <summary>
 41        /// Converts the provided <see cref="DateTime"/> to local time and applies the given time-of-day offset.
 42        /// </summary>
 43        /// <param name="time">The time-of-day to add after converting to local time.</param>
 44        /// <returns>A <see cref="DateTime"/> adjusted to local time and the provided time-of-day.</returns>
 045        public DateTime ToLocalTime(TimeSpan time) => dateTime.ToLocalTime().BeginningOfDay().Add(time);
 46
 47        /// <summary>
 48        /// Converts the provided <see cref="DateTime"/> to local time, applies the given time-of-day and converts to UT
 49        /// </summary>
 50        /// <param name="time">The time-of-day to apply before converting to UTC.</param>
 51        /// <returns>A UTC <see cref="DateTime"/> instance.</returns>
 052        public DateTime ToUniversalTime(TimeSpan time) => dateTime.ToLocalTime().BeginningOfDay().Add(time).ToUniversalT
 53
 54        /// <summary>
 55        /// Returns the date component of the specified <see cref="DateTime"/> as a <see cref="DateOnly"/>.
 56        /// </summary>
 57        /// <returns>A <see cref="DateOnly"/> containing the date part.</returns>
 058        public DateOnly ToDate() => DateOnly.FromDateTime(dateTime);
 59
 60        /// <summary>
 61        /// Returns the time component of the specified <see cref="DateTime"/> as a <see cref="TimeOnly"/>.
 62        /// </summary>
 63        /// <returns>A <see cref="TimeOnly"/> containing the time-of-day part.</returns>
 064        public TimeOnly ToTime() => TimeOnly.FromDateTime(dateTime);
 65
 66        /// <summary>
 67        /// Creates a <see cref="Period"/> starting at this date/time and lasting the specified <see cref="FluentTimeSpa
 68        /// </summary>
 69        /// <param name="timeSpan">The duration to apply.</param>
 70        /// <returns>A <see cref="Period"/> representing the interval.</returns>
 071        public Period ToPeriod(FluentTimeSpan timeSpan) => new(dateTime, dateTime.AddFluentTimeSpan(timeSpan));
 72
 73        /// <summary>
 74        /// Creates an inclusive calendar-day <see cref="Period"/> (end-of-day for single-day ranges).
 75        /// </summary>
 76        /// <param name="end">The other end of the range.</param>
 77        /// <returns>A <see cref="Period"/> suitable for calendar date selection.</returns>
 78        public Period ToInclusivePeriod(DateTime end)
 79        {
 380            var (normalizedStart, normalizedEnd) = dateTime.Normalize(end);
 81
 382            return normalizedStart == normalizedEnd
 383                ? normalizedStart.ToPeriod(normalizedStart.AddDays(1).AddTicks(-1))
 384                : normalizedStart.ToPeriod(normalizedEnd);
 85        }
 86
 87        /// <summary>
 88        /// Creates a <see cref="Period"/> that spans between this date/time and another date/time.
 89        /// </summary>
 90        /// <param name="otherDateTime">The other end of the period.</param>
 91        /// <returns>A <see cref="Period"/> representing the interval between the two dates.</returns>
 992        public Period ToPeriod(DateTime otherDateTime) => new(dateTime.Min(otherDateTime), dateTime.Max(otherDateTime));
 93
 94        /// <summary>
 95        /// Determines whether the current date is strictly before the specified <see cref="DateTime"/> (converted to a 
 96        /// </summary>
 1897        public bool IsBefore(DateTime toCompareWith) => dateTime < toCompareWith;
 98
 99        /// <summary>
 100        /// Determines whether the current date is strictly after the specified <see cref="DateTime"/> (converted to a <
 101        /// </summary>
 12102        public bool IsAfter(DateTime toCompareWith) => dateTime > toCompareWith;
 103
 104        /// <summary>
 105        /// Determines whether the current date is strictly before the specified <see cref="DateOnly"/>.
 106        /// </summary>
 0107        public bool IsBefore(DateOnly toCompareWith) => dateTime.IsBefore(toCompareWith.ToDateTime(TimeOnly.MinValue));
 108
 109        /// <summary>
 110        /// Determines whether the current date is strictly after the specified <see cref="DateOnly"/>.
 111        /// </summary>
 0112        public bool IsAfter(DateOnly toCompareWith) => dateTime.IsAfter(toCompareWith.ToDateTime(TimeOnly.MinValue));
 113
 114        /// <summary>
 115        /// Calculates the absolute difference between this date/time and another date/time, returning the result as a <
 116        /// </summary>
 117        /// <param name="otherDateTime">The other date/time to compare with.</param>
 118        /// <returns>A <see cref="TimeSpan"/> representing the absolute difference between the two dates.</returns>
 0119        public TimeSpan Between(DateTime otherDateTime) => dateTime > otherDateTime ? dateTime - otherDateTime : otherDa
 120
 121        /// <summary>
 122        /// Calculates the absolute difference between this date/time and another date/time, returning the result as a <
 123        /// </summary>
 124        /// <param name="toCompareWith">The other date/time to compare with.</param>
 125        /// <returns>A <see cref="TimeSpan"/> representing the absolute difference between the two dates.</returns>
 0126        public TimeSpan Between(DateOnly toCompareWith) => dateTime > toCompareWith.ToDateTime(TimeOnly.MinValue) ? date
 127
 128        /// <summary>
 129        /// Adds a value expressed in the specified <see cref="TimeUnit"/> to the date.
 130        /// </summary>
 131        /// <param name="value">The amount to add.</param>
 132        /// <param name="timeUnitToGet">The unit of time for the amount.</param>
 133        /// <returns>The adjusted <see cref="DateTime"/>.</returns>
 6134        public DateTime Add(int value, TimeUnit timeUnitToGet) => dateTime.AddFluentTimeSpan(value.ToTimeSpan(timeUnitTo
 135
 136        /// <summary>
 137        /// Returns a new <see cref="DateTime"/> that adds the value of the specified <see cref="FluentTimeSpan"/> to th
 138        /// </summary>
 139        public DateTime AddFluentTimeSpan(FluentTimeSpan timeSpan)
 9140            => dateTime.AddMonths(timeSpan.Months)
 9141                .AddYears(timeSpan.Years)
 9142                .Add(timeSpan.TimeSpan);
 143
 144        /// <summary>
 145        /// Returns a new <see cref="DateTime"/> that subtracts the value of the specified <see cref="FluentTimeSpan"/> 
 146        /// </summary>
 147        public DateTime SubtractFluentTimeSpan(FluentTimeSpan timeSpan)
 3148            => dateTime.AddMonths(-timeSpan.Months)
 3149                .AddYears(-timeSpan.Years)
 3150                .Subtract(timeSpan.TimeSpan);
 151
 152        /// <summary>
 153        /// Returns the very end of the given hour (the last millisecond of the hour for the given <see cref="DateTime"/
 154        /// </summary>
 0155        public DateTime EndOfHour() => new(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, 59, 59, 999, date
 156
 157        /// <summary>
 158        /// Returns the very end of the given day (the last millisecond of the last hour for the given <see cref="DateTi
 159        /// </summary>
 57160        public DateTime EndOfDay() => new(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59, 999, dateTime.Kind);
 161
 162        /// <summary>
 163        /// Returns the timezone-adjusted very end of the given day (the last millisecond of the last hour for the given
 164        /// </summary>
 165        public DateTime EndOfDay(int timeZoneOffset)
 72166            => new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 23, 59, 59, 999, dateTime.Kind)
 72167                .AddHours(timeZoneOffset);
 168
 169        /// <summary>
 170        /// Returns the last day of the week changing the time to the very end of the day. Eg, 2011-12-24T06:40:20.005 =
 171        /// </summary>
 18172        public DateTime EndOfWeek(DayOfWeek? firstDayOfWeek = null) => dateTime.LastDayOfWeek(firstDayOfWeek).EndOfDay()
 173
 174        /// <summary>
 175        /// Returns the last day of the week changing the time to the very end of the day with timezone-adjusted. Eg, 20
 176        /// </summary>
 0177        public DateTime EndOfWeek(int timeZoneOffset, DayOfWeek? firstDayOfWeek = null) => dateTime.LastDayOfWeek(firstD
 178
 179        /// <summary>
 180        /// Returns the last day of the month changing the time to the very end of the day. Eg, 2011-12-24T06:40:20.005 
 181        /// </summary>
 9182        public DateTime EndOfMonth() => dateTime.LastDayOfMonth().EndOfDay();
 183
 184        /// <summary>
 185        /// Returns the last day of the month changing the time to the very end of the day with timezone-adjusted. Eg, 2
 186        /// </summary>
 0187        public DateTime EndOfMonth(int timeZoneOffset) => dateTime.LastDayOfMonth().EndOfDay(timeZoneOffset);
 188
 189        /// <summary>
 190        /// Returns the last day of the quarter changing the time to the very end of the day. Eg, 2011-12-24T06:40:20.00
 191        /// </summary>
 9192        public DateTime EndOfQuarter() => dateTime.LastDayOfQuarter().EndOfDay();
 193
 194        /// <summary>
 195        /// Returns the last day of the quarter changing the time to the very end of the day with timezone-adjusted. Eg,
 196        /// </summary>
 0197        public DateTime EndOfQuarter(int timeZoneOffset) => dateTime.LastDayOfQuarter().EndOfDay(timeZoneOffset);
 198
 199        /// <summary>
 200        /// Returns the last day of the year changing the time to the very end of the day. Eg, 2011-12-24T06:40:20.005 =
 201        /// </summary>
 18202        public DateTime EndOfYear() => dateTime.LastDayOfYear().EndOfDay();
 203
 204        /// <summary>
 205        /// Returns the last day of the year changing the time to the very end of the day with timezone-adjusted. Eg, 20
 206        /// </summary>
 0207        public DateTime EndOfYear(int timeZoneOffset) => dateTime.LastDayOfYear().EndOfDay(timeZoneOffset);
 208
 209        /// <summary>
 210        /// Returns the last day of the year changing the time to the very end of the day. Eg, 2011-12-24T06:40:20.005 =
 211        /// </summary>
 9212        public DateTime EndOfDecade() => dateTime.SetYear(dateTime.Year - (dateTime.Year % 10) + 9).EndOfYear();
 213
 214        /// <summary>
 215        /// Returns the Start of the given day (the first millisecond of the given <see cref="DateTime"/>).
 216        /// </summary>
 0217        public DateTime BeginningOfHour() => new(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, 0, 0, 0, da
 218
 219        /// <summary>
 220        /// Returns the Start of the given day (the first millisecond of the given <see cref="DateTime"/>).
 221        /// </summary>
 108222        public DateTime BeginningOfDay() => new(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, 0, dateTime.Kind);
 223
 224        /// <summary>
 225        /// Returns the timezone-adjusted Start of the given day (the first millisecond of the given <see cref="DateTime
 226        /// </summary>
 227        public DateTime BeginningOfDay(int timezoneOffset)
 72228            => new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, 0, dateTime.Kind)
 72229                .AddHours(timezoneOffset);
 230
 231        /// <summary>
 232        /// Returns the Start day of the week changing the time to the very start of the day. Eg, 2011-12-24T06:40:20.00
 233        /// </summary>
 18234        public DateTime BeginningOfWeek(DayOfWeek? firstDayOfWeek = null) => dateTime.FirstDayOfWeek(firstDayOfWeek).Beg
 235
 236        /// <summary>
 237        /// Returns the Start day of the week changing the time to the very start of the day with timezone-adjusted. Eg,
 238        /// </summary>
 0239        public DateTime BeginningOfWeek(int timezoneOffset, DayOfWeek? firstDayOfWeek = null) => dateTime.FirstDayOfWeek
 240
 241        /// <summary>
 242        /// Returns the Start day of the month changing the time to the very start of the day. Eg, 2011-12-24T06:40:20.0
 243        /// </summary>
 9244        public DateTime BeginningOfMonth() => dateTime.FirstDayOfMonth().BeginningOfDay();
 245
 246        /// <summary>
 247        /// Returns the Start day of the month changing the time to the very start of the day with timezone-adjusted. Eg
 248        /// </summary>
 0249        public DateTime BeginningOfMonth(int timezoneOffset) => dateTime.FirstDayOfMonth().BeginningOfDay(timezoneOffset
 250
 251        /// <summary>
 252        /// Returns the Start day of the quarter changing the time to the very start of the day. Eg, 2011-12-24T06:40:20
 253        /// </summary>
 9254        public DateTime BeginningOfQuarter() => dateTime.FirstDayOfQuarter().BeginningOfDay();
 255
 256        /// <summary>
 257        /// Returns the Start day of the quarter changing the time to the very start of the day with timezone-adjusted. 
 258        /// </summary>
 0259        public DateTime BeginningOfQuarter(int timezoneOffset) => dateTime.FirstDayOfQuarter().BeginningOfDay(timezoneOf
 260
 261        /// <summary>
 262        /// Returns the Start day of the year changing the time to the very start of the day. Eg, 2011-12-24T06:40:20.00
 263        /// </summary>
 18264        public DateTime BeginningOfYear() => dateTime.FirstDayOfYear().BeginningOfDay();
 265
 266        /// <summary>
 267        /// Returns the Start day of the year changing the time to the very start of the day with timezone-adjusted. Eg,
 268        /// </summary>
 0269        public DateTime BeginningOfYear(int timezoneOffset) => dateTime.FirstDayOfYear().BeginningOfDay(timezoneOffset);
 270
 271        /// <summary>
 272        /// Returns the Start day of the year changing the time to the very start of the day with timezone-adjusted. Eg,
 273        /// </summary>
 9274        public DateTime BeginningOfDecade() => dateTime.SetYear(dateTime.Year - (dateTime.Year % 10)).BeginningOfYear();
 275
 276        /// <summary>
 277        /// Returns the same date (same Day, Month, Hour, Minute, Second etc.) in the next calendar year.
 278        /// If that day does not exist in next year in same month, number of missing days is added to the last day in sa
 279        /// </summary>
 280        public DateTime NextYear()
 281        {
 6282            var nextYear = dateTime.Year + 1;
 6283            var numberOfDaysInSameMonthNextYear = DateTime.DaysInMonth(nextYear, dateTime.Month);
 284
 6285            if (numberOfDaysInSameMonthNextYear >= dateTime.Day)
 3286                return new(nextYear, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, date
 287
 3288            var differenceInDays = dateTime.Day - numberOfDaysInSameMonthNextYear;
 3289            var dateTime1 = new DateTime(nextYear, dateTime.Month, numberOfDaysInSameMonthNextYear, dateTime.Hour, dateT
 3290            return dateTime1 + differenceInDays.Days();
 291        }
 292
 293        /// <summary>
 294        /// Returns the same date (same Day, Month, Hour, Minute, Second etc.) in the previous calendar year.
 295        /// If that day does not exist in previous year in same month, number of missing days is added to the last day i
 296        /// </summary>
 297        public DateTime PreviousYear()
 298        {
 6299            var previousYear = dateTime.Year - 1;
 6300            var numberOfDaysInSameMonthPreviousYear = DateTime.DaysInMonth(previousYear, dateTime.Month);
 301
 6302            if (numberOfDaysInSameMonthPreviousYear >= dateTime.Day)
 3303                return new(previousYear, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, 
 304
 3305            var differenceInDays = dateTime.Day - numberOfDaysInSameMonthPreviousYear;
 3306            var dateTime1 = new DateTime(previousYear, dateTime.Month, numberOfDaysInSameMonthPreviousYear, dateTime.Hou
 3307            return dateTime1 + differenceInDays.Days();
 308        }
 309
 310        /// <summary>
 311        /// Returns <see cref="DateTime"/> increased by 24 hours ie Next Day.
 312        /// </summary>
 45313        public DateTime NextDay() => dateTime + 1.Days();
 314
 315        /// <summary>
 316        /// Returns <see cref="DateTime"/> decreased by 24h period ie Previous Day.
 317        /// </summary>
 45318        public DateTime PreviousDay() => dateTime - 1.Days();
 319
 320        /// <summary>
 321        /// Returns first next occurrence of specified <see cref="DayOfWeek"/>.
 322        /// </summary>
 323        public DateTime Next(DayOfWeek day)
 324        {
 325            do
 326            {
 42327                dateTime = dateTime.NextDay();
 328            }
 42329            while (dateTime.DayOfWeek != day);
 330
 6331            return dateTime;
 332        }
 333
 334        /// <summary>
 335        /// Returns first next occurrence of specified <see cref="DayOfWeek"/>.
 336        /// </summary>
 337        public DateTime Next(int day, int month)
 338        {
 339            do
 340            {
 0341                dateTime = dateTime.NextDay();
 342            }
 0343            while (dateTime.Month != month || dateTime.Day != day);
 344
 0345            return dateTime;
 346        }
 347
 348        /// <summary>
 349        /// Returns first next occurrence of specified <see cref="DayOfWeek"/>.
 350        /// </summary>
 351        public DateTime Previous(DayOfWeek day)
 352        {
 353            do
 354            {
 42355                dateTime = dateTime.PreviousDay();
 356            }
 42357            while (dateTime.DayOfWeek != day);
 358
 6359            return dateTime;
 360        }
 361
 362        /// <summary>
 363        /// Returns first next occurrence of specified <see cref="DayOfWeek"/>.
 364        /// </summary>
 365        public DateTime Previous(int day, int month)
 366        {
 367            do
 368            {
 0369                dateTime = dateTime.PreviousDay();
 370            }
 0371            while (dateTime.Month != month || dateTime.Day != day);
 372
 0373            return dateTime;
 374        }
 375
 376        /// <summary>
 377        /// Increases supplied <see cref="DateTime"/> for 7 days ie returns the Next Week.
 378        /// </summary>
 3379        public DateTime WeekAfter() => dateTime + 1.Weeks();
 380
 381        /// <summary>
 382        /// Decreases supplied <see cref="DateTime"/> for 7 days ie returns the Previous Week.
 383        /// </summary>
 3384        public DateTime WeekEarlier() => dateTime - 1.Weeks();
 385
 386        /// <summary>
 387        /// Increases the <see cref="DateTime"/> object with given <see cref="TimeSpan"/> value.
 388        /// </summary>
 0389        public DateTime IncreaseTime(TimeSpan toAdd) => dateTime + toAdd;
 390
 391        /// <summary>
 392        /// Decreases the <see cref="DateTime"/> object with given <see cref="TimeSpan"/> value.
 393        /// </summary>
 0394        public DateTime DecreaseTime(TimeSpan toSubtract) => dateTime - toSubtract;
 395
 396        /// <summary>
 397        /// Returns the original <see cref="DateTime"/> with Hour part changed to supplied hour parameter.
 398        /// </summary>
 0399        public DateTime At(TimeOnly time) => new(dateTime.Year, dateTime.Month, dateTime.Day, time.Hour, time.Minute, ti
 400
 401        /// <summary>
 402        /// Returns the original <see cref="DateTime"/> with Hour part changed to supplied hour parameter.
 403        /// </summary>
 0404        public DateTime At(TimeSpan time) => new(dateTime.Year, dateTime.Month, dateTime.Day, time.Hours, time.Minutes, 
 405
 406        /// <summary>
 407        /// Returns the original <see cref="DateTime"/> with Hour and Minute parts changed to supplied hour and minute p
 408        /// </summary>
 18409        public DateTime At(int hour, int minute) => new(dateTime.Year, dateTime.Month, dateTime.Day, hour, minute, 0, 0,
 410
 411        /// <summary>
 412        /// Returns the original <see cref="DateTime"/> with Hour, Minute and Second parts changed to supplied hour, min
 413        /// </summary>
 18414        public DateTime At(int hour, int minute, int second) => new(dateTime.Year, dateTime.Month, dateTime.Day, hour, m
 415
 416        /// <summary>
 417        /// Returns the original <see cref="DateTime"/> with Hour, Minute, Second and Millisecond parts changed to suppl
 418        /// </summary>
 21419        public DateTime At(int hour, int minute, int second, int millisecond) => new(dateTime.Year, dateTime.Month, date
 420
 421        /// <summary>
 422        /// Returns <see cref="DateTime"/> with changed Hour part.
 423        /// </summary>
 87424        public DateTime SetHour(int hour) => new(dateTime.Year, dateTime.Month, dateTime.Day, hour, dateTime.Minute, dat
 425
 426        /// <summary>
 427        /// Returns <see cref="DateTime"/> with changed Minute part.
 428        /// </summary>
 72429        public DateTime SetMinute(int minute) => new(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, minute,
 430
 431        /// <summary>
 432        /// Returns <see cref="DateTime"/> with changed Second part.
 433        /// </summary>
 72434        public DateTime SetSecond(int second) => new(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTim
 435
 436        /// <summary>
 437        /// Returns <see cref="DateTime"/> with changed Millisecond part.
 438        /// </summary>
 72439        public DateTime SetMillisecond(int millisecond) => new(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hou
 440
 441        /// <summary>
 442        /// Returns original <see cref="DateTime"/> value with time part set to midnight (alias for <see cref="Beginning
 443        /// </summary>
 3444        public DateTime Midnight() => dateTime.BeginningOfDay();
 445
 446        /// <summary>
 447        /// Returns original <see cref="DateTime"/> value with time part set to Noon (12:00:00h).
 448        /// </summary>
 449        /// <returns>A <see cref="DateTime"/> value with time part set to Noon (12:00:00h).</returns>
 3450        public DateTime Noon() => dateTime.At(12, 0, 0, 0);
 451
 452        /// <summary>
 453        /// Returns <see cref="DateTime"/> with changed Year part.
 454        /// </summary>
 0455        public DateTime SetDate(int year) => new(year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dat
 456
 457        /// <summary>
 458        /// Returns <see cref="DateTime"/> with changed Year and Month part.
 459        /// </summary>
 0460        public DateTime SetDate(int year, int month) => new(year, month, dateTime.Day, dateTime.Hour, dateTime.Minute, d
 461
 462        /// <summary>
 463        /// Returns <see cref="DateTime"/> with changed Year, Month and Day part.
 464        /// </summary>
 108465        public DateTime SetDate(int year, int month, int day) => new(year, month, day, dateTime.Hour, dateTime.Minute, d
 466
 467        /// <summary>
 468        /// Returns <see cref="DateTime"/> with changed Year part.
 469        /// </summary>
 18470        public DateTime SetYear(int year) => new(year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dat
 471
 472        /// <summary>
 473        /// Returns <see cref="DateTime"/> with changed Month part.
 474        /// </summary>
 21475        public DateTime SetMonth(int month) => new(dateTime.Year, month, dateTime.Day, dateTime.Hour, dateTime.Minute, d
 476
 477        /// <summary>
 478        /// Returns <see cref="DateTime"/> with changed Day part.
 479        /// </summary>
 69480        public DateTime SetDay(int day) => new(dateTime.Year, dateTime.Month, day, dateTime.Hour, dateTime.Minute, dateT
 481
 482        /// <summary>
 483        /// Sets the day of the <see cref="DateTime"/> to the first day in that calendar quarter.
 484        /// credit to http://www.devcurry.com/2009/05/find-first-and-last-day-of-current.html.
 485        /// </summary>
 486        /// <returns>given <see cref="DateTime"/> with the day part set to the first day in the quarter.</returns>
 487        public DateTime FirstDayOfQuarter()
 488        {
 21489            var currentQuarter = ((dateTime.Month - 1) / 3) + 1;
 21490            var firstDay = new DateTime(dateTime.Year, (3 * currentQuarter) - 2, 1, 0, 0, 0, dateTime.Kind);
 491
 21492            return dateTime.SetDate(firstDay.Year, firstDay.Month, firstDay.Day);
 493        }
 494
 495        /// <summary>
 496        /// Sets the day of the <see cref="DateTime"/> to the first day in that month.
 497        /// </summary>
 498        /// <returns>given <see cref="DateTime"/> with the day part set to the first day in that month.</returns>
 12499        public DateTime FirstDayOfMonth() => dateTime.SetDay(1);
 500
 501        /// <summary>
 502        /// Sets the day of the <see cref="DateTime"/> to the last day in that calendar quarter.
 503        /// credit to http://www.devcurry.com/2009/05/find-first-and-last-day-of-current.html.
 504        /// </summary>
 505        /// <returns>given <see cref="DateTime"/> with the day part set to the last day in the quarter.</returns>
 506        public DateTime LastDayOfQuarter()
 507        {
 21508            var currentQuarter = ((dateTime.Month - 1) / 3) + 1;
 21509            var firstDay = dateTime.SetDate(dateTime.Year, (3 * currentQuarter) - 2, 1);
 21510            return firstDay.SetMonth(firstDay.Month + 2).LastDayOfMonth();
 511        }
 512
 513        /// <summary>
 514        /// Sets the day of the <see cref="DateTime"/> to the last day in that month.
 515        /// </summary>
 516        /// <returns>given <see cref="DateTime"/> with the day part set to the last day in that month.</returns>
 45517        public DateTime LastDayOfMonth() => dateTime.SetDay(DateTime.DaysInMonth(dateTime.Year, dateTime.Month));
 518
 519        /// <summary>
 520        /// Adds the given number of business days to the <see cref="DateTime"/>.
 521        /// </summary>
 522        /// <param name="days">Number of business days to be added.</param>
 523        /// <returns>A <see cref="DateTime"/> increased by a given number of business days.</returns>
 524        public DateTime AddBusinessDays(int days)
 525        {
 12526            var sign = Math.Sign(days);
 12527            var unsignedDays = Math.Abs(days);
 72528            for (var i = 0; i < unsignedDays; i++)
 529            {
 530                do
 531                {
 48532                    dateTime = dateTime.AddDays(sign);
 533                }
 48534                while (dateTime.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday);
 535            }
 536
 12537            return dateTime;
 538        }
 539
 540        /// <summary>
 541        /// Subtracts the given number of business days to the <see cref="DateTime"/>.
 542        /// </summary>
 543        /// <param name="days">Number of business days to be subtracted.</param>
 544        /// <returns>A <see cref="DateTime"/> increased by a given number of business days.</returns>
 6545        public DateTime SubtractBusinessDays(int days) => dateTime.AddBusinessDays(-days);
 546
 547        /// <summary>
 548        /// Determine if a <see cref="DateTime"/> is in the future.
 549        /// </summary>
 550        /// <returns><c>true</c> if <paramref name="dateTime"/> is in the future; otherwise <c>false</c>.</returns>
 9551        public bool IsInFuture() => dateTime.ToUniversalTime() > DateTime.UtcNow;
 552
 553        /// <summary>
 554        /// Determine if a <see cref="DateTime"/> is in the past.
 555        /// </summary>
 556        /// <returns><c>true</c> if <paramref name="dateTime"/> is in the past; otherwise <c>false</c>.</returns>
 6557        public bool IsInPast() => dateTime.ToUniversalTime() < DateTime.UtcNow;
 558
 559        /// <summary>
 560        /// Rounds <paramref name="dateTime"/> to the nearest <see cref="RoundTo"/>.
 561        /// </summary>
 562        /// <returns>The rounded <see cref="DateTime"/>.</returns>
 563        public DateTime Round(RoundTo rt)
 564        {
 565            DateTime rounded;
 566
 567            switch (rt)
 568            {
 569                case RoundTo.Second:
 570                    {
 0571                        rounded = new(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateT
 0572                        if (dateTime.Millisecond >= 500)
 573                        {
 0574                            rounded = rounded.AddSeconds(1);
 575                        }
 576
 0577                        break;
 578                    }
 579
 580                case RoundTo.Minute:
 581                    {
 0582                        rounded = new(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, 0, da
 0583                        if (dateTime.Second >= 30)
 584                        {
 0585                            rounded = rounded.AddMinutes(1);
 586                        }
 587
 0588                        break;
 589                    }
 590
 591                case RoundTo.Hour:
 592                    {
 0593                        rounded = new(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, 0, 0, dateTime.Kind);
 0594                        if (dateTime.Minute >= 30)
 595                        {
 0596                            rounded = rounded.AddHours(1);
 597                        }
 598
 0599                        break;
 600                    }
 601
 602                case RoundTo.Day:
 603                    {
 0604                        rounded = new(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, dateTime.Kind);
 0605                        if (dateTime.Hour >= 12)
 606                        {
 0607                            rounded = rounded.AddDays(1);
 608                        }
 609
 0610                        break;
 611                    }
 612
 613                default:
 614                    {
 0615                        throw new ArgumentOutOfRangeException(nameof(rt));
 616                    }
 617            }
 618
 0619            return rounded;
 620        }
 621
 622        /// <summary>
 623        /// Returns a DateTime adjusted to the beginning of the week.
 624        /// </summary>
 625        /// <returns>A DateTime instance adjusted to the beginning of the current week.</returns>
 626        /// <remarks>the beginning of the week is controlled by the current Culture.</remarks>
 627        public DateTime FirstDayOfWeek(DayOfWeek? firstDayOfWeek = null)
 628        {
 87629            var currentCulture = CultureInfo.CurrentCulture;
 87630            var firstDay = firstDayOfWeek ?? currentCulture.DateTimeFormat.FirstDayOfWeek;
 87631            var offset = dateTime.DayOfWeek < firstDay ? 7 : 0;
 87632            var numberOfDaysSinceBeginningOfTheWeek = dateTime.DayOfWeek + offset - firstDay;
 633
 87634            return dateTime.AddDays(-numberOfDaysSinceBeginningOfTheWeek);
 635        }
 636
 637        /// <summary>
 638        /// Returns the first day of the year keeping the time component intact. Eg, 2011-02-04T06:40:20.005 => 2011-01-
 639        /// </summary>
 27640        public DateTime FirstDayOfYear() => dateTime.SetDate(dateTime.Year, 1, 1);
 641
 642        /// <summary>
 643        /// Returns the last day of the week keeping the time component intact. Eg, 2011-12-24T06:40:20.005 => 2011-12-2
 644        /// </summary>
 27645        public DateTime LastDayOfWeek(DayOfWeek? firstDayOfWeek = null) => dateTime.FirstDayOfWeek(firstDayOfWeek).AddDa
 646
 647        /// <summary>
 648        /// Returns the last day of the year keeping the time component intact. Eg, 2011-12-24T06:40:20.005 => 2011-12-3
 649        /// </summary>
 27650        public DateTime LastDayOfYear() => dateTime.SetDate(dateTime.Year, 12, 31);
 651
 652        /// <summary>
 653        /// Determines whether the <see cref="DateTime"/> is the last day of the week. The beginning of the week is dete
 654        /// </summary>
 655        /// <param name="firstDayOfWeek">The first day of the week. If null, the current culture's first day of the week
 656        /// <returns><c>true</c> if the <see cref="DateTime"/> is the last day of the week; otherwise, <c>false</c>.</re
 0657        public bool IsLastDayOfWeek(DayOfWeek? firstDayOfWeek = null) => dateTime.DayOfWeek == dateTime.LastDayOfWeek(fi
 658
 659        /// <summary>
 660        /// Determines whether the <see cref="DateTime"/> is the first day of the week. The beginning of the week is det
 661        /// </summary>
 662        /// <param name="firstDayOfWeek">The first day of the week. If null, the current culture's first day of the week
 663        /// <returns><c>true</c> if the <see cref="DateTime"/> is the first day of the week; otherwise, <c>false</c>.</r
 0664        public bool IsFirstDayOfWeek(DayOfWeek? firstDayOfWeek = null) => dateTime.DayOfWeek == dateTime.FirstDayOfWeek(
 665
 666        /// <summary>
 667        /// Determines whether the <see cref="DateTime"/> falls on a weekend day (Saturday or Sunday).
 668        /// </summary>
 669        /// <returns><c>true</c> if the <see cref="DateTime"/> is a weekend day; otherwise, <c>false</c>.</returns>
 0670        public bool IsWeekend() => dateTime.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday;
 671
 672        /// <summary>
 673        /// Returns the previous month keeping the time component intact. Eg, 2010-01-20T06:40:20.005 => 2009-12-20T06:4
 674        /// If the previous month doesn't have that many days the last day of the previous month is used. Eg, 2009-03-31
 675        /// </summary>
 676        public DateTime PreviousMonth()
 677        {
 6678            var year = dateTime.Month == 1 ? dateTime.Year - 1 : dateTime.Year;
 679
 6680            var month = dateTime.Month == 1 ? 12 : dateTime.Month - 1;
 681
 6682            var firstDayOfPreviousMonth = dateTime.SetDate(year, month, 1);
 683
 6684            var lastDayOfPreviousMonth = firstDayOfPreviousMonth.LastDayOfMonth().Day;
 685
 6686            var day = dateTime.Day > lastDayOfPreviousMonth ? lastDayOfPreviousMonth : dateTime.Day;
 687
 6688            return firstDayOfPreviousMonth.SetDay(day);
 689        }
 690
 691        /// <summary>
 692        /// Returns the next month keeping the time component intact. Eg, 2012-12-05T06:40:20.005 => 2013-01-05T06:40:20
 693        /// If the next month doesn't have that many days the last day of the next month is used. Eg, 2013-01-31T06:40:2
 694        /// </summary>
 695        public DateTime NextMonth()
 696        {
 6697            var year = dateTime.Month == 12 ? dateTime.Year + 1 : dateTime.Year;
 698
 6699            var month = dateTime.Month == 12 ? 1 : dateTime.Month + 1;
 700
 6701            var firstDayOfNextMonth = dateTime.SetDate(year, month, 1);
 702
 6703            var lastDayOfPreviousMonth = firstDayOfNextMonth.LastDayOfMonth().Day;
 704
 6705            var day = dateTime.Day > lastDayOfPreviousMonth ? lastDayOfPreviousMonth : dateTime.Day;
 706
 6707            return firstDayOfNextMonth.SetDay(day);
 708        }
 709
 710        /// <summary>
 711        /// Determines whether the specified <see cref="DateTime"/> value is in the same day (day + month + year) as cur
 712        /// </summary>
 713        public bool IsToday()
 0714            => dateTime.Kind switch
 0715            {
 0716                DateTimeKind.Local => dateTime.SameDay(DateTime.Now),
 0717                _ => dateTime.SameDay(DateTime.UtcNow)
 0718            };
 719
 720        /// <summary>
 721        /// Determines whether the specified <see cref="DateTime"/> value is exactly the same millisecond (millisecond +
 722        /// </summary>
 723        /// <param name="date">The date to compare with.</param>
 724        /// <returns><c>true</c> if the specified date is exactly the same millisecond as the current date; otherwise, <
 0725        public bool SameMilliSecond(DateTime date) => dateTime.SameSecond(date) && dateTime.Millisecond == date.Millisec
 726
 727        /// <summary>
 728        /// Determines whether the specified <see cref="DateTime"/> value is exactly the same second (second + minute + 
 729        /// </summary>
 730        /// <param name="date">The date to compare with.</param>
 731        /// <returns><c>true</c> if the specified date is exactly the same second as the current date; otherwise, <c>fal
 0732        public bool SameSecond(DateTime date) => dateTime.SameMinute(date) && dateTime.Second == date.Second;
 733
 734        /// <summary>
 735        /// Determines whether the specified <see cref="DateTime"/> value is exactly the same minute (minute + hour + da
 736        /// </summary>
 737        /// <param name="date">The date to compare with.</param>
 738        /// <returns><c>true</c> if the specified date is exactly the same minute as the current date; otherwise, <c>fal
 0739        public bool SameMinute(DateTime date) => dateTime.SameHour(date) && dateTime.Minute == date.Minute;
 740
 741        /// <summary>
 742        /// Determines whether the specified <see cref="DateTime"/> value is exactly the same hour (hour + day + month +
 743        /// </summary>
 744        /// <param name="date">The date to compare with.</param>
 745        /// <returns><c>true</c> if the specified date is exactly the same hour as the current date; otherwise, <c>false
 0746        public bool SameHour(DateTime date) => dateTime.SameDay(date) && dateTime.Hour == date.Hour;
 747
 748        /// <summary>
 749        /// Determines whether the specified <see cref="DateTime"/> value is exactly the same day (day + month + year) t
 750        /// </summary>
 751        /// <param name="date">Value to compare with.</param>
 752        /// <returns>
 753        ///     <c>true</c> if the specified date is exactly the same year then current; otherwise, <c>false</c>.
 754        /// </returns>
 51755        public bool SameDay(DateTime date) => dateTime.Date == date.Date;
 756
 757        /// <summary>
 758        /// Determines whether the specified <see cref="DateTime"/> value is exactly the same month (month + year) then 
 759        /// </summary>
 760        /// <param name="date">Value to compare with.</param>
 761        /// <returns>
 762        ///     <c>true</c> if the specified date is exactly the same month and year then current; otherwise, <c>false</
 763        /// </returns>
 0764        public bool SameWeek(DateTime date) => date.IsAfter(dateTime.BeginningOfWeek()) && date < dateTime.EndOfWeek();
 765
 766        /// <summary>
 767        /// Determines whether the specified <see cref="DateTime"/> value is exactly the same month (month + year) then 
 768        /// </summary>
 769        /// <param name="date">Value to compare with.</param>
 770        /// <returns>
 771        ///     <c>true</c> if the specified date is exactly the same month and year then current; otherwise, <c>false</
 772        /// </returns>
 18773        public bool SameMonth(DateTime date) => dateTime.Month == date.Month && dateTime.Year == date.Year;
 774
 775        /// <summary>
 776        /// Determines whether the specified <see cref="DateTime"/> value is exactly the same year then current. Eg, 201
 777        /// </summary>
 778        /// <param name="date">Value to compare with.</param>
 779        /// <returns>
 780        ///     <c>true</c> if the specified date is exactly the same date then current; otherwise, <c>false</c>.
 781        /// </returns>
 18782        public bool SameYear(DateTime date) => dateTime.Year == date.Year;
 783
 784        /// <summary>
 785        /// Determines whether the specified <see cref="DateTime"/> value is exactly the same year then current. Eg, 201
 786        /// </summary>
 787        /// <param name="date">Value to compare with.</param>
 788        /// <returns>
 789        ///     <c>true</c> if the specified date is exactly the same date then current; otherwise, <c>false</c>.
 790        /// </returns>
 0791        public bool SameDecade(DateTime date) => dateTime.BeginningOfDecade() == date.BeginningOfDecade();
 792
 793        /// <summary>
 794        /// Compare two dates and return difference of days (positive or negative).
 795        /// </summary>
 796        /// <param name="dateTo">The date to compare with.</param>
 797        /// <returns>The difference in days between the current date and the specified date.</returns>
 9798        public int NumberOfDays(DateTime dateTo) => Math.Abs((dateTime - dateTo).Days);
 799
 800        /// <summary>
 801        /// Compare two dates and return difference of week (positive or negative).
 802        /// </summary>
 803        /// <param name="dateTo">The date to compare with.</param>
 804        /// <returns>The difference in weeks between the current date and the specified date.</returns>
 805        public int CompareWeek(DateTime dateTo)
 806        {
 24807            var ts = dateTo.Subtract(dateTime);
 24808            return ts.Days / 7;
 809        }
 810
 811        /// <summary>
 812        /// Compare two dates and return difference of week.
 813        /// </summary>
 814        /// <param name="dt2">The date to compare with.</param>
 815        /// <returns>The difference in weeks between the current date and the specified date.</returns>
 12816        public int NumberOfWeeks(DateTime dt2) => Math.Abs(dateTime.CompareWeek(dt2));
 817
 818        /// <summary>
 819        /// Compare two dates and return difference of month (positive or negative).
 820        /// </summary>
 24821        public int CompareMonth(DateTime dt2) => ((dt2.Year - dateTime.Year) * 12) + (dt2.Month - dateTime.Month);
 822
 823        /// <summary>
 824        /// Compare two dates and return difference of month.
 825        /// </summary>
 12826        public int NumberOfMonths(DateTime dt2) => Math.Abs(dateTime.CompareMonth(dt2));
 827
 828        /// <summary>
 829        /// Compare two dates and return difference of month (positive or negative).
 830        /// </summary>
 24831        public int CompareYear(DateTime dt2) => dt2.Year - dateTime.Year;
 832
 833        /// <summary>
 834        /// Compare two dates and return difference of month.
 835        /// </summary>
 12836        public int NumberOfYears(DateTime dt2) => Math.Abs(dateTime.CompareYear(dt2));
 837
 838        /// <summary>
 839        /// Returns the date with day-of-month discarded (keeps month and year) â€” useful for monthly calculations.
 840        /// </summary>
 841        /// <returns>A <see cref="DateTime"/> set to the first day of the month at midnight.</returns>
 0842        public DateTime DiscardDayTime() => new(dateTime.Year, dateTime.Month, 1, 0, 0, 0, dateTime.Kind);
 843
 844        /// <summary>
 845        /// Returns the date with the time portion discarded (time set to midnight).
 846        /// </summary>
 847        /// <returns>A <see cref="DateTime"/> with time portion set to 00:00:00.</returns>
 24848        public DateTime DiscardTime() => dateTime.Date;
 849
 850        /// <summary>
 851        /// Determines whether the date lies within the inclusive range defined by start and end.
 852        /// </summary>
 853        /// <param name="start">Range start.</param>
 854        /// <param name="end">Range end.</param>
 855        /// <param name="discardTime">If <c>true</c> compare only date parts for equality to boundaries.</param>
 856        /// <returns><c>true</c> when the date is within the range; otherwise <c>false</c>.</returns>
 21857        public bool InRange(DateTime start, DateTime end, bool discardTime = true) => (discardTime && (dateTime.SameDay(
 858
 859        /// <summary>
 860        /// Orders and normalizes date-only bounds (discards time, ascending order).
 861        /// </summary>
 862        /// <param name="end">The other end of the range.</param>
 863        /// <returns>Normalized start and end dates.</returns>
 864        public (DateTime Start, DateTime End) Normalize(DateTime end) =>
 6865            dateTime.IsBefore(end)
 6866                ? (dateTime.DiscardTime(), end.DiscardTime())
 6867                : (end.DiscardTime(), dateTime.DiscardTime());
 868
 869        /// <summary>
 870        /// Calculates the age in years from a birthdate to now (UTC based).
 871        /// </summary>
 872        /// <returns>The number of full years elapsed since <paramref name="dateTime"/>.</returns>
 873        public int Age()
 874        {
 0875            var today = DateTime.UtcNow;
 876
 0877            var age = today.Year - dateTime.Year;
 878
 0879            if (today.Month < dateTime.Month || (today.Month == dateTime.Month && today.Day < dateTime.Day))
 0880                age--;
 881
 0882            return age;
 883        }
 884
 885        /// <summary>
 886        /// Generates a sequence of DateTime values starting from a minimum value and ending at a maximum value, with a 
 887        /// </summary>
 888        /// <param name="max">The maximum value of the range.</param>
 889        /// <param name="step">The step value for each iteration.</param>
 890        /// <param name="unit">The time unit for the step.</param>
 891        /// <returns>A sequence of DateTime values within the specified range.</returns>
 892        public IEnumerable<DateTime> Range(DateTime max, int step = 1, TimeUnit unit = TimeUnit.Day)
 893        {
 0894            ArgumentOutOfRangeException.ThrowIfZero(step);
 895
 0896            Func<DateTime, DateTime> increment = unit switch
 0897            {
 0898                TimeUnit.Millisecond => x => x.AddMilliseconds(step),
 0899                TimeUnit.Second => x => x.AddSeconds(step),
 0900                TimeUnit.Minute => x => x.AddMinutes(step),
 0901                TimeUnit.Hour => x => x.AddHours(step),
 0902                TimeUnit.Day => x => x.AddDays(step),
 0903                TimeUnit.Week => x => x.AddDays(step * 7),
 0904                TimeUnit.Month => x => x.AddMonths(step),
 0905                TimeUnit.Year => x => x.AddYears(step),
 0906                _ => null!
 0907            };
 908
 0909            if (step > 0)
 910            {
 0911                for (var i = dateTime; i <= max; i = increment(i))
 0912                    yield return i;
 913            }
 914            else
 915            {
 0916                for (var i = dateTime; i >= max; i = increment(i))
 0917                    yield return i;
 918            }
 0919        }
 920    }
 921
 922    extension(DateTime? dateTime)
 923    {
 924        /// <summary>
 925        /// Returns the date or <see cref="DateTime.MinValue"/> when null.
 926        /// </summary>
 3927        public DateTime OrMinValue() => dateTime ?? DateTime.MinValue;
 928
 929        /// <summary>
 930        /// Returns the date or <see cref="DateTime.MaxValue"/> when null.
 931        /// </summary>
 0932        public DateTime OrMaxValue() => dateTime ?? DateTime.MaxValue;
 933    }
 934
 935    extension(IReadOnlyList<DateTime> dates)
 936    {
 937        /// <summary>
 938        /// Returns the earliest date in the list, or null when empty.
 939        /// </summary>
 940        public DateTime? MinOrNull()
 941        {
 3942            if (dates.Count == 0)
 0943                return null;
 944
 3945            var min = dates[0];
 18946            for (var i = 1; i < dates.Count; i++)
 947            {
 6948                if (dates[i].IsBefore(min))
 3949                    min = dates[i];
 950            }
 951
 3952            return min;
 953        }
 954
 955        /// <summary>
 956        /// Returns the latest date in the list, or null when empty.
 957        /// </summary>
 958        public DateTime? MaxOrNull()
 959        {
 3960            if (dates.Count == 0)
 0961                return null;
 962
 3963            var max = dates[0];
 18964            for (var i = 1; i < dates.Count; i++)
 965            {
 6966                if (dates[i].IsAfter(max))
 3967                    max = dates[i];
 968            }
 969
 3970            return max;
 971        }
 972    }
 973}
 974

Methods/Properties

IsConsecutiveDays(System.Collections.Generic.IEnumerable`1<System.DateTime>)
ToTimeZone(System.DateTime,System.TimeZoneInfo)
ToLocalTime(System.DateTime,System.TimeSpan)
ToUniversalTime(System.DateTime,System.TimeSpan)
ToDate(System.DateTime)
ToTime(System.DateTime)
ToPeriod(System.DateTime,MyNet.Primitives.Temporal.FluentTimeSpan)
ToInclusivePeriod(System.DateTime,System.DateTime)
ToPeriod(System.DateTime,System.DateTime)
IsBefore(System.DateTime,System.DateTime)
IsAfter(System.DateTime,System.DateTime)
IsBefore(System.DateTime,System.DateOnly)
IsAfter(System.DateTime,System.DateOnly)
Between(System.DateTime,System.DateTime)
Between(System.DateTime,System.DateOnly)
Add(System.DateTime,System.Int32,MyNet.Primitives.TimeUnit)
AddFluentTimeSpan(System.DateTime,MyNet.Primitives.Temporal.FluentTimeSpan)
SubtractFluentTimeSpan(System.DateTime,MyNet.Primitives.Temporal.FluentTimeSpan)
EndOfHour(System.DateTime)
EndOfDay(System.DateTime)
EndOfDay(System.DateTime,System.Int32)
EndOfWeek(System.DateTime,System.Nullable`1<System.DayOfWeek>)
EndOfWeek(System.DateTime,System.Int32,System.Nullable`1<System.DayOfWeek>)
EndOfMonth(System.DateTime)
EndOfMonth(System.DateTime,System.Int32)
EndOfQuarter(System.DateTime)
EndOfQuarter(System.DateTime,System.Int32)
EndOfYear(System.DateTime)
EndOfYear(System.DateTime,System.Int32)
EndOfDecade(System.DateTime)
BeginningOfHour(System.DateTime)
BeginningOfDay(System.DateTime)
BeginningOfDay(System.DateTime,System.Int32)
BeginningOfWeek(System.DateTime,System.Nullable`1<System.DayOfWeek>)
BeginningOfWeek(System.DateTime,System.Int32,System.Nullable`1<System.DayOfWeek>)
BeginningOfMonth(System.DateTime)
BeginningOfMonth(System.DateTime,System.Int32)
BeginningOfQuarter(System.DateTime)
BeginningOfQuarter(System.DateTime,System.Int32)
BeginningOfYear(System.DateTime)
BeginningOfYear(System.DateTime,System.Int32)
BeginningOfDecade(System.DateTime)
NextYear(System.DateTime)
PreviousYear(System.DateTime)
NextDay(System.DateTime)
PreviousDay(System.DateTime)
Next(System.DateTime,System.DayOfWeek)
Next(System.DateTime,System.Int32,System.Int32)
Previous(System.DateTime,System.DayOfWeek)
Previous(System.DateTime,System.Int32,System.Int32)
WeekAfter(System.DateTime)
WeekEarlier(System.DateTime)
IncreaseTime(System.DateTime,System.TimeSpan)
DecreaseTime(System.DateTime,System.TimeSpan)
At(System.DateTime,System.TimeOnly)
At(System.DateTime,System.TimeSpan)
At(System.DateTime,System.Int32,System.Int32)
At(System.DateTime,System.Int32,System.Int32,System.Int32)
At(System.DateTime,System.Int32,System.Int32,System.Int32,System.Int32)
SetHour(System.DateTime,System.Int32)
SetMinute(System.DateTime,System.Int32)
SetSecond(System.DateTime,System.Int32)
SetMillisecond(System.DateTime,System.Int32)
Midnight(System.DateTime)
Noon(System.DateTime)
SetDate(System.DateTime,System.Int32)
SetDate(System.DateTime,System.Int32,System.Int32)
SetDate(System.DateTime,System.Int32,System.Int32,System.Int32)
SetYear(System.DateTime,System.Int32)
SetMonth(System.DateTime,System.Int32)
SetDay(System.DateTime,System.Int32)
FirstDayOfQuarter(System.DateTime)
FirstDayOfMonth(System.DateTime)
LastDayOfQuarter(System.DateTime)
LastDayOfMonth(System.DateTime)
AddBusinessDays(System.DateTime,System.Int32)
SubtractBusinessDays(System.DateTime,System.Int32)
IsInFuture(System.DateTime)
IsInPast(System.DateTime)
Round(System.DateTime,MyNet.Primitives.Temporal.RoundTo)
FirstDayOfWeek(System.DateTime,System.Nullable`1<System.DayOfWeek>)
FirstDayOfYear(System.DateTime)
LastDayOfWeek(System.DateTime,System.Nullable`1<System.DayOfWeek>)
LastDayOfYear(System.DateTime)
IsLastDayOfWeek(System.DateTime,System.Nullable`1<System.DayOfWeek>)
IsFirstDayOfWeek(System.DateTime,System.Nullable`1<System.DayOfWeek>)
IsWeekend(System.DateTime)
PreviousMonth(System.DateTime)
NextMonth(System.DateTime)
IsToday(System.DateTime)
SameMilliSecond(System.DateTime,System.DateTime)
SameSecond(System.DateTime,System.DateTime)
SameMinute(System.DateTime,System.DateTime)
SameHour(System.DateTime,System.DateTime)
SameDay(System.DateTime,System.DateTime)
SameWeek(System.DateTime,System.DateTime)
SameMonth(System.DateTime,System.DateTime)
SameYear(System.DateTime,System.DateTime)
SameDecade(System.DateTime,System.DateTime)
NumberOfDays(System.DateTime,System.DateTime)
CompareWeek(System.DateTime,System.DateTime)
NumberOfWeeks(System.DateTime,System.DateTime)
CompareMonth(System.DateTime,System.DateTime)
NumberOfMonths(System.DateTime,System.DateTime)
CompareYear(System.DateTime,System.DateTime)
NumberOfYears(System.DateTime,System.DateTime)
DiscardDayTime(System.DateTime)
DiscardTime(System.DateTime)
InRange(System.DateTime,System.DateTime,System.DateTime,System.Boolean)
Normalize(System.DateTime,System.DateTime)
Age(System.DateTime)
Range()
OrMinValue(System.Nullable`1<System.DateTime>)
OrMaxValue(System.Nullable`1<System.DateTime>)
MinOrNull(System.Collections.Generic.IReadOnlyList`1<System.DateTime>)
MaxOrNull(System.Collections.Generic.IReadOnlyList`1<System.DateTime>)