1
0

GetAlignedInterval nun in UTC und Local unterschieden (Local beachtet Sommer-/Winterzeit); UnitTests begonnen

This commit is contained in:
2021-11-16 22:47:53 +01:00
parent f62adb6d72
commit 9f65b73204
6 changed files with 515 additions and 36 deletions

View File

@@ -1,5 +1,7 @@
using System.Text;
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("AMWD.Common.Tests")]
namespace System
{
/// <summary>
@@ -41,23 +43,44 @@ namespace System
#endregion Kind
#region Aligned Interval
/// <summary>
/// Aligns the <see cref="TimeSpan"/> to the clock.
/// Aligns the <see cref="TimeSpan"/> to the UTC clock.
/// </summary>
/// <param name="timeSpan">The timespan to align.</param>
/// <param name="offset">A specific offset to the timespan.</param>
/// <returns>The timespan until the aligned time.</returns>
public static TimeSpan GetAlignedInterval(this TimeSpan timeSpan, TimeSpan offset = default)
public static TimeSpan GetAlignedIntervalUtc(this TimeSpan timeSpan, TimeSpan offset = default)
=> timeSpan.GetAlignedInterval(DateTime.UtcNow, offset);
/// <summary>
/// Aligns the <see cref="TimeSpan"/> to the local clock and respects daylight saving time.
/// </summary>
/// <param name="timeSpan">The timespan to align.</param>
/// <param name="offset">A specific offset to the timespan.</param>
/// <returns>The timespan until the aligned time.</returns>
public static TimeSpan GetAlignedIntervalLocal(this TimeSpan timeSpan, TimeSpan offset = default)
=> timeSpan.GetAlignedInterval(DateTime.Now, offset);
internal static TimeSpan GetAlignedInterval(this TimeSpan timeSpan, DateTime now, TimeSpan offset = default)
{
var now = DateTime.UtcNow;
var nextTime = new DateTime(now.Ticks / timeSpan.Ticks * timeSpan.Ticks) + offset;
var nowWithOffset = new DateTimeOffset(now);
if (nextTime <= now)
nextTime += timeSpan;
var nextTime = new DateTime(nowWithOffset.Ticks / timeSpan.Ticks * timeSpan.Ticks, now.Kind).Add(offset);
var nextTimeWithOffset = new DateTimeOffset(nextTime);
return nextTime - now;
if (nextTimeWithOffset <= nowWithOffset)
nextTimeWithOffset = nextTimeWithOffset.Add(timeSpan);
if (now.Kind == DateTimeKind.Local)
return nextTimeWithOffset.LocalDateTime - nowWithOffset.LocalDateTime;
return nextTimeWithOffset - nowWithOffset;
}
#endregion Aligned Interval
/// <summary>
/// Prints the timespan as shortended string.
/// </summary>
@@ -94,9 +117,7 @@ namespace System
/// <returns></returns>
public static DateTime RoundToSecond(this DateTime dt)
{
return new DateTime(RoundTicks(dt.Ticks, TimeSpan.TicksPerSecond), dt.Kind);
}
=> new(RoundTicks(dt.Ticks, TimeSpan.TicksPerSecond), dt.Kind);
/// <summary>
/// Rounds the <see cref="DateTime"/> to full minutes.
@@ -104,9 +125,7 @@ namespace System
/// <param name="dt">The time value to round.</param>
/// <returns></returns>
public static DateTime RoundToMinute(this DateTime dt)
{
return new DateTime(RoundTicks(dt.Ticks, TimeSpan.TicksPerMinute), dt.Kind);
}
=> new(RoundTicks(dt.Ticks, TimeSpan.TicksPerMinute), dt.Kind);
/// <summary>
/// Rounds the <see cref="DateTime"/> to full hours.
@@ -114,9 +133,7 @@ namespace System
/// <param name="dt">The time value to round.</param>
/// <returns></returns>
public static DateTime RoundToHour(this DateTime dt)
{
return new DateTime(RoundTicks(dt.Ticks, TimeSpan.TicksPerHour), dt.Kind);
}
=> new(RoundTicks(dt.Ticks, TimeSpan.TicksPerHour), dt.Kind);
/// <summary>
/// Rounds the <see cref="DateTime"/> to full days.
@@ -124,9 +141,7 @@ namespace System
/// <param name="dt">The time value to round.</param>
/// <returns></returns>
public static DateTime RoundToDay(this DateTime dt)
{
return new DateTime(RoundTicks(dt.Ticks, TimeSpan.TicksPerDay), dt.Kind);
}
=> new(RoundTicks(dt.Ticks, TimeSpan.TicksPerDay), dt.Kind);
#endregion Round DateTime
@@ -138,9 +153,7 @@ namespace System
/// <param name="timeSpan">The time value to round.</param>
/// <returns></returns>
public static TimeSpan RoundToSecond(this TimeSpan timeSpan)
{
return new TimeSpan(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerSecond));
}
=> new(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerSecond));
/// <summary>
/// Rounds the <see cref="TimeSpan"/> to full minutes.
@@ -148,9 +161,7 @@ namespace System
/// <param name="timeSpan">The time value to round.</param>
/// <returns></returns>
public static TimeSpan RoundToMinute(this TimeSpan timeSpan)
{
return new TimeSpan(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerMinute));
}
=> new(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerMinute));
/// <summary>
/// Rounds the <see cref="TimeSpan"/> to full hours.
@@ -158,9 +169,7 @@ namespace System
/// <param name="timeSpan">The time value to round.</param>
/// <returns></returns>
public static TimeSpan RoundToHour(this TimeSpan timeSpan)
{
return new TimeSpan(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerHour));
}
=> new(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerHour));
/// <summary>
/// Rounds the <see cref="TimeSpan"/> to full days.
@@ -168,15 +177,11 @@ namespace System
/// <param name="timeSpan">The time value to round.</param>
/// <returns></returns>
public static TimeSpan RoundToDay(this TimeSpan timeSpan)
{
return new TimeSpan(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerDay));
}
=> new(RoundTicks(timeSpan.Ticks, TimeSpan.TicksPerDay));
#endregion Round TimeSpan
private static long RoundTicks(long ticks, long value)
{
return (ticks + value / 2) / value * value;
}
=> (ticks + value / 2) / value * value;
}
}