public static class DateTimeHelper
{
public static int ISO8601WeekNumber(DateTime fromDate)
{
// Get jan 1st of the year
var startOfYear = fromDate.AddDays(-fromDate.Day + 1).AddMonths(-fromDate.Month + 1);
// Get dec 31st of the year
var endOfYear = startOfYear.AddYears(1).AddDays(-1);
// ISO 8601 weeks start with **Monday**
// The first week of a year includes the first Thursday
// DayOfWeek returns 0 for sunday up to 6 for saterday
int[] iso8601Correction = { 6, 7, 8, 9, 10, 4, 5 };
var nds = fromDate.Subtract(startOfYear).Days + iso8601Correction[(int)startOfYear.DayOfWeek];
var wk = nds / 7;
switch (wk)
{
case 0:
// Return weeknumber of dec 31st of the previous year
return ISO8601WeekNumber(startOfYear.AddDays(-1));
case 53:
// If dec 31st falls before thursday it is week 01 of next year
if (endOfYear.DayOfWeek < DayOfWeek.Thursday)
return 1;
else
return wk;
default: return wk;
}
}
public static YearWeek GetWeekFromDate(DateTime date, bool includeSunday = false)
{
if (includeSunday && date.DayOfWeek == DayOfWeek.Sunday)
date = date.AddDays(1);
var week = ISO8601WeekNumber(date);
var year = GetYear(date, week);
return YearWeek.FromInts(year, week);
}
private static int GetYear(DateTime date, int week)
{
if (week <= 1)
return date.AddMonths(1).Year;
else if (week >= 52)
return date.AddMonths(-1).Year;
return date.Year;
}
public static DateTime GetDateFromISO8601Week(YearWeek week) => GetDateFromISO8601Week(week.Year, week.Week);
public static DateTime GetDateFromISO8601Week(int year, int week)
{
var dayOfYear = (week - 1) * 7;
var result = new DateTime(year, 1, 1).AddDays(dayOfYear);
var dayOfWeek = (int)result.DayOfWeek;
if (dayOfWeek <= (int)DayOfWeek.Thursday)
{
result = result.AddDays((-dayOfWeek) + 1);
}
else
{
result = result.AddDays(8 - dayOfWeek);
}
return result;
}
public static int YearWeekCount(int year)
{
var week = ISO8601WeekNumber(new DateTime(year + 1, 1, 1));
if (week == 53) return 53;
return 52;
}
public static IEnumerable<YearWeek> EachWeek(YearWeek startWeek, YearWeek endWeek)
{
var currentWeek = startWeek.Copy();
while (currentWeek.AsInt() < endWeek.AsInt())
{
yield return currentWeek;
currentWeek = GetNextWeek(currentWeek);
}
}
private static YearWeek GetNextWeek(YearWeek currentWeek)
{
var weeksInYear = YearWeekCount(currentWeek.Year);
var nextWeek = YearWeek.FromInts(currentWeek.Year, currentWeek.Week + 1);
if (nextWeek.Week > weeksInYear)
return YearWeek.FromInts(currentWeek.Year + 1, 1);
return nextWeek;
}
public static YearWeek AddWeeks(YearWeek yw, int numberOfWeeks)
{
if (numberOfWeeks == 0) return yw;
var year = yw.Year;
var week = yw.Week + numberOfWeeks;
while (week < 1)
{
year--;
week += YearWeekCount(year);
}
while (week > YearWeekCount(year))
{
week -= YearWeekCount(year);
year++;
}
return YearWeek.FromInts(year, week);
}
public static int GetQuarterForMonh(int month)
{
if (month < 1 || month > 12)
throw new ArgumentOutOfRangeException(nameof(month), "Month must be between 1 and 12.");
return (month - 1) / 3 + 1;
}
public static DateTime AddQuarters(DateTime date, int numberOfQuarters)
{
var dateCounter = GetQuarterDate(date);
return dateCounter.AddMonths(numberOfQuarters * 3);
}
public static DateTime GetQuarterDate(DateTime date) => new DateTime(date.Year, GetQuarterMonthFromMonth(date.Month), 1);
public static int GetQuarterMonthFromMonth(int month) => ((month - 1) / 3) * 3 + 1;
public static IEnumerable<DateTime> EachQuarter(DateTime startTime, DateTime endTime)
{
var dateCounter = GetQuarterDate(startTime);
var endDateTarget = GetQuarterDate(endTime); ;
while (dateCounter <= endDateTarget)
{
yield return dateCounter;
dateCounter = dateCounter.AddMonths(3);
}
}
public static string GetYearKey(DateTime date) => $"{date.Year}";
public static string GetMonthKey(DateTime date) => GetMonthKey(date.Year, date.Month);
public static string GetMonthKey(int year, int month) => $"{year}-{month:D2}";
public static string GetQuarterKey(DateTime date) => $"{date.Year}-Q{GetQuarterForMonh(date.Month):D1}";
public static IEnumerable<DateTime> EachMonth(DateTime startTime, DateTime endTime)
{
var dateCounter = new DateTime(startTime.Year, startTime.Month, 1);
var endDateTarget = new DateTime(endTime.Year, endTime.Month, 1);
while (dateCounter <= endDateTarget)
{
yield return dateCounter;
dateCounter = dateCounter.AddMonths(1);
}
}
public static IEnumerable<DateTime> EachYear(DateTime startTime, DateTime endTime)
{
var dateCounter = new DateTime(startTime.Year, 1, 1);
var endDateTarget = new DateTime(endTime.Year, 1, 1);
while (dateCounter <= endDateTarget)
{
yield return dateCounter;
dateCounter = dateCounter.AddYears(1);
}
}
}
public class YearWeek : IComparable
{
public YearWeek(int year, int week)
{
Year = year;
Week = Limit(week, 1, 53);
}
public int Year { get; private set; }
public int Week { get; private set; }
public static YearWeek FromInts(int year, int week) => new(year, week);
public string Key => ToString();
public int CompareTo(object o) => InternalCompareTo(o as YearWeek);
public int CompareTo(YearWeek other) => InternalCompareTo(other);
private int InternalCompareTo(YearWeek o) => AsInt().CompareTo(o?.AsInt() ?? 0);
private static int Limit(int val, int min, int max) => Math.Max(min, Math.Min(max, val));
public override bool Equals(object obj)
{
if (obj == null || obj is not YearWeek yw) return false;
return yw.AsInt() == AsInt();
}
public override int GetHashCode() => AsInt();
public int AsInt() => (Year * 100) + Week;
public override string ToString() => $"{Year}-{Week:D2}";
public YearWeek Copy() => (YearWeek)MemberwiseClone();
public static YearWeek FromInt(int? yearWeekInt)
{
if (yearWeekInt == null) return null;
var year = yearWeekInt.Value / 100;
var week = yearWeekInt.Value % 100;
return new YearWeek(year, week);
}
// Must be overloaded in pairs as follows: == and !=, < and >, <= and >=.
public static bool operator ==(YearWeek obj1, YearWeek obj2) => (obj1?.AsInt() ?? 0) == (obj2?.AsInt() ?? 0);
public static bool operator !=(YearWeek obj1, YearWeek obj2) => (obj1?.AsInt() ?? 0) != (obj2?.AsInt() ?? 0);
public static bool operator <(YearWeek obj1, YearWeek obj2) => (obj1?.AsInt() ?? 0) < (obj2?.AsInt() ?? 0);
public static bool operator >(YearWeek obj1, YearWeek obj2) => (obj1?.AsInt() ?? 0) > (obj2?.AsInt() ?? 0);
public static bool operator <=(YearWeek obj1, YearWeek obj2) => (obj1?.AsInt() ?? 0) <= (obj2?.AsInt() ?? 0);
public static bool operator >=(YearWeek obj1, YearWeek obj2) => (obj1?.AsInt() ?? 0) >= (obj2?.AsInt() ?? 0);
}Older
using System;
using System.Collections.Generic;
using System.Linq;
namespace Helpers
{
public static class DateTimeHelper
{
public static DateTime? GetDateTimeFromInput(string dateTimeStr, DateTime? def = null)
{
if (string.IsNullOrWhiteSpace(dateTimeStr))
return def;
if (DateTime.TryParse(dateTimeStr.Trim(), CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out var dateTime))
return dateTime;
return def;
}
public static TimeSpan? GetTimeFromInput(string timeStr, TimeSpan? def = null)
{
if (string.IsNullOrWhiteSpace(timeStr))
return def;
if (TimeSpan.TryParse(timeStr.Trim(), CultureInfo.InvariantCulture, out var time))
return time;
return def;
}
public static DateTime? GetCombinedDateTime(DateTime? date, TimeSpan? time)
{
if (date == null) return null;
var d = date.Value.Date;
if (time == null) return d;
return d.Add(time.Value);
}
public static int ISO8601WeekNumber2(DateTime fromDate)
{
var culture = new System.Globalization.CultureInfo("nl-NL");
var format = culture.DateTimeFormat;
var weekOfYear = culture.Calendar.GetWeekOfYear(fromDate, format.CalendarWeekRule, format.FirstDayOfWeek);
}
public static int ISO8601WeekNumber(DateTime fromDate)
{
// Get jan 1st of the year
DateTime startOfYear = fromDate.AddDays(-fromDate.Day + 1).AddMonths(-fromDate.Month + 1);
// Get dec 31st of the year
DateTime endOfYear = startOfYear.AddYears(1).AddDays(-1);
// ISO 8601 weeks start with Monday
// The first week of a year includes the first Thursday
// DayOfWeek returns 0 for sunday up to 6 for saterday
int[] iso8601Correction = { 6, 7, 8, 9, 10, 4, 5 };
int nds = fromDate.Subtract(startOfYear).Days + iso8601Correction[(int)startOfYear.DayOfWeek];
int wk = nds / 7;
switch (wk)
{
case 0:
// Return weeknumber of dec 31st of the previous year
return ISO8601WeekNumber(startOfYear.AddDays(-1));
case 53:
// If dec 31st falls before thursday it is week 01 of next year
if (endOfYear.DayOfWeek < DayOfWeek.Thursday)
return 1;
else
return wk;
default: return wk;
}
}
public static YearWeek GetWeekFromDate(DateTime date)
{
return new YearWeek
{
Year = date.Year,
Week = ISO8601WeekNumber(date)
};
}
public static DateTime GetDateFromISO8601Week(YearWeek week)
{
return GetDateFromISO8601Week(week.Year, week.Week);
}
public static DateTime GetDateFromISO8601Week(int year, int week)
{
var dayOfYear = (week - 1) * 7;
var result = new DateTime(year, 1, 1).AddDays(dayOfYear);
var dayOfWeek = (int)result.DayOfWeek;
if (dayOfWeek <= (int)DayOfWeek.Thursday)
{
result = result.AddDays((-dayOfWeek) + 1);
}
else
{
result = result.AddDays(8 - dayOfWeek);
}
return result;
}
public static Range<DateTime> GetDateRangeFromISO8601Week(YearWeek week)
{
return GetDateRangeFromISO8601Week(week.Year, week.Week);
}
public static Range<DateTime> GetDateRangeFromISO8601Week(int year, int week)
{
var range = new Range<DateTime>();
range.Minimum = GetDateFromISO8601Week(year, week);
range.Maximum = range.Minimum.AddDays(6);
return range;
}
public static List<DateTime> GetlistOfWeekDays(DateTime startDateParam)
{
DateTime startDate = startDateParam;// startDateParam.AddDays(-(((dow - (int)DayOfWeek.Monday) + 7) % 7));
while (startDate.DayOfWeek != DayOfWeek.Monday)
{
startDate = startDate.AddDays(-1);
}
var endDate = startDate.AddDays(7);
//the number of days in our range of dates
var numDays = (int)((endDate - startDate).TotalDays);
List<DateTime> myDates = Enumerable
//creates an IEnumerable of ints from 0 to numDays
.Range(0, numDays)
//now for each of those numbers (0..numDays),
//select startDate plus x number of days
.Select(x => startDate.AddDays(x))
//and make a list
.ToList();
return myDates;
}
public static DateTime FirstDateOfWeek(int year, int weekOfYear, System.Globalization.CultureInfo ci)
{
DateTime jan1 = new DateTime(year, 1, 1);
int daysOffset = (int)ci.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;
DateTime firstWeekDay = jan1.AddDays(daysOffset);
int firstWeek = ci.Calendar.GetWeekOfYear(jan1, ci.DateTimeFormat.CalendarWeekRule, ci.DateTimeFormat.FirstDayOfWeek);
if (firstWeek <= 1 || firstWeek > 50)
{
weekOfYear -= 1;
}
return firstWeekDay.AddDays(weekOfYear * 7);
}
public static DateTime LastDateOfWeek(int year, int weekOfYear, System.Globalization.CultureInfo ci)
{
DateTime jan1 = new DateTime(year, 1, 1);
int daysOffset = (int)ci.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;
DateTime firstWeekDay = jan1.AddDays(daysOffset);
int firstWeek = ci.Calendar.GetWeekOfYear(jan1, ci.DateTimeFormat.CalendarWeekRule, ci.DateTimeFormat.FirstDayOfWeek);
if (firstWeek <= 1 || firstWeek > 50)
{
weekOfYear -= 1;
}
return firstWeekDay.AddDays((weekOfYear + 1 * 7) - 1);
}
public static IEnumerable<DateTime> EachDay(DateTime start, DateTime end)
{
// Remove time info from start date (we only care about day).
DateTime currentDay = new DateTime(start.Year, start.Month, start.Day);
while (currentDay <= end)
{
yield return currentDay;
currentDay = currentDay.AddDays(1);
}
}
public static IEnumerable<Tuple<int, int, int>> EachDayOfMonth(DateTime start, DateTime end)
{
// Remove time info from start date (we only care about day).
DateTime currentDay = new DateTime(start.Year, start.Month, start.Day);
while (currentDay <= end)
{
yield return new Tuple<int, int, int>(currentDay.Year, currentDay.Month, currentDay.Day);
currentDay = currentDay.AddDays(1);
}
}
public static IEnumerable<Tuple<int, int>> EachMonth(DateTime start, DateTime end)
{
// Remove time info from start date (we only care about day).
var firstMonth = new DateTime(start.Year, start.Month, 1);
var currentMonth = firstMonth;
while (currentMonth <= end)
{
yield return new Tuple<int, int>(currentMonth.Year, currentMonth.Month);
currentMonth = currentMonth.AddMonths(1);
}
}
public static IEnumerable<YearWeek> EachWeek(YearWeek yearWeek, int numberOfWeeks)
{
var firstDateOfWeek = GetDateFromISO8601Week(yearWeek.Year, yearWeek.Week);
return EachWeek(firstDateOfWeek, numberOfWeeks);
}
public static IEnumerable<YearWeek> EachWeek(DateTime start, int numberOfWeeks)
{
// Remove time info from start date (we only care about day).
DateTime currentDay = new DateTime(start.Year, start.Month, start.Day);
int lastWeek = 0;
int weekCounter = 0;
while (weekCounter < numberOfWeeks)
{
var week = DateTimeHelper.ISO8601WeekNumber(currentDay);
var year = currentDay.Year;
if (week == 1)
{
year = currentDay.AddMonths(1).Year;
}
else if (week >= 52)
{
year = currentDay.AddMonths(-1).Year;
}
if (week != lastWeek)
{
lastWeek = week;
weekCounter += 1;
currentDay = currentDay.AddDays(7);
yield return new YearWeek { Year = year, Week = week };
}
else
{
currentDay = currentDay.AddDays(1);
}
}
}
public static IEnumerable<YearWeek> EachWeek(DateTime start, DateTime end)
{
// Remove time info from start date (we only care about day).
DateTime currentDay = new DateTime(start.Year, start.Month, start.Day);
int lastWeek = 0;
while (currentDay <= end)
{
var week = DateTimeHelper.ISO8601WeekNumber(currentDay);
var year = currentDay.Year;
if (week == 1)
{
year = currentDay.AddMonths(1).Year;
}
else if (week >= 52)
{
year = currentDay.AddMonths(-1).Year;
}
if (week != lastWeek)
{
lastWeek = week;
currentDay = currentDay.AddDays(7);
yield return new YearWeek { Year = year, Week = week };
}
else
{
currentDay = currentDay.AddDays(1);
}
}
}
public static int YearWeekCount(int year)
{
var week = ISO8601WeekNumber(new DateTime(year + 1, 1, 1));
if (week == 53)
{
return 53;
}
else
{
return 52;
}
}
public class YearWeek : IComparable
{
public int Year { get; set; }
public int Week { get; set; }
public int CompareTo(object o)
{
int c = 0;
var b = (YearWeek)o;
if (b != null)
{
c = Year.CompareTo(b.Year);
if (c == 0)
{
c = Week.CompareTo(b.Week);
}
}
return c;
}
public override bool Equals(object obj)
{
if (obj != null && obj is YearWeek)
{
var yw = (YearWeek)obj;
return yw.Year == Year && yw.Week == Week;
}
return false;
}
public override int GetHashCode()
{
return Year.GetHashCode() + Week.GetHashCode();
}
}
public static bool IsGreaterThan<T>(this T value, T other) where T : IComparable
{
return value.CompareTo(other) > 0;
}
public static bool IsLessThan<T>(this T value, T other) where T : IComparable
{
return value.CompareTo(other) < 0;
}
public static YearWeek AddWeeks(YearWeek yearWeek, int numberOfWeeks)
{
int weeksToGo = Math.Abs(numberOfWeeks);
int step = numberOfWeeks / Math.Abs(numberOfWeeks);
var current = new YearWeek { Year = yearWeek.Year, Week = yearWeek.Week };
while (weeksToGo > 0)
{
current.Week += step;
if (current.Week < 1)
{
current.Year -= 1;
current.Week = YearWeekCount(current.Year);
}
else if (current.Week > 52)
{
var wc = YearWeekCount(current.Year);
if (current.Week > wc)
{
current.Week = 1;
current.Year += 1;
}
}
weeksToGo -= 1;
}
return current;
}
public static int GetWeekDiff(YearWeek a, YearWeek b)
{
int diff = 0;
int cmp = 0;
var c = new YearWeek { Year = b.Year, Week = b.Week };
while (true)
{
cmp = c.CompareTo(a);
if (cmp == 0)
{
return diff;
}
else
{
diff += cmp;
c = AddWeeks(c, -cmp);
}
}
}
public static bool IsDateInRange(DateTime? val, DateTime? min, DateTime? max)
{
return val.HasValue && (!min.HasValue || val.Value >= min.Value) && (!max.HasValue || val.Value <= max.Value);
}
public static bool DateRangeOverlap(DateTime? min1, DateTime? max1, DateTime? min2, DateTime? max2)
{
return DateRangeOverlap(min1.GetValueOrDefault(DateTime.MinValue), max1.GetValueOrDefault(DateTime.MaxValue),
min2.GetValueOrDefault(DateTime.MinValue), max2.GetValueOrDefault(DateTime.MaxValue));
}
public static bool DateRangeOverlap(DateTime min1, DateTime max1, DateTime min2, DateTime max2)
{
// from: http://stackoverflow.com/questions/7325124/how-check-intersection-of-datetime-periods
if (min1 > max1 || min2 > max2)
throw new Exception("Invalid date range");
if (min1 == max1 || min2 == max2)
return false; // No actual date range
if (min1 == min2 || max1 == max2)
return true; // If any set is the same time, then by default there must be some overlap.
if (min1 < min2)
{
if (max1 > min2 && max1 < max2)
return true; // Condition 1
if (max1 > max2)
return true; // Condition 3
}
else
{
if (max2 > min1 && max2 < max1)
return true; // Condition 2
if (max2 > max1)
return true; // Condition 4
}
return false;
}
public static TimeSpan DateRangeOverlapTimeSpan(DateTime min1, DateTime max1, DateTime min2, DateTime max2)
{
if (min1 > max1 || min2 > max2)
{
throw new Exception("Invalid date range");
}
// Cases:
// [---- Date1 ----]
// [--2C--]
// [------------2D------------]
// [----2A----] [----2B----]
// [--E--] [--F--]
// 2E, 2F: skip
if (max2 <= min1 || min2 >= max1)
{
return new TimeSpan(0);
}
// 2C
if (min1 <= min2 && max1 >= max2)
{
return (max2 - min2).Duration();
}
// 2D
if (min1 >= min2 && max1 <= max2)
{
return (max1 - min1).Duration();
}
// 2A
if (min1 >= min2 && max1 >= max2 && max2 >= min1)
{
return (max2 - min1).Duration();
}
// 2B
if (min1 <= min2 && max1 >= min2 && max2 >= max1)
{
return (max1 - min2).Duration();
}
return new TimeSpan(0);
}
public static TimeSpan TimespanRangeOverlapTimeSpan(TimeSpan min1, TimeSpan max1, TimeSpan min2, TimeSpan max2)
{
if (min1 > max1 || min2 > max2)
{
throw new Exception("Invalid date range");
}
// Cases:
// [---- Date1 ----]
// [--2C--]
// [------------2D------------]
// [----2A----] [----2B----]
// [--E--] [--F--]
// 2E, 2F: skip
if (max2 <= min1 || min2 >= max1)
{
return new TimeSpan(0);
}
// 2C
if (min1 <= min2 && max1 >= max2)
{
return (max2 - min2).Duration();
}
// 2D
if (min1 >= min2 && max1 <= max2)
{
return (max1 - min1).Duration();
}
// 2A
if (min1 >= min2 && max1 >= max2 && max2 >= min1)
{
return (max2 - min1).Duration();
}
// 2B
if (min1 <= min2 && max1 >= min2 && max2 >= max1)
{
return (max1 - min2).Duration();
}
return new TimeSpan(0);
}
public static TimeSpan TimespanBetweenDatetimes(TimeSpan from, TimeSpan to)
{
// Next day
if (IsGreaterThan<TimeSpan>(from, to))
{
TimeSpan timespanday = TimeSpan.FromDays(1);
to = to.Add(timespanday);
}
TimeSpan totaltime = new TimeSpan(to.Ticks - from.Ticks);
return totaltime;
}
public static Double GetUnixTimestampFromDate(DateTime targetDateTime)
{
DateTime zeroDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
TimeSpan timeDifference = targetDateTime.ToUniversalTime() - zeroDateTime;
return timeDifference.TotalSeconds;
}
public static DateTime? GetDateFromAS400(long date)
{
return GetDateFromAS400(date.ToString());
}
public static DateTime? GetDateFromAS400(string date)
{
if (date.Length == 8)
// formaat YYYYMMDDD
return new DateTime(Convert.ToInt32(date.Substring(0, 4)), Convert.ToInt32(date.Substring(4, 2)), Convert.ToInt32(date.Substring(6, 2)));
else
return null;
}
public static long SetDateToAS400(DateTime date)
{
return long.Parse(string.Format("{0:yyyyMMdd}", date));
}
}
}
public class YearWeek : IComparable, IComparable<YearWeek>
{
public int Year { get; set; }
public int Week { get; set; }
public string Key => ToString();
public static YearWeek FromInts(int year, int week)
{
return new YearWeek { Year = year, Week = week };
}
public int CompareTo(object o) => InternalCompareTo(o as YearWeek);
public override bool Equals(object obj)
{
if (obj == null || obj is not YearWeek yw) return false;
return yw.Year == Year && yw.Week == Week;
}
public override string ToString() => $"{Year}-{Week}";
public override int GetHashCode() => Year.GetHashCode() + Week.GetHashCode();
public int AsInt() => int.Parse($"{Year}{Week:D2}");
public YearWeek Copy() => (YearWeek)MemberwiseClone();
public int WeekCountTo(YearWeek yearWeek)
{
var i = 0;
var current = this;
while (current.IsLessThan(yearWeek))
{
current = DateTimeHelper.AddWeeks(current, 1);
i += 1;
}
return i;
}
public static YearWeek FromInt(int? yearWeekInt)
{
if (yearWeekInt == null) return null;
var yearWeekStr = yearWeekInt.ToString();
var year = int.Parse(yearWeekStr.Substring(0, yearWeekStr.Length - 2));
var week = int.Parse(yearWeekStr.Substring(yearWeekStr.Length - 2));
return new YearWeek { Year = year, Week = week };
}
public static YearWeek Now() => DateTimeHelper.GetWeekFromDate(DateTime.Now);
public int CompareTo(YearWeek other) => InternalCompareTo(other);
private int InternalCompareTo(YearWeek o) => this?.AsInt() ?? 0 - o?.AsInt() ?? 0;
public YearWeek AddWeeks(int count) => DateTimeHelper.AddWeeks(this, count);
}269200cookie-checkC# DateTime helpers