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