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