2016-06-27 01:45:38 +02:00
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 ,
2021-02-21 19:01:51 +01:00
Year ,
Hour
2016-06-27 01:45:38 +02:00
}
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
{
2020-10-13 14:35:06 +02:00
public static DateTimeUnit GetDateTimeUnit ( this DateTime Date1 , DateTime Date2 , TimeUnit unit )
2016-06-27 01:45:38 +02:00
{
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 / 7 m ) ;
ds . RestDays = totaldays - ( ds . UnitCount * 7 ) ;
break ;
case TimeUnit . Fortnightly :
ds . UnitCount = ( int ) ( totaldays / 14 m ) ;
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 ;
2020-10-13 14:35:06 +02:00
2016-06-27 01:45:38 +02:00
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 ;
}
2020-10-13 14:35:06 +02:00
2016-06-27 01:45:38 +02:00
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 )
{
2020-10-13 14:35:06 +02:00
if ( pForward )
2016-06-27 01:45:38 +02:00
{
return ( int ) Math . Ceiling ( pDateTime . Day / 7d ) ;
}
2020-10-13 14:35:06 +02:00
return ( int ) Math . Ceiling ( ( DateTime . DaysInMonth ( pDateTime . Year , pDateTime . Month ) - pDateTime . Day ) / 7d ) ;
2016-06-27 01:45:38 +02:00
}
2020-10-13 14:35:06 +02:00
public static bool InBetween ( this DateTime pDateTime , DateTime pSpanStart , DateTime pSpanStop , bool ignoreTimeAndCompareWholeDays )
2016-06-27 01:45:38 +02:00
{
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 ;
2019-01-05 17:03:44 -04:00
return lInfo . GetAbbreviatedDayName ( pDate . DayOfWeek ) + ", " + $"{pDate.Day:00}" + "." + $"{pDate.Month:00}" + "." + pDate . Year . ToString ( ) . Substring ( 2 ) ;
2016-06-27 01:45:38 +02:00
}
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 ) ) ;
}
}
2020-10-13 14:35:06 +02:00
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 ;
}
2016-06-27 01:45:38 +02:00
/// <summary>
/// Erzeugt aus zwei Datumsobjekten ein neues mit den Datumsangaben des ersten und den Zeitangaben des zweiten Parameters.
/// </summary>
2019-09-27 15:55:01 +02:00
/// <param name="first">Datum dessen Datewerte übernommen werden.</param>
2016-06-27 01:45:38 +02:00
/// <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 ) ;
}
2019-02-28 12:38:29 +01:00
public static DateTime MergeDateAndTimeSpan ( this DateTime pDate , TimeSpan pTimeSpan )
{
return new DateTime ( pDate . Year , pDate . Month , pDate . Day , pTimeSpan . Hours , pTimeSpan . Minutes , pTimeSpan . Seconds ) ;
}
2019-07-01 15:11:19 +02:00
public static WeekDays GetSchedulerWeekDays ( this DateTime pDateTime )
{
2020-10-13 14:35:06 +02:00
return ( WeekDays ) ( int ) Math . Pow ( 2 , ( double ) pDateTime . DayOfWeek ) ;
2019-07-01 15:11:19 +02:00
}
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 ;
}
}
2019-09-27 15:55:01 +02:00
/// <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 ;
}
2019-12-07 21:06:03 +01:00
public static bool IsIntervalOverlappingWithAbsenceTimeInterval ( this DateTime start , DateTime end , DateTime absenceTimeStart , DateTime ? absenceTimeEnd )
2019-12-03 13:00:04 +01:00
{
if ( absenceTimeEnd = = null )
{
return start > = absenceTimeStart & & end > = absenceTimeStart ;
}
2019-12-07 21:06:03 +01:00
var start2 = absenceTimeStart ;
var end2 = absenceTimeEnd . Value ;
return ! ( start > = start2 & & start > = end2 | | end < = start2 & & end < = end2 ) ;
2019-12-03 13:00:04 +01:00
}
2019-12-20 12:37:08 +01:00
public static bool IsTimeZero ( this DateTime dateTime )
2019-09-27 15:55:01 +02:00
{
2019-12-20 12:37:08 +01:00
return dateTime . Hour = = 0 & & dateTime . Minute = = 0 & & dateTime . Second = = 0 ;
}
public static string GetIntervalDescription ( this DateTime start , DateTime ? end )
{
var result = string . Empty ;
2019-09-27 15:55:01 +02:00
2019-12-20 12:37:08 +01:00
var isAllDay = start . IsTimeZero ( ) & & ( end = = null | | end . Value . IsTimeZero ( ) ) ;
var endTimeHasValue = end . HasValue ;
if ( isAllDay )
2019-09-27 15:55:01 +02:00
{
2019-12-20 12:37:08 +01:00
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()}" ;
}
2019-09-27 15:55:01 +02:00
}
2019-12-20 12:37:08 +01:00
else
2019-09-27 15:55:01 +02:00
{
2019-12-20 12:37:08 +01:00
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}" ;
}
2019-09-27 15:55:01 +02:00
}
2019-12-20 12:37:08 +01:00
return result ;
2019-12-19 14:27:03 +01:00
}
2020-08-04 12:45:46 +02:00
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 ) ;
}
2020-08-31 17:44:05 +02:00
public static DateTime GetFirstOfMonth ( this DateTime dateTime )
{
return new DateTime ( dateTime . Year , dateTime . Month , 1 ) ;
}
2020-09-21 11:57:10 +02:00
public static DateTime GetServiceRecordNoDateTimeDate ( this DateTime date )
{
return date . MergeDateAndTimeSpan ( new TimeSpan ( 0 , 0 , 1 ) ) ;
}
2020-10-13 14:35:06 +02:00
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 ;
}
2020-11-09 17:55:01 +01:00
public static DateTime GetLastOfMonth ( this DateTime dateTime )
{
return dateTime . GetFirstOfMonth ( ) . AddMonths ( 1 ) . AddDays ( - 1 ) ;
}
2020-12-01 12:29:12 +01:00
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()}" ;
}
2021-01-05 19:19:51 +01:00
public static DateTime MergeDateWithHoursMinutesSeconds ( this DateTime date , int hours , int minutes , int seconds = 0 )
{
var h = hours > = 0 & & hours < 24 ? hours : 0 ;
var m = minutes > = 0 & & minutes < 60 ? minutes : 0 ;
var s = seconds > = 0 & & seconds < 60 ? seconds : 0 ;
return date . MergeDatesByDate ( new DateTime ( 2000 , 1 , 1 , h , m , s ) ) ;
}
2016-06-27 01:45:38 +02:00
}
}