using System; namespace Developpez.Dotnet { /// /// Permet d'utiliser des methodes d'extensions sur les types de Date. /// En particulier, permet d'utiliser des expressions "à la Ruby" en C# /// Par exemple, plutôt que de faire DateTime.Now.AddMinutes(5), on fera: /// 5.Minutes().FromNow() /// ) public static class DateExtensions { /// /// Retourne une durée correspondant au nombre de jours passé en paramètre /// /// Nombre de jours dans la période /// Une durée correspondant au nombre de jours spécifié public static TimeSpan Days(this int value) { return TimeSpan.FromDays(value); } /// /// Retourne une durée correspondant au nombre d'heures passé en paramètre /// /// Nombre de heures dans la période /// Une durée correspondant au nombre d'heures spécifié public static TimeSpan Hours(this int value) { return TimeSpan.FromHours(value); } /// /// Retourne une durée correspondant au nombre de minutes passé en paramètre /// /// Nombre de minutes dans la période /// Une durée correspondant au nombre de minutes spécifié public static TimeSpan Minutes(this int value) { return TimeSpan.FromMinutes(value); } /// /// Retourne une durée correspondant au nombre de secondes passé en paramètre /// /// Nombre de secondes dans la période /// Une durée correspondant au nombre de secondes spécifié public static TimeSpan Seconds(this int value) { return TimeSpan.FromSeconds(value); } /// /// Retourne une durée correspondant au nombre de millisecondes passé en paramètre /// /// Nombre de millisecondes dans la période /// Une durée correspondant au nombre de millisecondes spécifié public static TimeSpan Milliseconds(this int value) { return TimeSpan.FromMilliseconds(value); } /// /// Retourne une date correspondant à la durée précédant la date courante /// /// Durée que l'on veut soustraire a la date courante /// La date correspondant à la durée précédent la date courante public static DateTime Ago(this TimeSpan timeSpan) { return DateTime.Now - timeSpan; } /// /// Retourne une date correspondant à la durée suivant la date courante /// /// Durée que l'on veut ajouter a la date courante /// La date correspondant à la durée suivant la date courante public static DateTime FromNow(this TimeSpan timeSpan) { return DateTime.Now + timeSpan; } /// /// Retourne une date correspondant à la durée suivant la date de départ spécifiée /// /// Durée que l'on veut ajouter a la date de départ spécifiée /// Date de départ /// La date correspondant à la durée suivant la date de départ spécifiée public static DateTime From(this TimeSpan timeSpan, DateTime startDate) { return startDate + timeSpan; } /// /// Retourne une date correspondant à la durée précédent la date spécifiée /// /// Durée que l'on veut retrancher de la date spécifiée /// Date de fin /// La date correspondant à la durée précédent la date spécifiée public static DateTime Before(this TimeSpan timeSpan, DateTime endDate) { return endDate - timeSpan; } private static readonly DateTime _unixEpoch = new DateTime(1970, 1, 1); /// /// Convertit un DateTime en timestamp Unix /// /// La date à convertir /// Le timestamp Unix équivalent public static long ToUnixTimestamp(this DateTime dt) { TimeSpan span = dt - _unixEpoch; return (long)Math.Truncate(span.TotalSeconds); } /// /// Convertit un timestamp Unix en DateTime /// /// Le timestamp à convertir /// Le DateTime équivalent public static DateTime ToDateTime(this long timestamp) { return _unixEpoch.AddSeconds(timestamp); } /// /// Renvoie le prochain jour de la semaine spécifié à partir d'une date /// /// la date à partir de laquelle on recherche /// le jour de la semaine recherché /// Le prochain dayOfWeek spécifié à partir de la date public static DateTime Next(this DateTime from, DayOfWeek dayOfWeek) { int start = (int)from.DayOfWeek; int wanted = (int)dayOfWeek; if (wanted <= start) wanted += 7; return from.AddDays(wanted - start); } /// /// Renvoie le prochain jour de la semaine spécifié à partir de la date courante /// /// le jour de la semaine recherché /// Le prochain dayOfWeek spécifié à partir de la date courante public static DateTime Next(this DayOfWeek dayOfWeek) { return DateTime.Now.Next(dayOfWeek); } /// /// Renvoie le précédent jour de la semaine spécifié à partir d'une date /// /// la date à partir de laquelle on recherche /// le jour de la semaine recherché /// Le précédent dayOfWeek spécifié à partir de la date public static DateTime Previous(this DateTime from, DayOfWeek dayOfWeek) { int end = (int)from.DayOfWeek; int wanted = (int)dayOfWeek; if (wanted >= end) end += 7; return from.AddDays(wanted - end); } /// /// Renvoie le précédent jour de la semaine spécifié à partir de la date courante /// /// le jour de la semaine recherché /// Le précédent dayOfWeek spécifié à partir de la date courante public static DateTime Previous(DayOfWeek dayOfWeek) { return DateTime.Now.Previous(dayOfWeek); } /// /// Ajoute le nombre spécifié de jours ouvrés à la date /// /// Date d'origine /// Nombre de jours ouvrés à ajouter /// La date days jours ouvrés après date (ou avant si days est négatif) /// Cette méthode suppose que la semaine comporte 5 jours ouvrés, du lundi au vendredi. Les jours fériés ne sont pas pris en compte. public static DateTime AddWorkingDays(this DateTime date, int days) { if (days == 0) return date; int sign = days < 0 ? -1 : 1; while (days % 5 != 0 || !date.IsWorkingDay()) { date = date.AddDays(sign); if (!date.IsWorkingDay()) continue; days -= sign; } int nWeekEnds = days / 5; DateTime result = date.AddDays(days + nWeekEnds * 2); return result; } /// /// Indique si la date est un jour ouvré /// /// La date à vérifier /// true si la date est un jour ouvré, sinon false. /// Cette méthode suppose que la semaine comporte 5 jours ouvrés, du lundi au vendredi. Les jours fériés ne sont pas pris en compte. public static bool IsWorkingDay(this DateTime date) { return !(date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday); } } }