using System.Text;
namespace System
{
///
/// Provides extension methods for date and time manipulation.
///
public static class DateTimeExtensions
{
#region Kind
///
/// Specifies the as UTC.
///
/// The instance.
/// A with correct .
public static DateTime AsUtc(this DateTime dt)
{
return dt.Kind switch
{
DateTimeKind.Local => dt.ToUniversalTime(),
DateTimeKind.Utc => dt,
_ => DateTime.SpecifyKind(dt, DateTimeKind.Utc),
};
}
///
/// Specifies the as local time.
///
/// The instance.
/// A with correct .
public static DateTime AsLocal(this DateTime dt)
{
return dt.Kind switch
{
DateTimeKind.Local => dt,
DateTimeKind.Utc => dt.ToLocalTime(),
_ => DateTime.SpecifyKind(dt, DateTimeKind.Local),
};
}
#endregion Kind
///
/// Aligns the to the clock.
///
/// The timespan to align.
/// A specific offset to the timespan.
/// The timespan until the aligned time.
public static TimeSpan GetAlignedInterval(this TimeSpan timeSpan, TimeSpan offset = default)
{
var now = DateTime.UtcNow;
var nextTime = new DateTime(now.Ticks / timeSpan.Ticks * timeSpan.Ticks) + offset;
if (nextTime <= now)
nextTime += timeSpan;
return nextTime - now;
}
///
/// Prints the timespan as shortended string.
///
/// The timespan
/// A value indicating whether to show milliseconds.
/// The timespan as string.
public static string ToShortString(this TimeSpan timeSpan, bool withMilliseconds = false)
{
var sb = new StringBuilder();
if (timeSpan.TotalDays >= 1)
sb.Append(timeSpan.Days).Append("d ");
if (timeSpan.TotalHours >= 1)
sb.Append(timeSpan.Hours).Append("h ");
if (timeSpan.TotalMinutes >= 1)
sb.Append(timeSpan.Minutes).Append("m ");
sb.Append(timeSpan.Seconds).Append("s ");
if (withMilliseconds)
sb.Append(timeSpan.Milliseconds).Append("ms");
return sb.ToString().Trim();
}
#region Round DateTime
///
/// Rounds the to full seconds.
///
/// The time value to round.
///
public static DateTime RoundToSecond(this DateTime dt)
{
return new DateTime(RoundTicks(dt.Ticks, TimeSpan.TicksPerSecond), dt.Kind);
}
///
/// Rounds the to full minutes.
///
/// The time value to round.
///
public static DateTime RoundToMinute(this DateTime dt)
{
return new DateTime(RoundTicks(dt.Ticks, TimeSpan.TicksPerMinute), dt.Kind);
}
///
/// Rounds the to full hours.
///
/// The time value to round.
///
public static DateTime RoundToHour(this DateTime dt)
{
return new DateTime(RoundTicks(dt.Ticks, TimeSpan.TicksPerHour), dt.Kind);
}
///
/// Rounds the to full days.
///
/// The time value to round.
///
public static DateTime RoundToDay(this DateTime dt)
{
return new DateTime(RoundTicks(dt.Ticks, TimeSpan.TicksPerDay), dt.Kind);
}
#endregion Round DateTime
#region Round TimeSpan
///
/// Rounds the to full seconds.
///
/// The time value to round.
///
public static TimeSpan RoundToSecond(this TimeSpan timeSpan)
{
return new TimeSpan(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerSecond));
}
///
/// Rounds the to full minutes.
///
/// The time value to round.
///
public static TimeSpan RoundToMinute(this TimeSpan timeSpan)
{
return new TimeSpan(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerMinute));
}
///
/// Rounds the to full hours.
///
/// The time value to round.
///
public static TimeSpan RoundToHour(this TimeSpan timeSpan)
{
return new TimeSpan(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerHour));
}
///
/// Rounds the to full days.
///
/// The time value to round.
///
public static TimeSpan RoundToDay(this TimeSpan timeSpan)
{
return new TimeSpan(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerDay));
}
#endregion Round TimeSpan
private static long RoundTicks(long ticks, long value)
{
return (ticks + value / 2) / value * value;
}
}
}