Extension methods for the DateTime class.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace Extensions
{
public static class DateTimeExtensions
{
private static readonly DateTime _date1970 = new DateTime(1970, 1, 1);
private const int EVENING_ENDS = 2;
private const int MORNING_ENDS = 12;
private const int AFTERNOON_ENDS = 6;
/// <summary>
/// Gets the System UTC Offset.
/// </summary>
/// <value>The UTC offset.</value>
public static double UtcOffset
{
get
{
return DateTime.Now.Subtract(DateTime.UtcNow).TotalHours;
}
}
/// <summary>
/// Converts a nullable date/time value to UTC.
/// </summary>
/// <param name="dateTime">The nullable date/time</param>
/// <returns>The nullable date/time in UTC</returns>
public static DateTime? ToUniversalTime(this DateTime? dateTime)
{
return dateTime.HasValue ? dateTime.Value.ToUniversalTime() : (DateTime?)null;
}
/// <summary>
/// Converts a nullable UTC date/time value to local time.
/// </summary>
/// <param name="dateTime">The nullable UTC date/time</param>
/// <returns>The nullable UTC date/time as local time</returns>
public static DateTime? ToLocalTime(this DateTime? dateTime)
{
return dateTime.HasValue ? dateTime.Value.ToLocalTime() : (DateTime?)null;
}
public static long ToJavaScriptTicks(this DateTime dateTime)
{
DateTimeOffset utcDateTime = dateTime.ToUniversalTime();
long javaScriptTicks = (utcDateTime.Ticks - BeginOfEpoch.Ticks) / (long)10000;
return javaScriptTicks;
}
/// <summary>
/// Determines whether the specified DateTime object occurs on a weekend.
/// </summary>
/// <param name="self">The DateTime object.</param>
/// <returns></returns>
public static bool IsWeekend(this DateTime self)
{
return (self.DayOfWeek == DayOfWeek.Sunday || self.DayOfWeek == DayOfWeek.Saturday);
}
/// <summary>
/// Determines whether the specified DayOfWeek occurs on a weekend.
/// </summary>
/// <param name="self">The Day of Week.</param>
/// <returns></returns>
public static bool IsWeekend(this DayOfWeek self)
{
return !self.IsWeekday();
}
/// <summary>
/// Determines whether the specified DateTime occurs on a week day.
/// </summary>
/// <param name="self">The DateTime object.</param>
/// <returns></returns>
public static bool IsWeekday(this DateTime self)
{
return !self.IsWeekend();
}
/// <summary>
/// Determines whether the specified DayOfWeek occurs on a week day.
/// </summary>
/// <param name="self">The DayOfWeek.</param>
/// <returns></returns>
public static bool IsWeekday(this DayOfWeek self)
{
switch (self)
{
case DayOfWeek.Sunday:
case DayOfWeek.Saturday:
return false;
default:
return true;
}
}
/// <summary>
/// Add number of working days to a DateTime.
/// </summary>
/// <param name="self">The self.</param>
/// <param name="days">The days.</param>
/// <example>
/// // due date is in 10 working days.
/// DateTime due = DateTime.Today.AddWorkDays(10);
/// </example>
/// <remarks>Does not take into account holidays.</remarks>
/// <returns></returns>
public static DateTime AddWorkDays(this DateTime self, int days)
{
// start from a weekday
while (self.DayOfWeek.IsWeekday())
{
self = self.AddDays(1.0);
}
for (int i = 0; i < days; ++i)
{
self = self.AddDays(1.0);
while (self.DayOfWeek.IsWeekday())
{
self = self.AddDays(1.0);
}
}
return self;
}
/// <summary>
/// Determines if the date is between the two provided dates.
///
/// Example:
/// var today = DateTime.Now;
/// var start = new DateTime(2012, 1, 1);
/// var end = new DateTime(2013, 11, 25);
///
/// Boolean isBetween = today.IsBetween(start, end);
/// </summary>
/// <param name="self">The self.</param>
/// <param name="startDate">The start date.</param>
/// <param name="endDate">The end date.</param>
/// <param name="compareTime">The compare time.</param>
/// <returns></returns>
public static Boolean IsBetween(this DateTime self, DateTime startDate, DateTime endDate, Boolean compareTime = false)
{
return compareTime ?
self >= startDate && self <= endDate :
self.Date >= startDate.Date && self.Date <= endDate.Date;
}
/// <summary>
/// Determines if a DateTime is within a given DateTime range.
/// </summary>
/// <param name="self">The current DateTime.</param>
/// <param name="beginDate">The beginning DateTime.</param>
/// <param name="endDate">The ending DateTime.</param>
/// <example>
/// var monday = DateTime.Now.ThisWeekMonday();
/// var friday = DateTime.Now.ThisWeekFriday();
///
/// If (DateTime.Now.IsInRange(monday, friday)
/// // do something...
/// </example>
/// <returns></returns>
public static bool IsInRange(this DateTime self, DateTime beginDate, DateTime endDate)
{
return (self >= beginDate && self <= endDate);
}
/// <summary>
/// Determines whether the set year is a Leap Year.
/// </summary>
/// <example>
/// bool isLeap = DateTime.Today.IsLeapYear();
/// </example>
/// <param name="self">The datetime object.</param>
/// <returns>True if it is a Leap Year, otherwise false.</returns>
public static bool IsLeapYear(this DateTime self)
{
return (DateTime.DaysInMonth(self.Year, 2) == 29);
}
/// <summary>
/// Determines whether the DateTime value is the Leap Day.
/// </summary>
/// <example>
/// bool isLeapDay = new DateTime(2012, 2, 29).IsLeapDay();
/// </example>
/// <param name="self">The DateTime object.</param>
/// <returns></returns>
public static Boolean IsLeapDay(this DateTime self)
{
return(self.Month == 2 && self.Day == 29);
}
/// <summary>
/// Determines whether the given date is the last day of the month.
/// </summary>
/// <example>
/// var isLastDay = DateTime.Now.IsLastDayOfMonth()
/// </example>
/// <param name="self">The self.</param>
/// <returns></returns>
public static bool IsLastDayOfMonth(this DateTime self)
{
return self == new DateTime(self.Year, self.Month, 1).AddMonths(1).AddDays(-1);
}
/// <summary>
/// Determines if the two date ranges intersect.
///
/// Example:
/// bool eventsInterect = eventXStartDate.Intersects(eventXEndDate, eventYStartDate, eventYEndDate);
/// </summary>
/// <param name="self">The start date.</param>
/// <param name="endDate">The end date.</param>
/// <param name="intersectingStartDate">The intersecting start date.</param>
/// <param name="intersectingEndDate">The intersecting end date.</param>
/// <returns></returns>
public static bool Intersects(this DateTime self, DateTime endDate, DateTime intersectingStartDate, DateTime intersectingEndDate)
{
return (intersectingEndDate >= self && intersectingStartDate <= endDate);
}
/// <summary>
/// Calculates the age based on today.
/// </summary>
/// <param name="self">The date of birth.</param>
/// <returns>The calculated age.</returns>
public static int Age(this DateTime self)
{
return Age(self, DateTime.Today.Date);
}
/// <summary>
/// Calculates the age based on a passed reference date.
/// </summary>
/// <param name="self">The date of birth.</param>
/// <param name="referenceDate">The reference date to calculate on.</param>
/// <returns>The calculated age.</returns>
public static int Age(this DateTime self, DateTime referenceDate)
{
int years = referenceDate.Year - self.Year;
if (referenceDate.Month < self.Month ||
(referenceDate.Month == self.Month && referenceDate.Day < self.Day))
{
--years;
}
return years;
}
/// <summary>
/// Generates a humanized Age string.
///
/// Based on: http://stackoverflow.com/a/3055445
/// </summary>
/// <param name="self">The DateTime.</param>
/// <returns>ex: 1 day, </returns>
public static string HumanizeAge(this DateTime self)
{
DateTime dt = DateTime.Today;
int days = dt.Day - self.Day;
if (days < 0)
{
dt = dt.AddMonths(-1);
days += DateTime.DaysInMonth(dt.Year, dt.Month);
}
int months = dt.Month - self.Month;
if (months < 0)
{
dt = dt.AddYears(-1);
months += 12;
}
int years = dt.Year - self.Year;
if (years <= 0)
{
if (months >= 1)
{
return string.Format("{0} month{1} and {2} day{3}",
months,
(months == 1) ? "" : "s",
days,
(days == 1) ? "" : "s");
}
if (months <= 0)
{
return string.Format("{0} day{1}",
days,
(days == 1) ? "" : "s");
}
}
return string.Format("{0} year{1}, {2} month{3} and {4} day{5}",
years,
(years == 1) ? "" : "s",
months,
(months == 1) ? "" : "s",
days,
(days == 1) ? "" : "s");
}
/// <summary>
/// Gets the date range to.
///
/// Example: Get next 80 days
/// var dateRange = DateTime.Now.GetDateRangeTo(DateTime.Now.AddDays(80));
/// </summary>
/// <param name="self">The self.</param>
/// <param name="toDate">To date.</param>
/// <returns></returns>
public static IEnumerable<DateTime> GetDateRangeTo(this DateTime self, DateTime toDate)
{
IEnumerable<int> range = Enumerable.Range(0, new TimeSpan(toDate.Ticks - self.Ticks).Days);
return from p in range
select self.Date.AddDays(p);
}
/// <summary>
/// Date diff (SQL style).
///</summary>
/// <example>
/// Accepted DateParts:
///
/// "year" (abbr. "yy", "yyyy")
/// "quarter" (abbr. "qq", "q")
/// "month" (abbr. "mm", "m")
/// "day" (abbr. "dd", "d")
/// "week" (abbr. "wk", "ww")
/// "hour" (abbr. "hh")
/// "minute" (abbr. "mi", "n")
/// "second" (abbr. "ss", "s")
/// "millisecond" (abbr. "ms")
///
/// Examples:
///
/// Gets the total days from 01/01/2000:
///
/// DateTime dt = new DateTime(2000, 01, 01);
/// Int64 days = dt.DateDiff("day", DateTime.Now);
///
/// Gets the total hours from 01/01/2000:
///
/// Int64 hours = dt.DateDiff("hour", DateTime.Now);
/// </example>
/// <param name="startDate">The start date.</param>
/// <param name="datePart">The date part.</param>
/// <param name="endDate">The end date.</param>
/// <returns></returns>
public static long DateDiff(DateTime startDate, string datePart, DateTime endDate)
{
long dateDiffVal;
Calendar cal = System.Threading.Thread.CurrentThread.CurrentCulture.Calendar;
var ts = new TimeSpan(endDate.Ticks - startDate.Ticks);
switch (datePart.ToLower().Trim())
{
case "year":
case "yy":
case "yyyy":
dateDiffVal = (cal.GetYear(endDate) - cal.GetYear(startDate));
break;
case "quarter":
case "qq":
case "q":
dateDiffVal = ((((cal.GetYear(endDate) -
cal.GetYear(startDate)) * 4) +
((cal.GetMonth(endDate) - 1) / 3)) -
((cal.GetMonth(startDate) - 1) / 3));
break;
case "month":
case "mm":
case "m":
dateDiffVal = (((cal.GetYear(endDate) - cal.GetYear(startDate)) * 12 +
cal.GetMonth(endDate)) -
cal.GetMonth(startDate));
break;
case "day":
case "d":
case "dd":
dateDiffVal = (long)ts.TotalDays;
break;
case "week":
case "wk":
case "ww":
dateDiffVal = (long)(ts.TotalDays / 7);
break;
case "hour":
case "hh":
dateDiffVal = (long)ts.TotalHours;
break;
case "minute":
case "mi":
case "n":
dateDiffVal = (long)ts.TotalMinutes;
break;
case "second":
case "ss":
case "s":
dateDiffVal = (long)ts.TotalSeconds;
break;
case "millisecond":
case "ms":
dateDiffVal = (long)ts.TotalMilliseconds;
break;
default:
throw new Exception(String.Format("DatePart \"{0}\" is unknown.", datePart));
}
return dateDiffVal;
}
/// <summary>
/// Converts a DateTime to a RFC822 date string.
///
/// Example:
/// var s = DateTime.Now.ToRFC822DateString();
/// </summary>
/// <param name="self">The self.</param>
/// <returns>The specified date formatted as a RFC822 date string.</returns>
public static string ToRfc822DateString(this DateTime self)
{
int offset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now).Hours;
string timeZone = string.Format("+{0}", offset.ToString(CultureInfo.InvariantCulture).PadLeft(2, '0'));
if (offset < 0)
{
int i = offset * -1;
timeZone = string.Format("-{0}", i.ToString(CultureInfo.InvariantCulture).PadLeft(2, '0'));
}
return self.ToString(string.Format("ddd, dd MMM yyyy HH:mm:ss {0}", timeZone.PadRight(5, '0')), CultureInfo.GetCultureInfo("en-US"));
}
/// <summary>
/// Get milliseconds of UNIX area.
/// This is the milliseconds since 1/1/1970
/// </summary>
/// <param name="self">Up to which time.</param>
/// <returns>number of milliseconds.</returns>
public static long GetEpoch(this DateTime self)
{
TimeSpan ts = self.Subtract(_date1970);
return (long)ts.TotalMilliseconds;
}
/// <summary>
/// Get milliseconds of UNIX area.
/// This is the milliseconds since 1/1/1970
/// </summary>
/// <param name="self">The date time.</param>
/// <returns>number of milliseconds.</returns>
/// <remarks>This is the same as GetEpoch,
/// but more descriptive.
/// </remarks>
public static long ToUnixTime(this DateTime self)
{
return GetEpoch(self);
}
/// <summary>
/// Generates a DateTime object from a UNIX/Epoch timestamp value.
/// DateTimeKind is UTC.
/// See: http://stackoverflow.com/a/7844741
///
/// </summary>
/// <param name="self">The UNIX/Epoch timestamp value.</param>
/// <returns></returns>
public static DateTime FromUnixTime(this long self)
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return epoch.AddSeconds(self);
}
/// <summary>
/// Generates a human friendly string from the DateTime object.
/// </summary>
/// <param name="self">The DateTime object.</param>
/// <param name="isUtc">Is the DateTime object in UTC?</param>
/// <returns>A nicely formatted duration. ex: "3 seconds ago", "4 hours ago"</returns>
public static string Humanize(this DateTime self, bool isUtc = false)
{
TimeSpan timespan = isUtc ? (DateTime.UtcNow - self) : (DateTime.Now - self);
var totalDays = (int)timespan.TotalDays;
var totalHours = (int)timespan.TotalHours;
var totalMinutes = (int)timespan.TotalMinutes;
var totalSeconds = (int)timespan.TotalSeconds;
var sb = new StringBuilder();
// A year or more? Do "[Y] years and [M] months ago"
if (totalDays >= 365)
{
// Years
int nYears = totalDays / 365;
sb.Append(nYears);
sb.Append(nYears > 1 ? " years" : " year");
// Months
int remainingDays = totalDays - (nYears * 365);
int nMonths = remainingDays / 30;
if (nMonths == 1)
{
sb.Append(" and ").Append(nMonths).Append(" month");
}
else if (nMonths > 1)
{
sb.Append(" and ").Append(nMonths).Append(" months");
}
}
// More than 60 days? (approx. 2 months or 8 weeks)
else if (totalDays >= 60)
{
// Do months
int nMonths = totalDays / 30;
sb.Append(nMonths).Append(" months");
}
// Weeks? (7 days or more)
else if (totalDays >= 7)
{
int nWeeks = totalDays / 7;
sb.Append(nWeeks);
sb.Append(nWeeks == 1 ? " week" : " weeks");
}
// Days? (1 or more)
else if (totalDays >= 1)
{
int nDays = totalDays;
sb.Append(nDays);
sb.Append(nDays == 1 ? " day" : " days");
}
// Hours?
else if (totalHours >= 1)
{
int nHours = totalHours;
sb.Append(nHours);
sb.Append(nHours == 1 ? " hour" : " hours");
}
// Minutes?
else if (totalMinutes >= 1)
{
int nMinutes = totalMinutes;
sb.Append(nMinutes);
sb.Append(nMinutes == 1 ? " minute" : " minutes");
}
// Seconds?
else if (totalSeconds >= 1)
{
int nSeconds = totalSeconds;
sb.Append(nSeconds);
sb.Append(nSeconds == 1 ? " second" : " seconds");
}
// Just say "1 second" as the smallest unit of time
else
{
sb.Append("1 second");
}
sb.Append(" ago");
// For anything more than 6 months back,
// put "([Month] [Year])" at the end, for better reference
if (totalDays >= 30 * 6)
{
sb.AppendFormat(" ({0} {1})", self.ToString("MMMM"), self.Year);
}
return sb.ToString();
}
/// <summary>
/// Generates a human friendly string from the DateTime object.
/// </summary>
/// <param name="self">The DateTime object.</param>
/// <param name="sinceDate">The when date.</param>
/// <returns>A nicely formatted duration. ex: "3 seconds ago", "4 hours ago"</returns>
public static string Humanize(this DateTime self, DateTime sinceDate)
{
TimeSpan timespan = (self - sinceDate);
var totalDays = (int)timespan.TotalDays;
var totalHours = (int)timespan.TotalHours;
var totalMinutes = (int)timespan.TotalMinutes;
var totalSeconds = (int)timespan.TotalSeconds;
var sb = new StringBuilder();
// A year or more? Do "[Y] years and [M] months ago"
if (totalDays >= 365)
{
// Years
int nYears = totalDays / 365;
sb.Append(nYears);
sb.Append(nYears > 1 ? " years" : " year");
// Months
int remainingDays = totalDays - (nYears * 365);
int nMonths = remainingDays / 30;
if (nMonths == 1)
{
sb.Append(" and ").Append(nMonths).Append(" month");
}
else if (nMonths > 1)
{
sb.Append(" and ").Append(nMonths).Append(" months");
}
}
// More than 60 days? (approx. 2 months or 8 weeks)
else if (totalDays >= 60)
{
// Do months
int nMonths = totalDays / 30;
sb.Append(nMonths).Append(" months");
}
// Weeks? (7 days or more)
else if (totalDays >= 7)
{
int nWeeks = totalDays / 7;
sb.Append(nWeeks);
sb.Append(nWeeks == 1 ? " week" : " weeks");
}
// Days? (1 or more)
else if (totalDays >= 1)
{
int nDays = totalDays;
sb.Append(nDays);
sb.Append(nDays == 1 ? " day" : " days");
}
// Hours?
else if (totalHours >= 1)
{
int nHours = totalHours;
sb.Append(nHours);
sb.Append(nHours == 1 ? " hour" : " hours");
}
// Minutes?
else if (totalMinutes >= 1)
{
int nMinutes = totalMinutes;
sb.Append(nMinutes);
sb.Append(nMinutes == 1 ? " minute" : " minutes");
}
// Seconds?
else if (totalSeconds >= 1)
{
int nSeconds = totalSeconds;
sb.Append(nSeconds);
sb.Append(nSeconds == 1 ? " second" : " seconds");
}
// Just say "1 second" as the smallest unit of time
else
{
sb.Append("1 second");
}
sb.Append(" ago");
// For anything more than 6 months back,
// put "([Month] [Year])" at the end, for better reference
if (totalDays >= 30 * 6)
{
sb.AppendFormat(" ({0} {1})", self.ToString("MMMM"), self.Year);
}
return sb.ToString();
}
/// <summary>
/// Represents dates in a user friendly way.
///
/// For example, when displaying a news article on a webpage, you might want
/// articles that were published one day ago to have their publish dates
/// represented as "yesterday at 12:30 PM". Or if the article was publish today,
/// show the date as "Today, 3:33 PM".
/// </summary>
/// <param name="self">The date.</param>
/// <param name="culture">Specific Culture</param>
/// <returns>ex: "yesterday at 12:30 PM"</returns>
public static string ToFriendlyDateString(this DateTime self, CultureInfo culture)
{
var sbFormattedDate = new StringBuilder();
if (self.Date == DateTime.Today)
{
sbFormattedDate.Append("Today");
}
else if (self.Date == DateTime.Today.AddDays(-1))
{
sbFormattedDate.Append("Yesterday");
}
else if (self.Date > DateTime.Today.AddDays(-6))
{
// *** Show the Day of the week
sbFormattedDate.Append(self.ToString("dddd").ToString(culture));
}
else
{
sbFormattedDate.Append(self.ToString("MMMM dd, yyyy").ToString(culture));
}
//append the time portion to the output
sbFormattedDate.Append(" at ").Append(self.ToString("t").ToLower());
return sbFormattedDate.ToString();
}
/// <summary>
/// Represents dates in a user friendly way.
///
/// For example, when displaying a news article on a webpage, you might want
/// articles that were published one day ago to have their publish dates
/// represented as "yesterday at 12:30 PM". Or if the article was publish today,
/// show the date as "Today, 3:33 PM".
/// </summary>
/// <param name="self">The date.</param>
/// <returns>ex: "yesterday at 12:30 PM"</returns>
public static string ToFriendlyDateString(this DateTime self)
{
return ToFriendlyDateString(self, CultureInfo.CurrentCulture);
}
/// <summary>
/// Get the elapsed time since the DateTime object.
/// </summary>
/// <param name="self">Input DateTime</param>
/// <param name="isUtc">Is the DateTime object in UTC?</param>
/// <example>
/// DateTime dtStart = DateTime.Now;
/// // Do something here...
/// Console.WriteLine(dtStart.Elapsed().TotalMilliseconds);
/// </example>
/// <returns>
/// Returns a TimeSpan value with the elapsed time since the self DateTime
/// </returns>
public static TimeSpan Elapsed(this DateTime self, bool isUtc = false)
{
return isUtc ? DateTime.UtcNow.Subtract(self) : DateTime.Now.Subtract(self);
}
/// <summary>
/// Gest the elapsed seconds since the DateTime.
/// </summary>
/// <example>
/// DateTime dtStart = DateTime.Now;
/// // Do something
/// Double elapsed = dtStart.ElapsedSeconds();
/// </example>
/// <param name="self">The DateTime object.</param>
/// <param name="isUtc">Is the DateTime object in UTC?</param>
/// <returns></returns>
public static Double ElapsedSeconds(this DateTime self, bool isUtc = false)
{
return isUtc ? DateTime.UtcNow.Subtract(self).TotalSeconds : DateTime.Now.Subtract(self).TotalSeconds;
}
/// <summary>
/// Gest the elapsed seconds since the input DateTime.
/// </summary>
/// <param name="input">Input DateTime</param>
/// <returns>Returns a Double value with the elapsed seconds since the input
/// DateTime.
/// </returns>
/// <example>
/// Double elapsed = dtStart.ElapsedSeconds();
/// </example>
/// <seealso cref="Elapsed()"/>
public static Double ElapsedSeconds(this DateTime self)
{
return DateTime.Now.Subtract(self).TotalSeconds;
}
/// <summary>
/// Gets a new DateTime object corresponding to first day
/// of the month.
/// </summary>
/// <example>
/// var firstDay = DateTime.Now.MonthStart();
/// </example>
/// <param name="self">The DateTime object.</param>
/// <returns></returns>
public static DateTime MonthStart(this DateTime self)
{
return new DateTime(self.Year, self.Month, 1);
}
/// <summary>
/// Gets a new DateTime object corresponding to last day
/// of the month.
/// </summary>
/// <example>
/// var lastDay = DateTime.Now.MonthEnd();
/// </example>
/// <param name="self">The DateTime object.</param>
/// <returns></returns>
public static DateTime MonthEnd(this DateTime self)
{
DateTime endOfTheMonth = new DateTime(self.Year, self.Month, 1).AddMonths(1).AddDays(-1);
return endOfTheMonth;
}
/// <summary>
/// Gets a DateTime object corresponding to the beginning of the day.
/// </summary>
/// <param name="self">The DateTime object.</param>
/// <example>
/// var dayBegins = DateTime.Now.DayStart();
/// </example>
/// <returns></returns>
public static DateTime DayStart(this DateTime self)
{
return new DateTime(self.Year, self.Month, self.Day);
}
/// <summary>
/// Gets a DateTime object corresponding to the end of the day.
/// </summary>
/// <param name="self">The DateTime object.</param>
/// <example>
/// var dayEnds = DateTime.Now.DayEnd();
/// </example>
/// <returns></returns>
public static DateTime DayEnd(this DateTime self)
{
return new DateTime(self.Year, self.Month, self.Day, 23, 59, 59, 999);
}
/// <summary>
/// Returns the date at 12:00:00 for the specified DateTime
/// </summary>
/// <param name="time">The current date</param>
/// <returns></returns>
public static DateTime Noon(this DateTime time)
{
return time.SetTime(12, 0, 0);
}
/// <summary>
/// Returns the date at 00:00:00 for the specified DateTime
/// </summary>
/// <param name="time">The current date</param>
/// <returns></returns>
public static DateTime Midnight(this DateTime time)
{
return time.SetTime(0, 0, 0, 0);
}
/// <summary>
/// Get the number of days within that year.
/// </summary>
/// <param name="year">The year.</param>
/// <returns>the number of days within that year</returns>
public static int GetDays(int year)
{
return GetDays(year, CultureInfo.CurrentCulture);
}
/// <summary>
/// Get the number of days within that year.
/// Uses the culture specified.
/// </summary>
/// <param name="year">The year.</param>
/// <param name="culture">Specific culture</param>
/// <returns>the number of days within that year</returns>
public static int GetDays(int year, CultureInfo culture)
{
var first = new DateTime(year, 1, 1, culture.Calendar);
var last = new DateTime(year + 1, 1, 1, culture.Calendar);
return GetDays(first, last);
}
/// <summary>
/// Get the number of days within that date year.
/// </summary>
/// <param name="self">The date.</param>
/// <returns>the number of days within that year</returns>
public static int GetDays(this DateTime self)
{
return GetDays(self.Year, CultureInfo.CurrentCulture);
}
/// <summary>
/// Get the number of days within that date year.
/// </summary>
/// <param name="self">The date.</param>
/// <param name="culture">Specific culture</param>
/// <returns>the number of days within that year</returns>
public static int GetDays(this DateTime self, CultureInfo culture)
{
return GetDays(self.Year, culture);
}
/// <summary>
/// Get the number of days between two dates.
/// </summary>
/// <param name="self">The origin year.</param>
/// <param name="toDate">To year</param>
/// <returns>The number of days between the two years</returns>
public static int GetDays(this DateTime self, DateTime toDate)
{
return Convert.ToInt32(toDate.Subtract(self).TotalDays);
}
/// <summary>
/// Returns the number of days in the month of the provided date.
/// </summary>
/// <param name="self">The date.</param>
/// <returns>The number of days.</returns>
public static int GetCountDaysOfMonth(this DateTime self)
{
DateTime nextMonth = self.AddMonths(1);
return new DateTime(nextMonth.Year, nextMonth.Month, 1).AddDays(-1).Day;
}
/// <summary>
/// Indicates whether the source DateTime is before the supplied DateTime.
/// </summary>
/// <param name="self">The source DateTime.</param>
/// <param name="other">The compared DateTime.</param>
/// <returns>True if the source is before the other DateTime, False otherwise</returns>
public static bool IsBefore(this DateTime self, DateTime other)
{
return self.CompareTo(other) < 0;
}
/// <summary>
/// Indicates whether the source DateTime is before the supplied DateTime.
/// </summary>
/// <param name="self">The source DateTime.</param>
/// <param name="other">The compared DateTime.</param>
/// <returns>True if the source is before the other DateTime, False otherwise</returns>
public static bool IsAfter(this DateTime self, DateTime other)
{
return self.CompareTo(other) > 0;
}
/// <summary>
/// Gets a DateTime representing Next Day.
/// </summary>
/// <param name="self">The current day</param>
/// <returns>The next Day.</returns>
public static DateTime Tomorrow(this DateTime self)
{
return self.AddDays(1);
}
/// <summary>
/// Gets a DateTime representing Previous Day.
/// </summary>
/// <param name="self">The current day</param>
/// <returns>The previous Day.</returns>
public static DateTime Yesterday(this DateTime self)
{
return self.AddDays(-1);
}
/// <summary>
/// Indicates whether the date is today.
/// </summary>
/// <param name="self">The date.</param>
/// <returns>
/// <c>true</c> if the specified date is today; otherwise, <c>false</c>.
/// </returns>
public static bool IsToday(this DateTime self)
{
return (self.Date == DateTime.Today);
}
/// <summary>
/// Sets the time on the specified DateTime value.
/// </summary>
/// <param name="self">The base date.</param>
/// <param name="hours">The hours to be set.</param>
/// <param name="minutes">The minutes to be set.</param>
/// <param name="seconds">The seconds to be set.</param>
/// <returns>The DateTime including the new time value</returns>
public static DateTime SetTime(this DateTime self, int hours, int minutes, int seconds)
{
return self.SetTime(new TimeSpan(hours, minutes, seconds));
}
/// <summary>
/// Sets the time on the specified DateTime value.
/// </summary>
/// <param name="self">The base date.</param>
/// <param name="hours">The hour</param>
/// <param name="minutes">The minute</param>
/// <param name="seconds">The second</param>
/// <param name="milliseconds">The millisecond</param>
/// <remarks>Added overload for milliseconds - jtolar</remarks>
/// <returns>The DateTime including the new time value</returns>
public static DateTime SetTime(this DateTime self, int hours, int minutes, int seconds, int milliseconds)
{
return self.SetTime(new TimeSpan(0, hours, minutes, seconds, milliseconds));
}
/// <summary>
/// Sets the time on the specified DateTime value.
/// </summary>
/// <param name="self">The base date.</param>
/// <param name="time">The TimeSpan to be applied.</param>
/// <returns>The DateTime including the new time value</returns>
public static DateTime SetTime(this DateTime self, TimeSpan time)
{
return self.Date.Add(time);
}
/// <summary>
/// Converts a DateTime into a DateTimeOffset using the local system time zone.
/// </summary>
/// <param name="self">The local DateTime.</param>
/// <returns>The converted DateTimeOffset</returns>
public static DateTimeOffset ToDateTimeOffset(this DateTime self)
{
return self.ToDateTimeOffset(null);
}
/// <summary>
/// Converts a DateTime into a DateTimeOffset using the specified time zone.
/// </summary>
/// <param name="self">The local DateTime.</param>
/// <param name="localTimeZone">The local time zone.</param>
/// <returns>The converted DateTimeOffset</returns>
public static DateTimeOffset ToDateTimeOffset(this DateTime self, TimeZoneInfo localTimeZone)
{
localTimeZone = (localTimeZone ?? TimeZoneInfo.Local);
if (self.Kind != DateTimeKind.Unspecified)
{
self = new DateTime(self.Ticks, DateTimeKind.Unspecified);
}
return TimeZoneInfo.ConvertTimeToUtc(self, localTimeZone);
}
/// <summary>
/// Return a period "Morning", "Afternoon", or "Evening"
/// </summary>
/// <param name="self">The date.</param>
/// <returns>The period "morning", "afternoon", or "evening"</returns>
public static string GetPeriodOfDay(this DateTime self)
{
int hour = self.Hour;
if (hour < EVENING_ENDS)
{
return "evening";
}
if (hour < MORNING_ENDS)
{
return "morning";
}
return hour < AFTERNOON_ENDS ? "afternoon" : "evening";
}
public static int TotalDaysAgo(this DateTimeOffset d)
{
return Convert.ToInt32(Math.Round(DateTimeOffset.Now.Subtract(d).TotalDays));
}
/// <summary>
/// Extension method to round a datetime to the nearest unit timespan.
/// </summary>
/// <param name="datetime">Datetime object we're rounding.</param>
/// <param name="roundingInterval">Timespan rounding period.s</param>
/// <returns>Rounded datetime</returns>
public static DateTime Round(this DateTime datetime, TimeSpan roundingInterval)
{
return new DateTime((datetime - DateTime.MinValue).Round(roundingInterval).Ticks);
}
/// <summary>
/// Extension method to explicitly round up to the nearest timespan interval.
/// </summary>
/// <param name="time">Base datetime object to round up.</param>
/// <param name="d">Timespan interval for rounding</param>
/// <returns>Rounded datetime</returns>
public static DateTime RoundUp(this DateTime time, TimeSpan d)
{
if (d == TimeSpan.Zero)
{
// divide by zero exception
return time;
}
return new DateTime(((time.Ticks + d.Ticks - 1) / d.Ticks) * d.Ticks);
}
/// <summary>
/// Converts the specified time from the <paramref name="from"/> time zone to the <paramref name="to"/> time zone
/// </summary>
/// <param name="time">The time to be converted in terms of the <paramref name="from"/> time zone</param>
/// <param name="from">The time zone the specified <paramref name="time"/> is in</param>
/// <param name="to">The time zone to be converted to</param>
/// <param name="strict">True for strict conversion, this will throw during ambiguitities, false for lenient conversion</param>
/// <returns>The time in terms of the to time zone</returns>
public static DateTime ConvertTo(this DateTime time, DateTimeZone from, DateTimeZone to, bool strict = false)
{
if (ReferenceEquals(from, to)) return time;
if (strict)
{
return from.AtStrictly(LocalDateTime.FromDateTime(time)).WithZone(to).ToDateTimeUnspecified();
}
return from.AtLeniently(LocalDateTime.FromDateTime(time)).WithZone(to).ToDateTimeUnspecified();
}
/// <summary>
/// Converts the specified time from UTC to the <paramref name="to"/> time zone
/// </summary>
/// <param name="time">The time to be converted expressed in UTC</param>
/// <param name="to">The destinatio time zone</param>
/// <param name="strict">True for strict conversion, this will throw during ambiguitities, false for lenient conversion</param>
/// <returns>The time in terms of the <paramref name="to"/> time zone</returns>
public static DateTime ConvertFromUtc(this DateTime time, DateTimeZone to, bool strict = false)
{
return time.ConvertTo(TimeZones.Utc, to, strict);
}
/// <summary>
/// Converts the specified time from the <paramref name="from"/> time zone to <see cref="TimeZones.Utc"/>
/// </summary>
/// <param name="time">The time to be converted in terms of the <paramref name="from"/> time zone</param>
/// <param name="from">The time zone the specified <paramref name="time"/> is in</param>
/// <param name="strict">True for strict conversion, this will throw during ambiguitities, false for lenient conversion</param>
/// <returns>The time in terms of the to time zone</returns>
public static DateTime ConvertToUtc(this DateTime time, DateTimeZone from, bool strict = false)
{
if (strict)
{
return from.AtStrictly(LocalDateTime.FromDateTime(time)).ToDateTimeUtc();
}
return from.AtLeniently(LocalDateTime.FromDateTime(time)).ToDateTimeUtc();
}
}
}