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);
}
}
}