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

@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AMWD.Common\AMWD.Common.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,318 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class DateTimeExtensionsTests
{
[TestMethod]
public void ShouldReturnUtc()
{
// arrange
var utc = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Utc);
var local = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Local);
var unspecified = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Unspecified);
// act
var utcCorrected = utc.AsUtc();
var localCorrected = local.AsUtc();
var unspecifiedCorrected = unspecified.AsUtc();
// assert
Assert.AreEqual(DateTimeKind.Utc, utcCorrected.Kind);
Assert.AreEqual(DateTimeKind.Utc, localCorrected.Kind);
Assert.AreEqual(DateTimeKind.Utc, unspecifiedCorrected.Kind);
Assert.AreEqual(utc, utcCorrected);
Assert.AreEqual(utc.AddHours(-1), localCorrected);
Assert.AreEqual(utc, unspecifiedCorrected);
}
[TestMethod]
public void ShouldReturnLocal()
{
// arrange
var utc = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Utc);
var local = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Local);
var unspecified = new DateTime(2021, 11, 15, 11, 22, 33, DateTimeKind.Unspecified);
// act
var utcCorrected = utc.AsLocal();
var localCorrected = local.AsLocal();
var unspecifiedCorrected = unspecified.AsLocal();
// assert
Assert.AreEqual(DateTimeKind.Local, utcCorrected.Kind);
Assert.AreEqual(DateTimeKind.Local, localCorrected.Kind);
Assert.AreEqual(DateTimeKind.Local, unspecifiedCorrected.Kind);
Assert.AreEqual(local.AddHours(1), utcCorrected);
Assert.AreEqual(local, localCorrected);
Assert.AreEqual(local, unspecifiedCorrected);
}
[TestMethod]
public void ShouldReturnCorrectUtcAlignmentDaylightSavingEnd()
{
// arrange
var utcNow = new DateTime(2021, 10, 30, 12, 15, 30, 45, DateTimeKind.Utc);
var intervalThreeSeconds = TimeSpan.FromSeconds(3);
var intervalSixMinutes = TimeSpan.FromMinutes(6);
var intervalTwoHours = TimeSpan.FromHours(2);
var intervalDay = TimeSpan.FromDays(1);
var offsetTwoMinutes = TimeSpan.FromMinutes(2);
var offsetFourHours = TimeSpan.FromHours(4);
// act
var diffThreeSeconds = intervalThreeSeconds.GetAlignedInterval(utcNow);
var diffSixMinutes = intervalSixMinutes.GetAlignedInterval(utcNow);
var diffTwoHours = intervalTwoHours.GetAlignedInterval(utcNow);
var diffDay = intervalDay.GetAlignedInterval(utcNow);
var diffTwoHoursOffset = intervalTwoHours.GetAlignedInterval(utcNow, offsetTwoMinutes);
var diffDayOffset = intervalDay.GetAlignedInterval(utcNow, offsetFourHours);
// assert
Assert.AreEqual(TimeSpan.Parse("00:00:02.955"), diffThreeSeconds);
Assert.AreEqual(TimeSpan.Parse("00:02:29.955"), diffSixMinutes);
Assert.AreEqual(TimeSpan.Parse("01:44:29.955"), diffTwoHours);
Assert.AreEqual(TimeSpan.Parse("11:44:29.955"), diffDay);
Assert.AreEqual(TimeSpan.Parse("01:46:29.955"), diffTwoHoursOffset);
Assert.AreEqual(TimeSpan.Parse("15:44:29.955"), diffDayOffset); // must be the same whether daylight saving has ended
}
[TestMethod]
public void ShouldReturnCorrectUtcAlignmentDaylightSavingStart()
{
// arrange
var utcNow = new DateTime(2022, 3, 26, 12, 15, 30, 45, DateTimeKind.Utc);
var intervalThreeSeconds = TimeSpan.FromSeconds(3);
var intervalSixMinutes = TimeSpan.FromMinutes(6);
var intervalTwoHours = TimeSpan.FromHours(2);
var intervalDay = TimeSpan.FromDays(1);
var offsetTwoMinutes = TimeSpan.FromMinutes(2);
var offsetFourHours = TimeSpan.FromHours(4);
// act
var diffThreeSeconds = intervalThreeSeconds.GetAlignedInterval(utcNow);
var diffSixMinutes = intervalSixMinutes.GetAlignedInterval(utcNow);
var diffTwoHours = intervalTwoHours.GetAlignedInterval(utcNow);
var diffDay = intervalDay.GetAlignedInterval(utcNow);
var diffTwoHoursOffset = intervalTwoHours.GetAlignedInterval(utcNow, offsetTwoMinutes);
var diffDayOffset = intervalDay.GetAlignedInterval(utcNow, offsetFourHours);
// assert
Assert.AreEqual(TimeSpan.Parse("00:00:02.955"), diffThreeSeconds);
Assert.AreEqual(TimeSpan.Parse("00:02:29.955"), diffSixMinutes);
Assert.AreEqual(TimeSpan.Parse("01:44:29.955"), diffTwoHours);
Assert.AreEqual(TimeSpan.Parse("11:44:29.955"), diffDay);
Assert.AreEqual(TimeSpan.Parse("01:46:29.955"), diffTwoHoursOffset);
Assert.AreEqual(TimeSpan.Parse("15:44:29.955"), diffDayOffset); // must be the same whether daylight saving has started
}
[TestMethod]
public void ShouldReturnCorrectLocalAlignmentDaylightSavingEnd()
{
// arrange
var utcNow = new DateTime(2021, 10, 30, 12, 15, 30, 45, DateTimeKind.Local);
var intervalThreeSeconds = TimeSpan.FromSeconds(3);
var intervalSixMinutes = TimeSpan.FromMinutes(6);
var intervalTwoHours = TimeSpan.FromHours(2);
var intervalDay = TimeSpan.FromDays(1);
var offsetTwoMinutes = TimeSpan.FromMinutes(2);
var offsetFourHours = TimeSpan.FromHours(4);
// act
var diffThreeSeconds = intervalThreeSeconds.GetAlignedInterval(utcNow);
var diffSixMinutes = intervalSixMinutes.GetAlignedInterval(utcNow);
var diffTwoHours = intervalTwoHours.GetAlignedInterval(utcNow);
var diffDay = intervalDay.GetAlignedInterval(utcNow);
var diffTwoHoursOffset = intervalTwoHours.GetAlignedInterval(utcNow, offsetTwoMinutes);
var diffDayOffset = intervalDay.GetAlignedInterval(utcNow, offsetFourHours);
// assert
Assert.AreEqual(TimeSpan.Parse("00:00:02.955"), diffThreeSeconds);
Assert.AreEqual(TimeSpan.Parse("00:02:29.955"), diffSixMinutes);
Assert.AreEqual(TimeSpan.Parse("01:44:29.955"), diffTwoHours);
Assert.AreEqual(TimeSpan.Parse("11:44:29.955"), diffDay);
Assert.AreEqual(TimeSpan.Parse("01:46:29.955"), diffTwoHoursOffset);
Assert.AreEqual(TimeSpan.Parse("14:44:29.955"), diffDayOffset); // has to be minus one hour due to daylight saving ended
}
[TestMethod]
public void ShouldReturnCorrectLocalAlignmentDaylightSavingStart()
{
// arrange
var utcNow = new DateTime(2022, 3, 26, 12, 15, 30, 45, DateTimeKind.Local);
var intervalThreeSeconds = TimeSpan.FromSeconds(3);
var intervalSixMinutes = TimeSpan.FromMinutes(6);
var intervalTwoHours = TimeSpan.FromHours(2);
var intervalDay = TimeSpan.FromDays(1);
var offsetTwoMinutes = TimeSpan.FromMinutes(2);
var offsetFourHours = TimeSpan.FromHours(4);
// act
var diffThreeSeconds = intervalThreeSeconds.GetAlignedInterval(utcNow);
var diffSixMinutes = intervalSixMinutes.GetAlignedInterval(utcNow);
var diffTwoHours = intervalTwoHours.GetAlignedInterval(utcNow);
var diffDay = intervalDay.GetAlignedInterval(utcNow);
var diffTwoHoursOffset = intervalTwoHours.GetAlignedInterval(utcNow, offsetTwoMinutes);
var diffDayOffset = intervalDay.GetAlignedInterval(utcNow, offsetFourHours);
// assert
Assert.AreEqual(TimeSpan.Parse("00:00:02.955"), diffThreeSeconds);
Assert.AreEqual(TimeSpan.Parse("00:02:29.955"), diffSixMinutes);
Assert.AreEqual(TimeSpan.Parse("01:44:29.955"), diffTwoHours);
Assert.AreEqual(TimeSpan.Parse("11:44:29.955"), diffDay);
Assert.AreEqual(TimeSpan.Parse("01:46:29.955"), diffTwoHoursOffset);
Assert.AreEqual(TimeSpan.Parse("16:44:29.955"), diffDayOffset); // has to be plus one hour due to daylight saving started
}
[TestMethod]
public void ShouldReturnCorrectShortStringForTimeSpan()
{
// arrange
var timeSpan = TimeSpan.Parse("1.10:11:12.345");
// act
string shortString = timeSpan.ToShortString(withMilliseconds: false);
string shortStringWithMillis = timeSpan.ToShortString(withMilliseconds: true);
// assert
Assert.AreEqual("1d 10h 11m 12s", shortString);
Assert.AreEqual("1d 10h 11m 12s 345ms", shortStringWithMillis);
}
[TestMethod]
public void ShouldRoundToSecond()
{
// arrange
var timestampUp = new DateTime(2021, 11, 16, 20, 15, 30, 500);
var timestampDown = new DateTime(2021, 11, 16, 20, 15, 30, 499);
var timespanUp = new TimeSpan(1, 2, 3, 4, 500);
var timespanDown = new TimeSpan(1, 2, 3, 4, 499);
// act
var timestampUpRounded = timestampUp.RoundToSecond();
var timestampDownRounded = timestampDown.RoundToSecond();
var timespanUpRounded = timespanUp.RoundToSecond();
var timespanDownRounded = timespanDown.RoundToSecond();
// assert
Assert.AreNotEqual(timestampUp, timestampUpRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:15:31.000"), timestampUpRounded);
Assert.AreNotEqual(timestampDown, timestampDownRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:15:30.000"), timestampDownRounded);
Assert.AreNotEqual(timespanUp, timespanUpRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:03:05.000"), timespanUpRounded);
Assert.AreNotEqual(timespanDown, timespanDownRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:03:04.000"), timespanDownRounded);
}
[TestMethod]
public void ShouldRoundToMinute()
{
// arrange
var timestampUp = new DateTime(2021, 11, 16, 20, 15, 30, 0);
var timestampDown = new DateTime(2021, 11, 16, 20, 15, 29, 999);
var timespanUp = new TimeSpan(1, 2, 3, 30, 0);
var timespanDown = new TimeSpan(1, 2, 3, 29, 999);
// act
var timestampUpRounded = timestampUp.RoundToMinute();
var timestampDownRounded = timestampDown.RoundToMinute();
var timespanUpRounded = timespanUp.RoundToMinute();
var timespanDownRounded = timespanDown.RoundToMinute();
// assert
Assert.AreNotEqual(timestampUp, timestampUpRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:16:00.000"), timestampUpRounded);
Assert.AreNotEqual(timestampDown, timestampDownRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:15:00.000"), timestampDownRounded);
Assert.AreNotEqual(timespanUp, timespanUpRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:04:00.000"), timespanUpRounded);
Assert.AreNotEqual(timespanDown, timespanDownRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:03:00.000"), timespanDownRounded);
}
[TestMethod]
public void ShouldRoundToHour()
{
// arrange
var timestampUp = new DateTime(2021, 11, 16, 20, 30, 0, 0);
var timestampDown = new DateTime(2021, 11, 16, 20, 29, 59, 999);
var timespanUp = new TimeSpan(1, 2, 30, 0, 0);
var timespanDown = new TimeSpan(1, 2, 29, 59, 999);
// act
var timestampUpRounded = timestampUp.RoundToHour();
var timestampDownRounded = timestampDown.RoundToHour();
var timespanUpRounded = timespanUp.RoundToHour();
var timespanDownRounded = timespanDown.RoundToHour();
// assert
Assert.AreNotEqual(timestampUp, timestampUpRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 21:00:00.000"), timestampUpRounded);
Assert.AreNotEqual(timestampDown, timestampDownRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 20:00:00.000"), timestampDownRounded);
Assert.AreNotEqual(timespanUp, timespanUpRounded);
Assert.AreEqual(TimeSpan.Parse("1.03:00:00.000"), timespanUpRounded);
Assert.AreNotEqual(timespanDown, timespanDownRounded);
Assert.AreEqual(TimeSpan.Parse("1.02:00:00.000"), timespanDownRounded);
}
[TestMethod]
public void ShouldRoundToDay()
{
// arrange
var timestampUp = new DateTime(2021, 11, 16, 12, 0, 0, 0);
var timestampDown = new DateTime(2021, 11, 16, 11, 59, 59, 999);
var timespanUp = new TimeSpan(1, 12, 0, 0, 0);
var timespanDown = new TimeSpan(1, 11, 59, 59, 999);
// act
var timestampUpRounded = timestampUp.RoundToDay();
var timestampDownRounded = timestampDown.RoundToDay();
var timespanUpRounded = timespanUp.RoundToDay();
var timespanDownRounded = timespanDown.RoundToDay();
// assert
Assert.AreNotEqual(timestampUp, timestampUpRounded);
Assert.AreEqual(DateTime.Parse("2021-11-17 00:00:00.000"), timestampUpRounded);
Assert.AreNotEqual(timestampDown, timestampDownRounded);
Assert.AreEqual(DateTime.Parse("2021-11-16 00:00:00.000"), timestampDownRounded);
Assert.AreNotEqual(timespanUp, timespanUpRounded);
Assert.AreEqual(TimeSpan.Parse("2.00:00:00.000"), timespanUpRounded);
Assert.AreNotEqual(timespanDown, timespanDownRounded);
Assert.AreEqual(TimeSpan.Parse("1.00:00:00.000"), timespanDownRounded);
}
}
}

View File

@@ -0,0 +1,107 @@
using System;
using System.Linq;
using AMWD.Common.Tests.Utils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
namespace AMWD.Common.Tests.Extensions
{
[TestClass]
public class EnumExtensionsTests
{
[TestMethod]
public void ShouldReturnEmptyList()
{
// arrange
var enumValue = TestEnum.Two;
// act
var customList = enumValue.GetAttributes<CustomMultipleAttribute>();
var descriptionList = enumValue.GetAttributes<DescriptionAttribute>();
// assert
Assert.IsNotNull(customList);
Assert.IsFalse(customList.Any());
Assert.IsNotNull(descriptionList);
Assert.IsFalse(descriptionList.Any());
}
[TestMethod]
public void ShouldReturnList()
{
// arrange
var enumValue = TestEnum.Zero;
// act
var customList = enumValue.GetAttributes<CustomMultipleAttribute>();
var descriptionList = enumValue.GetAttributes<DescriptionAttribute>();
// assert
Assert.IsNotNull(customList);
Assert.IsTrue(customList.Any());
Assert.AreEqual(2, customList.Count());
Assert.IsNotNull(descriptionList);
Assert.IsTrue(descriptionList.Any());
Assert.AreEqual(1, descriptionList.Count());
}
[TestMethod]
public void ShouldReturnNothing()
{
// arrange
var enumValue = TestEnum.Two;
// act
var customAttribute = enumValue.GetAttribute<CustomMultipleAttribute>();
var descriptionAttribute = enumValue.GetAttribute<DescriptionAttribute>();
// assert
Assert.IsNull(customAttribute);
Assert.IsNull(descriptionAttribute);
}
[TestMethod]
public void ShouldReturnFirstAttribute()
{
// arrange
var enumValue = TestEnum.Zero;
// act
var customAttribute = enumValue.GetAttribute<CustomMultipleAttribute>();
var descriptionAttribute = enumValue.GetAttribute<DescriptionAttribute>();
// assert
Assert.IsNotNull(customAttribute);
Assert.AreEqual("nix", customAttribute.Name);
Assert.IsNotNull(descriptionAttribute);
Assert.AreEqual("Null", descriptionAttribute.Description);
}
[TestMethod]
public void ShouldReturnDescriptionOrStringRepresentation()
{
// arrange
var enumWithDescription = TestEnum.One;
var enumWithoutDescripton = TestEnum.Two;
// act
string description = enumWithDescription.GetDescription();
string noDescription = enumWithoutDescripton.GetDescription();
// assert
Assert.AreEqual("Eins", description);
Assert.AreEqual(enumWithoutDescripton.ToString(), noDescription);
}
internal enum TestEnum
{
[CustomMultiple("nix")]
[CustomMultiple("Null")]
[Description("Null")]
Zero,
[Description("Eins")]
One,
Two,
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
namespace AMWD.Common.Tests.Utils
{
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
internal class CustomMultipleAttribute : Attribute
{
public CustomMultipleAttribute(string name)
{
Name = name;
}
public string Name { get; set; }
}
}

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

View File

@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31729.503
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Common", "AMWD.Common\AMWD.Common.csproj", "{F512C474-B670-4E47-911E-7C0674AA8E7E}"
EndProject
@@ -20,6 +20,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AMWD.Common.Tests", "AMWD.Common.Tests\AMWD.Common.Tests.csproj", "{086E3C11-454A-4C8F-AEAA-215BAE9C443F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F2C7556A-99EB-43EB-8954-56A24AFE928F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E5DF156A-6C8B-4004-BA4C-A8DDE6FD3ECD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -38,10 +44,20 @@ Global
{7091CECF-C981-4FB9-9CC6-91C4E65A6356}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7091CECF-C981-4FB9-9CC6-91C4E65A6356}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7091CECF-C981-4FB9-9CC6-91C4E65A6356}.Release|Any CPU.Build.0 = Release|Any CPU
{086E3C11-454A-4C8F-AEAA-215BAE9C443F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{086E3C11-454A-4C8F-AEAA-215BAE9C443F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{086E3C11-454A-4C8F-AEAA-215BAE9C443F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{086E3C11-454A-4C8F-AEAA-215BAE9C443F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{F512C474-B670-4E47-911E-7C0674AA8E7E} = {F2C7556A-99EB-43EB-8954-56A24AFE928F}
{725F40C9-8172-487F-B3D0-D7E38B4DB197} = {F2C7556A-99EB-43EB-8954-56A24AFE928F}
{7091CECF-C981-4FB9-9CC6-91C4E65A6356} = {F2C7556A-99EB-43EB-8954-56A24AFE928F}
{086E3C11-454A-4C8F-AEAA-215BAE9C443F} = {E5DF156A-6C8B-4004-BA4C-A8DDE6FD3ECD}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {961E8DF8-DDF5-4D10-A510-CE409E9962AC}
EndGlobalSection