Files
BeWoPlaner/Shared/Extensions/DateTimeExtensions.cs
Lyndon Jetten ee68e7879a Bugs im Kalender behoben (noch nicht alle)
Mitarbeiter wird nicht mehr automatisch bei Gruppenbuchungen hinzugefügt, wenn es nicht erwünscht IsTask
Hilfepläne, die heute ablaufen, werden noch als nicht abgelaufen angezeigt wie im Fat-Client
2020-12-01 12:29:12 +01:00

595 lines
21 KiB
C#

using System;
using System.Globalization;
using BS.Shared.Core;
using System.Collections.Generic;
using DevExpress.XtraScheduler;
namespace BS.Shared.Extensions
{
public enum TimeUnit
{
Day,
Week,
Fortnightly,
Month,
Quarter,
Halfyear,
Year
}
public class DateTimeUnit
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int UnitCount { get; set; }
public int RestDays { get; set; }
}
public static class DateTimeExtensions
{
public static DateTimeUnit GetDateTimeUnit(this DateTime Date1, DateTime Date2, TimeUnit unit)
{
List<DateTime> period = new List<DateTime>() { Date1, Date2 };
period.Sort(DateTime.Compare);
DateTimeUnit ds = new DateTimeUnit();
ds.StartDate = period[0];
ds.EndDate = period[1].AddDays(1);
int totaldays = (int)ds.EndDate.Subtract(ds.StartDate).TotalDays;
DateTime startDate = ds.StartDate;
switch (unit)
{
case TimeUnit.Day:
ds.UnitCount = totaldays;
ds.RestDays = 0;
break;
case TimeUnit.Week:
ds.UnitCount = (int)(totaldays / 7m);
ds.RestDays = totaldays - (ds.UnitCount * 7);
break;
case TimeUnit.Fortnightly:
ds.UnitCount = (int)(totaldays / 14m);
ds.RestDays = totaldays - (ds.UnitCount * 14);
break;
case TimeUnit.Month:
int months = 0;
while (startDate.AddMonths(1) <= ds.EndDate)
{
startDate = startDate.AddMonths(1);
months++;
}
ds.UnitCount = months;
ds.RestDays = (int)ds.EndDate.Subtract(startDate).TotalDays;
break;
case TimeUnit.Quarter:
int quarter = 0;
while (startDate.AddMonths(3) <= ds.EndDate)
{
startDate = startDate.AddMonths(3);
quarter++;
}
ds.UnitCount = quarter;
ds.RestDays = (int)ds.EndDate.Subtract(startDate).TotalDays;
break;
case TimeUnit.Halfyear:
int halfyear = 0;
while (startDate.AddMonths(6) <= ds.EndDate)
{
startDate = startDate.AddMonths(6);
halfyear++;
}
ds.UnitCount = halfyear;
ds.RestDays = (int)ds.EndDate.Subtract(startDate).TotalDays;
break;
case TimeUnit.Year:
int year = 0;
while (startDate.AddYears(1) <= ds.EndDate)
{
startDate = startDate.AddYears(1);
year++;
}
ds.UnitCount = year;
ds.RestDays = (int)ds.EndDate.Subtract(startDate).TotalDays;
break;
default:
break;
}
return ds;
}
public static DateTime AddMonthsDayDependent(this DateTime pDateTime, int pMonthsToAdd, bool pFirstDay)
{
var lResult = new DateTime(pDateTime.Year, pDateTime.Month, 1);
lResult = lResult.AddMonths(pMonthsToAdd);
lResult = FromWeekdayOccurence(lResult.Year, lResult.Month, pDateTime.DayOfWeek, pDateTime.GetWeekdayOccurence(pFirstDay), pFirstDay);
lResult = lResult.AddHours(pDateTime.Hour);
lResult = lResult.AddMinutes(pDateTime.Minute);
lResult = lResult.AddSeconds(pDateTime.Second);
lResult = lResult.AddMilliseconds(pDateTime.Millisecond);
return lResult;
}
public static T DoIfNotNull<T>(this DateTime? pDateTime, Func<DateTime, T> pFunc)
{
if (pDateTime.HasValue)
{
return pFunc(pDateTime.Value);
}
else
{
return default(T);
}
}
public static void DoIfNotNull<T>(this DateTime? pDateTime, Action<DateTime> pFunc)
{
if (pDateTime.HasValue)
{
pFunc(pDateTime.Value);
}
}
public static DateTime GetInSameCalendarWeek(this DateTime pDateTime, DayOfWeek pDay)
{
DateTime lStart = pDateTime.GetLast(DayOfWeek.Monday);
while (lStart.DayOfWeek != pDay)
{
lStart = lStart.AddDays(1);
}
return lStart;
}
public static DateTime GetLast(this DateTime pDateTime, DayOfWeek pDay)
{
DateTime lResult = pDateTime;
while (lResult.DayOfWeek != pDay)
{
lResult = lResult.Date.AddDays(-1);
}
return lResult;
}
public static DateTime GetLastFridayIfWeekend(this DateTime pDateTime)
{
DateTime lResult = pDateTime;
while (lResult.DayOfWeek == DayOfWeek.Saturday || lResult.DayOfWeek == DayOfWeek.Sunday)
{
lResult = lResult.Date.AddMilliseconds(-1);
}
return lResult;
}
public static DateTime GetNext(this DateTime pDateTime, DayOfWeek pDay)
{
DateTime lResult = pDateTime;
while (lResult.DayOfWeek != pDay)
{
lResult = lResult.Date.AddDays(1);
}
return lResult;
}
public static DateTime GetNextMondayIfWeekend(this DateTime pDateTime)
{
DateTime lResult = pDateTime;
while (lResult.DayOfWeek == DayOfWeek.Saturday || lResult.DayOfWeek == DayOfWeek.Sunday)
{
lResult = lResult.Date.AddDays(1);
}
return lResult;
}
public static int GetWeekdayOccurence(this DateTime pDateTime, bool pForward)
{
if (pForward)
{
return (int)Math.Ceiling(pDateTime.Day / 7d);
}
return (int)Math.Ceiling((DateTime.DaysInMonth(pDateTime.Year, pDateTime.Month) - pDateTime.Day) / 7d);
}
public static bool InBetween(this DateTime pDateTime, DateTime pSpanStart, DateTime pSpanStop, bool ignoreTimeAndCompareWholeDays)
{
DateTime stop = pSpanStop;
if (ignoreTimeAndCompareWholeDays)
{
if (stop < DateTime.MaxValue.Date)
{
try
{
stop = stop.Date.AddDays(1);
}
catch (Exception)
{
stop = pSpanStop;
}
}
return pDateTime >= pSpanStart && pDateTime < stop;
}
return pDateTime >= pSpanStart && pDateTime <= stop;
}
public static bool InBetween(this DateTime pDateTime, DateTimeSpan pSpan, bool ignoreTimeAndCompareWholeDays)
{
if (pSpan == null)
{
return false;
}
return pDateTime.InBetween(pSpan.StartDateTime, pSpan.EndDateTime, ignoreTimeAndCompareWholeDays);
}
public static string ToMonthSlashShortYear(this DateTime pDate)
{
return pDate.Month + "/" + pDate.Year.ToString().Substring(2);
}
public static string ToVeryShortDateString(this DateTime ths)
{
return ths.ToShortDateString().Remove(ths.ToShortDateString().Length - 4, 2);
}
public static string ToMyDateTimeString(this DateTime pDate)
{
var lInfo = DateTimeFormatInfo.CurrentInfo;
return lInfo.GetAbbreviatedDayName(pDate.DayOfWeek) + ", " + $"{pDate.Day:00}" + "." + $"{pDate.Month:00}" + "." + pDate.Year.ToString().Substring(2);
}
private static DateTime FromWeekdayOccurence(int pYear, int pMonth, DayOfWeek pDay, int pWeekdayOccurence, bool pFromStart)
{
if (pFromStart)
{
DateTime lResult = new DateTime(pYear, pMonth, 1);
while (lResult.DayOfWeek != pDay)
{
lResult = lResult.AddDays(1);
}
return lResult.AddDays(7 * (pWeekdayOccurence - 1));
}
else
{
DateTime lResult = new DateTime(pYear, pMonth, DateTime.DaysInMonth(pYear, pMonth));
while (lResult.DayOfWeek != pDay)
{
lResult = lResult.AddDays(-1);
}
return lResult.AddDays(-7 * (pWeekdayOccurence - 1));
}
}
public static WeekOfMonth GetWeekOfMonth(this DateTime pDateTime, DayOfWeek WeekStartingOn)
{
var x = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(pDateTime, CalendarWeekRule.FirstFourDayWeek, WeekStartingOn);
var y = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(pDateTime.AddDays(1 - pDateTime.Day), CalendarWeekRule.FirstFourDayWeek, WeekStartingOn);
var r = x - y + 1;
switch (r)
{
case 1:
return WeekOfMonth.First;
case 2:
return WeekOfMonth.Second;
case 3:
return WeekOfMonth.Third;
case 4:
return WeekOfMonth.Fourth;
default:
return WeekOfMonth.None;
}
}
public static DateTime GetXthLastOccurenceInMonth(this DateTime pDateTime, DayOfWeek pDayOfWeek, int x)
{
var initialDate = new DateTime(pDateTime.Year, pDateTime.Month, DateTime.DaysInMonth(pDateTime.Year, pDateTime.Month));
var lastOccurence = initialDate;
for (var currentDate = initialDate; currentDate >= new DateTime(pDateTime.Year, pDateTime.Month, 1); currentDate = currentDate.AddDays(-1))
{
if (!currentDate.DayOfWeek.Equals(pDayOfWeek)) continue;
lastOccurence = currentDate;
break;
}
return lastOccurence.AddDays(-1 * 7 * x);
}
public static int GetOccurenceNumber(this DateTime pDateTime)
{
var initialDate = new DateTime(pDateTime.Year, pDateTime.Month, DateTime.DaysInMonth(pDateTime.Year, pDateTime.Month));
var lastOccurence = initialDate;
var dayOfWeek = pDateTime.DayOfWeek;
for (var currentDate = initialDate; currentDate >= new DateTime(pDateTime.Year, pDateTime.Month, 1); currentDate = currentDate.AddDays(-1))
{
if (!currentDate.DayOfWeek.Equals(dayOfWeek)) continue;
lastOccurence = currentDate;
break;
}
return Convert.ToInt32((lastOccurence - pDateTime).TotalDays / 7);
}
public static int GetIso8601WeekOfYear(this DateTime time)
{
var day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
{
time = time.AddDays(3);
}
return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
public static DateTime FirstDateOfWeek(this DateTime date, int weekOfYear)
{
var jan1 = new DateTime(date.Year, 1, 1);
var daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek;
var firstThursday = jan1.AddDays(daysOffset);
var cal = CultureInfo.CurrentCulture.Calendar;
var firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
var weekNum = weekOfYear;
if (firstWeek <= 1)
{
weekNum -= 1;
}
var result = firstThursday.AddDays(weekNum * 7);
return result.AddDays(-3);
}
public static bool CompareShortDates(this DateTime date, DateTime pDate)
{
return date.Year == pDate.Year && date.Month == pDate.Month && date.Day == pDate.Day;
}
public static double GetIntersectingMinutes(this DateTime start1, DateTime end1, DateTime start2, DateTime end2)
{
var e = end1 <= end2 ? end1 : end2;
var s = start1 >= start2 ? start1 : start2;
return s > e ? 0 : (e - s).TotalMinutes;
}
public static DateTime GetNextDayOfWeek(this DateTime start, DayOfWeek WeekDay)
{
var result = start;
while (!result.DayOfWeek.Equals(WeekDay))
{
result = result.AddDays(1);
}
return result;
}
public static DateTime GetShortDateTime(this DateTime date)
{
return new DateTime(date.Year, date.Month, date.Day);
}
public static int GetDayNumberBetweenTwoDates(this DateTime anteriorDate, DateTime posteriorDate)
{
var value = 0;
var shortAnteriorDate = new DateTime(anteriorDate.Year, anteriorDate.Month, anteriorDate.Day);
var shortPosteriorDate = new DateTime(posteriorDate.Year, posteriorDate.Month, posteriorDate.Day);
var tmpDate = shortAnteriorDate;
while (tmpDate < shortPosteriorDate)
{
tmpDate = tmpDate.AddDays(1);
value++;
}
return value;
}
/// <summary>
/// Erzeugt aus zwei Datumsobjekten ein neues mit den Datumsangaben des ersten und den Zeitangaben des zweiten Parameters.
/// </summary>
/// <param name="first">Datum dessen Datewerte übernommen werden.</param>
/// <param name="second">Datum dessen Zeitwerte übernommen werden.</param>
/// <returns>Gibt ein neues Objekt der Klasse Datum mit dem Datum des ersten Parameters und der Zeit des zweiten Parameters zurück.</returns>
public static DateTime MergeDatesByDate(this DateTime first, DateTime second)
{
return new DateTime(first.Year, first.Month, first.Day, second.Hour, second.Minute, second.Second);
}
public static DateTime MergeDateAndTimeSpan(this DateTime pDate, TimeSpan pTimeSpan)
{
return new DateTime(pDate.Year, pDate.Month, pDate.Day, pTimeSpan.Hours, pTimeSpan.Minutes, pTimeSpan.Seconds);
}
public static WeekDays GetSchedulerWeekDays(this DateTime pDateTime)
{
return (WeekDays)(int)Math.Pow(2, (double)pDateTime.DayOfWeek);
}
public static WeekOfMonth GetWeekOfMonthForRecurrenceInfo(this DateTime pDate)
{
pDate = pDate.Date;
var firstMonthDay = new DateTime(pDate.Year, pDate.Month, 1);
var firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
if (firstMonthMonday > pDate)
{
firstMonthDay = firstMonthDay.AddMonths(-1);
firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
}
var weekNumber = (pDate - firstMonthMonday).Days / 7 + 1;
switch (weekNumber)
{
case 1:
return WeekOfMonth.First;
case 2:
return WeekOfMonth.Second;
case 3:
return WeekOfMonth.Third;
case 4:
return WeekOfMonth.Fourth;
default:
return WeekOfMonth.None;
}
}
/// <summary>
/// Prüft, ob sich ein Interval aus start1 und end1 innerhalb vom zweiten Interval, das aus start2 und end2 besteht, befindet oder sich mit diesem deckt.
/// </summary>
/// <param name="start1">Beginn des ersten Intervalls.</param>
/// <param name="end1">Ende des ersten Intervalls.</param>
/// <param name="start2">Beginn des zweiten Intervalls.</param>
/// <param name="end2">Ende des zweiten Intervalls.</param>
/// <returns>Ob der das erste Intervall im zweiten liegt</returns>
public static bool AreInBetweenDates(this DateTime start1, DateTime end1, DateTime start2, DateTime end2)
{
return start1 >= start2 && end1 <= end2;
}
public static bool IsIntervalOverlappingWithAbsenceTimeInterval(this DateTime start, DateTime end, DateTime absenceTimeStart, DateTime? absenceTimeEnd)
{
if (absenceTimeEnd == null)
{
return start >= absenceTimeStart && end >= absenceTimeStart;
}
var start2 = absenceTimeStart;
var end2 = absenceTimeEnd.Value;
return !(start >= start2 && start >= end2 || end <= start2 && end <= end2);
}
public static bool IsTimeZero(this DateTime dateTime)
{
return dateTime.Hour == 0 && dateTime.Minute == 0 && dateTime.Second == 0;
}
public static string GetIntervalDescription(this DateTime start, DateTime? end)
{
var result = string.Empty;
var isAllDay = start.IsTimeZero() && (end == null || end.Value.IsTimeZero());
var endTimeHasValue = end.HasValue;
if (isAllDay)
{
if (endTimeHasValue)
{
if (start.Date.Equals(end.Value.Date))
{
result += $" {start.ToShortDateString()}";
}
else
{
result += $" {start.ToShortDateString()} - {end.Value.ToShortDateString()}";
}
}
else
{
result += $" Ab dem {start.ToShortDateString()}";
}
}
else
{
if (endTimeHasValue)
{
if (start.Date.Equals(end.Value.Date))
{
result += $" {start:dd.MM.yyyy HH:mm} - {end.Value:HH:mm}";
}
else
{
result += $" {start:dd.MM.yyyy HH:mm} - {(end.Value.IsTimeZero() ? end.Value.ToString("dd.MM.yyyy") : end.Value.ToString("dd.MM.yyyy HH:mm"))}";
}
}
else
{
result += $" Ab dem {start:dd.MM.yyyy HH:mm}";
}
}
return result;
}
public static bool IsInInterval(this DateTime start, DateTime end, DateTime start2, DateTime end2)
{
var interval1 = new TimeInterval(start, end);
var interval2 = new TimeInterval(start2, end2);
return interval1.IntersectsWithExcludingBounds(interval2);
}
public static DateTime GetFirstOfMonth(this DateTime dateTime)
{
return new DateTime(dateTime.Year, dateTime.Month, 1);
}
public static DateTime GetServiceRecordNoDateTimeDate(this DateTime date)
{
return date.MergeDateAndTimeSpan(new TimeSpan(0, 0, 1));
}
public static DateTime? GetMin(this DateTime? d1, DateTime? d2)
{
if (d1 != null && d2 == null)
return d1;
if (d1 == null && d2 != null)
return d2;
if (d1 <= d2)
return d1;
return d2;
}
public static DateTime? GetMax(this DateTime? d1, DateTime? d2)
{
if (d1 != null && d2 == null)
return d1;
if (d1 == null && d2 != null)
return d2;
if (d1 >= d2)
return d1;
return d2;
}
public static DateTime GetLastOfMonth(this DateTime dateTime)
{
return dateTime.GetFirstOfMonth().AddMonths(1).AddDays(-1);
}
public static string GetDateString(this DateTime start, DateTime end)
{
return start.Date != end.Date ?
$"{start.ToShortDateString()} {start.ToShortTimeString()} - {end.ToShortDateString()} {end.ToShortTimeString()}" :
$"{start.ToShortDateString()} {start.ToShortTimeString()} - {end.ToShortTimeString()}";
}
}
}