1
0
mirror of https://github.com/oliverbooth/X10D synced 2024-11-23 00:38:47 +00:00

Add IsLeapYear for DateTime(Offset) and numeric types

This commit is contained in:
Oliver Booth 2022-04-28 10:27:32 +01:00
parent e08274189a
commit ef9c186684
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
22 changed files with 561 additions and 9 deletions

View File

@ -18,6 +18,35 @@ public class ByteTests
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), ((byte)0).FromUnixTimeSeconds()); Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), ((byte)0).FromUnixTimeSeconds());
} }
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenMultipleOf100()
{
Assert.IsFalse(((byte)100).IsLeapYear());
Assert.IsFalse(((byte)200).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse(((byte)1).IsLeapYear());
Assert.IsFalse(((byte)101).IsLeapYear());
Assert.IsFalse(((byte)201).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_GivenMultipleOf4()
{
Assert.IsTrue(((byte)4).IsLeapYear());
Assert.IsTrue(((byte)104).IsLeapYear());
Assert.IsTrue(((byte)204).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldThrow_GivenZero()
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => ((byte)0).IsLeapYear());
}
[TestMethod] [TestMethod]
public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBePositive_GivenOne() public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBePositive_GivenOne()
{ {

View File

@ -37,6 +37,34 @@ public class DateTimeOffsetTests
Assert.AreEqual(new DateTime(today.Year, today.Month, 1), today.FirstDayOfMonth()); Assert.AreEqual(new DateTime(today.Year, today.Month, 1), today.FirstDayOfMonth());
} }
[TestMethod]
public void IsLeapYear_ShouldBeFalse_Given1999()
{
DateTimeOffset date = new DateTime(1999, 1, 1);
Assert.IsFalse(date.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_Given2000()
{
DateTimeOffset date = new DateTime(2000, 1, 1);
Assert.IsTrue(date.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_Given2001()
{
DateTimeOffset date = new DateTime(2001, 1, 1);
Assert.IsFalse(date.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_Given2100()
{
DateTimeOffset date = new DateTime(2100, 1, 1);
Assert.IsFalse(date.IsLeapYear());
}
[TestMethod] [TestMethod]
public void LastSaturday_ShouldBe29th_Given1Jan2000() public void LastSaturday_ShouldBe29th_Given1Jan2000()
{ {

View File

@ -37,6 +37,34 @@ public class DateTimeTests
Assert.AreEqual(new DateTime(today.Year, today.Month, 1), today.FirstDayOfMonth()); Assert.AreEqual(new DateTime(today.Year, today.Month, 1), today.FirstDayOfMonth());
} }
[TestMethod]
public void IsLeapYear_ShouldBeFalse_Given1999()
{
var date = new DateTime(1999, 1, 1);
Assert.IsFalse(date.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_Given2000()
{
var date = new DateTime(2000, 1, 1);
Assert.IsTrue(date.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_Given2001()
{
var date = new DateTime(2001, 1, 1);
Assert.IsFalse(date.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_Given2100()
{
var date = new DateTime(2100, 1, 1);
Assert.IsFalse(date.IsLeapYear());
}
[TestMethod] [TestMethod]
public void LastSaturday_ShouldBe29th_Given1Jan2000() public void LastSaturday_ShouldBe29th_Given1Jan2000()
{ {

View File

@ -11,13 +11,47 @@ public class Int16Tests
{ {
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), ((short)0).FromUnixTimeMilliseconds()); Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), ((short)0).FromUnixTimeMilliseconds());
} }
[TestMethod] [TestMethod]
public void FromUnixTimeSeconds_ShouldBeEpoch_GivenZero() public void FromUnixTimeSeconds_ShouldBeEpoch_GivenZero()
{ {
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), ((short)0).FromUnixTimeSeconds()); Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), ((short)0).FromUnixTimeSeconds());
} }
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenMultipleOf100()
{
Assert.IsFalse(((short)100).IsLeapYear());
Assert.IsFalse(((short)-100).IsLeapYear());
Assert.IsFalse(((short)1900).IsLeapYear());
Assert.IsFalse(((short)2100).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse(((short)1).IsLeapYear());
Assert.IsFalse(((short)101).IsLeapYear());
Assert.IsFalse(((short)-101).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_GivenMultipleOf4Or400()
{
Assert.IsTrue(((short)-401).IsLeapYear());
Assert.IsTrue(((short)-105).IsLeapYear());
Assert.IsTrue(((short)4).IsLeapYear());
Assert.IsTrue(((short)104).IsLeapYear());
Assert.IsTrue(((short)400).IsLeapYear());
Assert.IsTrue(((short)2000).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldThrow_GivenZero()
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => ((short)0).IsLeapYear());
}
[TestMethod] [TestMethod]
public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBeNegative_GivenMinusOne() public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBeNegative_GivenMinusOne()
{ {

View File

@ -18,6 +18,40 @@ public class Int32Tests
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), 0.FromUnixTimeSeconds()); Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), 0.FromUnixTimeSeconds());
} }
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenMultipleOf100()
{
Assert.IsFalse(100.IsLeapYear());
Assert.IsFalse((-100).IsLeapYear());
Assert.IsFalse(1900.IsLeapYear());
Assert.IsFalse(2100.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse(1.IsLeapYear());
Assert.IsFalse(101.IsLeapYear());
Assert.IsFalse((-101).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_GivenMultipleOf4Or400()
{
Assert.IsTrue((-401).IsLeapYear());
Assert.IsTrue((-105).IsLeapYear());
Assert.IsTrue(4.IsLeapYear());
Assert.IsTrue(104.IsLeapYear());
Assert.IsTrue(400.IsLeapYear());
Assert.IsTrue(2000.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldThrow_GivenZero()
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => 0.IsLeapYear());
}
[TestMethod] [TestMethod]
public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBeNegative_GivenMinusOne() public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBeNegative_GivenMinusOne()
{ {

View File

@ -18,6 +18,40 @@ public class Int64Tests
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), 0L.FromUnixTimeSeconds()); Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), 0L.FromUnixTimeSeconds());
} }
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenMultipleOf100()
{
Assert.IsFalse(100L.IsLeapYear());
Assert.IsFalse((-100L).IsLeapYear());
Assert.IsFalse(1900L.IsLeapYear());
Assert.IsFalse(2100L.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse(1L.IsLeapYear());
Assert.IsFalse(101L.IsLeapYear());
Assert.IsFalse((-101L).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_GivenMultipleOf4Or400()
{
Assert.IsTrue((-401L).IsLeapYear());
Assert.IsTrue((-105L).IsLeapYear());
Assert.IsTrue(4L.IsLeapYear());
Assert.IsTrue(104L.IsLeapYear());
Assert.IsTrue(400L.IsLeapYear());
Assert.IsTrue(2000L.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldThrow_GivenZero()
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => 0L.IsLeapYear());
}
[TestMethod] [TestMethod]
public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBeNegative_GivenMinusOne() public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBeNegative_GivenMinusOne()
{ {

View File

@ -19,6 +19,35 @@ public class SByteTests
Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), ((sbyte)0).FromUnixTimeSeconds()); Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), ((sbyte)0).FromUnixTimeSeconds());
} }
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenMultipleOf100()
{
Assert.IsFalse(((sbyte)100).IsLeapYear());
Assert.IsFalse(((sbyte)-100).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse(((sbyte)1).IsLeapYear());
Assert.IsFalse(((sbyte)101).IsLeapYear());
Assert.IsFalse(((sbyte)-101).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_GivenMultipleOf4()
{
Assert.IsTrue(((sbyte)4).IsLeapYear());
Assert.IsTrue(((sbyte)104).IsLeapYear());
Assert.IsTrue(((sbyte)-105).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldThrow_GivenZero()
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => ((sbyte)0).IsLeapYear());
}
[TestMethod] [TestMethod]
public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBeZero_GivenZero() public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBeZero_GivenZero()
{ {

View File

@ -7,6 +7,36 @@ namespace X10D.Tests.Time;
[CLSCompliant(false)] [CLSCompliant(false)]
public class UInt16Tests public class UInt16Tests
{ {
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenMultipleOf100()
{
Assert.IsFalse(((ushort)100).IsLeapYear());
Assert.IsFalse(((ushort)1900).IsLeapYear());
Assert.IsFalse(((ushort)2100).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse(((ushort)1).IsLeapYear());
Assert.IsFalse(((ushort)101).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_GivenMultipleOf4Or400()
{
Assert.IsTrue(((ushort)4).IsLeapYear());
Assert.IsTrue(((ushort)104).IsLeapYear());
Assert.IsTrue(((ushort)400).IsLeapYear());
Assert.IsTrue(((ushort)2000).IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldThrow_GivenZero()
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => ((ushort)0).IsLeapYear());
}
[TestMethod] [TestMethod]
public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBePositive_GivenOne() public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBePositive_GivenOne()
{ {

View File

@ -7,6 +7,36 @@ namespace X10D.Tests.Time;
[CLSCompliant(false)] [CLSCompliant(false)]
public class UInt32Tests public class UInt32Tests
{ {
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenMultipleOf100()
{
Assert.IsFalse(100U.IsLeapYear());
Assert.IsFalse(1900U.IsLeapYear());
Assert.IsFalse(2100U.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse(1U.IsLeapYear());
Assert.IsFalse(101U.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_GivenMultipleOf4Or400()
{
Assert.IsTrue(4U.IsLeapYear());
Assert.IsTrue(104U.IsLeapYear());
Assert.IsTrue(400U.IsLeapYear());
Assert.IsTrue(2000U.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldThrow_GivenZero()
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => 0U.IsLeapYear());
}
[TestMethod] [TestMethod]
public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBePositive_GivenOne() public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBePositive_GivenOne()
{ {

View File

@ -7,6 +7,36 @@ namespace X10D.Tests.Time;
[CLSCompliant(false)] [CLSCompliant(false)]
public class UInt64Tests public class UInt64Tests
{ {
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenMultipleOf100()
{
Assert.IsFalse(100UL.IsLeapYear());
Assert.IsFalse(1900UL.IsLeapYear());
Assert.IsFalse(2100UL.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse(1UL.IsLeapYear());
Assert.IsFalse(101UL.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldBeTrue_GivenMultipleOf4Or400()
{
Assert.IsTrue(4UL.IsLeapYear());
Assert.IsTrue(104UL.IsLeapYear());
Assert.IsTrue(400UL.IsLeapYear());
Assert.IsTrue(2000UL.IsLeapYear());
}
[TestMethod]
public void IsLeapYear_ShouldThrow_GivenZero()
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => 0UL.IsLeapYear());
}
[TestMethod] [TestMethod]
public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBePositive_GivenOne() public void TicksMillisecondsSecondsMinutesDaysHoursWeeks_ShouldBePositive_GivenOne()
{ {

View File

@ -185,5 +185,14 @@ namespace X10D {
return ResourceManager.GetString("TypeIsNotInterface", resourceCulture); return ResourceManager.GetString("TypeIsNotInterface", resourceCulture);
} }
} }
/// <summary>
/// Looks up a localized string similar to Year cannot be zero..
/// </summary>
internal static string YearCannotBeZero {
get {
return ResourceManager.GetString("YearCannotBeZero", resourceCulture);
}
}
} }
} }

View File

@ -65,4 +65,7 @@
<data name="CountMustBeGreaterThanOrEqualTo0" xml:space="preserve"> <data name="CountMustBeGreaterThanOrEqualTo0" xml:space="preserve">
<value>count must be greater than or equal to 0.</value> <value>count must be greater than or equal to 0.</value>
</data> </data>
<data name="YearCannotBeZero" xml:space="preserve">
<value>Year cannot be zero.</value>
</data>
</root> </root>

View File

@ -1,10 +1,33 @@
namespace X10D.Time; using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Time;
/// <summary> /// <summary>
/// Time-related extension methods for <see cref="byte" />. /// Time-related extension methods for <see cref="byte" />.
/// </summary> /// </summary>
public static class ByteExtensions public static class ByteExtensions
{ {
/// <summary>
/// Returns a value indicating whether the current integer, representing a year, is a leap year.
/// </summary>
/// <param name="value">The value whose leap year status to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> refers to a leap year; otherwise, <see langword="false" />.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsLeapYear(this byte value)
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), ExceptionMessages.YearCannotBeZero);
}
return value % 4 == 0 && value % 100 != 0; // mod 400 not required, byte.MaxValue is 255 anyway
}
/// <summary> /// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a /// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value. /// <see cref="DateTimeOffset" /> value.

View File

@ -31,6 +31,19 @@ public static class DateTimeExtensions
return ((DateTimeOffset)value).FirstDayOfMonth().DateTime; return ((DateTimeOffset)value).FirstDayOfMonth().DateTime;
} }
/// <summary>
/// Returns a value indicating whether the year represented by the current <see cref="DateTime" /> is a leap year.
/// </summary>
/// <param name="value">The date whose year to check.</param>
/// <returns>
/// <see langword="true" /> if the year represented by <paramref name="value" /> is a leap year; otherwise,
/// <see langword="false" />.
/// </returns>
public static bool IsLeapYear(this DateTime value)
{
return DateTime.IsLeapYear(value.Year);
}
/// <inheritdoc cref="DateTimeOffsetExtensions.Last(DateTimeOffset, DayOfWeek)" /> /// <inheritdoc cref="DateTimeOffsetExtensions.Last(DateTimeOffset, DayOfWeek)" />
/// <returns>A <see cref="DateTimeOffset" /> representing the final occurence of <paramref name="dayOfWeek" />.</returns> /// <returns>A <see cref="DateTimeOffset" /> representing the final occurence of <paramref name="dayOfWeek" />.</returns>
public static DateTime Last(this DateTime value, DayOfWeek dayOfWeek) public static DateTime Last(this DateTime value, DayOfWeek dayOfWeek)

View File

@ -57,6 +57,19 @@ public static class DateTimeOffsetExtensions
return value.AddDays(1 - value.Day); return value.AddDays(1 - value.Day);
} }
/// <summary>
/// Returns a value indicating whether the year represented by the current <see cref="DateTimeOffset" /> is a leap year.
/// </summary>
/// <param name="value">The date whose year to check.</param>
/// <returns>
/// <see langword="true" /> if the year represented by <paramref name="value" /> is a leap year; otherwise,
/// <see langword="false" />.
/// </returns>
public static bool IsLeapYear(this DateTimeOffset value)
{
return DateTime.IsLeapYear(value.Year);
}
/// <summary> /// <summary>
/// Gets a date representing the final occurence of a specified day of the week in the current month. /// Gets a date representing the final occurence of a specified day of the week in the current month.
/// </summary> /// </summary>

View File

@ -1,10 +1,39 @@
namespace X10D.Time; using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using X10D.Math;
namespace X10D.Time;
/// <summary> /// <summary>
/// Time-related extension methods for <see cref="short" />. /// Time-related extension methods for <see cref="short" />.
/// </summary> /// </summary>
public static class Int16Extensions public static class Int16Extensions
{ {
/// <summary>
/// Returns a value indicating whether the current integer, representing a year, is a leap year.
/// </summary>
/// <param name="value">The value whose leap year status to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> refers to a leap year; otherwise, <see langword="false" />.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsLeapYear(this short value)
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), ExceptionMessages.YearCannotBeZero);
}
if (value < 0)
{
value++;
}
return value.Mod(4) == 0 && (value.Mod(100) != 0 || value.Mod(400) == 0);
}
/// <summary> /// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a /// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value. /// <see cref="DateTimeOffset" /> value.

View File

@ -1,10 +1,39 @@
namespace X10D.Time; using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using X10D.Math;
namespace X10D.Time;
/// <summary> /// <summary>
/// Time-related extension methods for <see cref="int" />. /// Time-related extension methods for <see cref="int" />.
/// </summary> /// </summary>
public static class Int32Extensions public static class Int32Extensions
{ {
/// <summary>
/// Returns a value indicating whether the current integer, representing a year, is a leap year.
/// </summary>
/// <param name="value">The value whose leap year status to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> refers to a leap year; otherwise, <see langword="false" />.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsLeapYear(this int value)
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), ExceptionMessages.YearCannotBeZero);
}
if (value < 0)
{
value++;
}
return value.Mod(4) == 0 && (value.Mod(100) != 0 || value.Mod(400) == 0);
}
/// <summary> /// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a /// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value. /// <see cref="DateTimeOffset" /> value.

View File

@ -1,10 +1,39 @@
namespace X10D.Time; using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using X10D.Math;
namespace X10D.Time;
/// <summary> /// <summary>
/// Time-related extension methods for <see cref="long" />. /// Time-related extension methods for <see cref="long" />.
/// </summary> /// </summary>
public static class Int64Extensions public static class Int64Extensions
{ {
/// <summary>
/// Returns a value indicating whether the current integer, representing a year, is a leap year.
/// </summary>
/// <param name="value">The value whose leap year status to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> refers to a leap year; otherwise, <see langword="false" />.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsLeapYear(this long value)
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), ExceptionMessages.YearCannotBeZero);
}
if (value < 0)
{
value++;
}
return value.Mod(4) == 0 && (value.Mod(100) != 0 || value.Mod(400) == 0);
}
/// <summary> /// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a /// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value. /// <see cref="DateTimeOffset" /> value.

View File

@ -1,4 +1,8 @@
namespace X10D.Time; using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
using X10D.Math;
namespace X10D.Time;
/// <summary> /// <summary>
/// Time-related extension methods for <see cref="sbyte" />. /// Time-related extension methods for <see cref="sbyte" />.
@ -6,6 +10,31 @@
[CLSCompliant(false)] [CLSCompliant(false)]
public static class SByteExtensions public static class SByteExtensions
{ {
/// <summary>
/// Returns a value indicating whether the current integer, representing a year, is a leap year.
/// </summary>
/// <param name="value">The value whose leap year status to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> refers to a leap year; otherwise, <see langword="false" />.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsLeapYear(this sbyte value)
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), ExceptionMessages.YearCannotBeZero);
}
if (value < 0)
{
value++;
}
return value.Mod(4) == 0 && value.Mod(100) != 0; // mod 400 not required, sbyte.MaxValue is 127 anyway
}
/// <summary> /// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a /// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value. /// <see cref="DateTimeOffset" /> value.

View File

@ -1,4 +1,7 @@
namespace X10D.Time; using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Time;
/// <summary> /// <summary>
/// Time-related extension methods for <see cref="ushort" />. /// Time-related extension methods for <see cref="ushort" />.
@ -6,6 +9,26 @@
[CLSCompliant(false)] [CLSCompliant(false)]
public static class UInt16Extensions public static class UInt16Extensions
{ {
/// <summary>
/// Returns a value indicating whether the current integer, representing a year, is a leap year.
/// </summary>
/// <param name="value">The value whose leap year status to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> refers to a leap year; otherwise, <see langword="false" />.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsLeapYear(this ushort value)
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), ExceptionMessages.YearCannotBeZero);
}
return value % 4 == 0 && (value % 100 != 0 || value % 400 == 0);
}
/// <summary> /// <summary>
/// Returns a <see cref="TimeSpan" /> that represents this value as the number of ticks. /// Returns a <see cref="TimeSpan" /> that represents this value as the number of ticks.
/// </summary> /// </summary>

View File

@ -1,4 +1,7 @@
namespace X10D.Time; using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Time;
/// <summary> /// <summary>
/// Time-related extension methods for <see cref="uint" />. /// Time-related extension methods for <see cref="uint" />.
@ -6,6 +9,26 @@
[CLSCompliant(false)] [CLSCompliant(false)]
public static class UInt32Extensions public static class UInt32Extensions
{ {
/// <summary>
/// Returns a value indicating whether the current integer, representing a year, is a leap year.
/// </summary>
/// <param name="value">The value whose leap year status to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> refers to a leap year; otherwise, <see langword="false" />.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsLeapYear(this uint value)
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), ExceptionMessages.YearCannotBeZero);
}
return value % 4 == 0 && (value % 100 != 0 || value % 400 == 0);
}
/// <summary> /// <summary>
/// Returns a <see cref="TimeSpan" /> that represents this value as the number of ticks. /// Returns a <see cref="TimeSpan" /> that represents this value as the number of ticks.
/// </summary> /// </summary>

View File

@ -1,4 +1,7 @@
namespace X10D.Time; using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Time;
/// <summary> /// <summary>
/// Time-related extension methods for <see cref="ulong" />. /// Time-related extension methods for <see cref="ulong" />.
@ -6,6 +9,26 @@
[CLSCompliant(false)] [CLSCompliant(false)]
public static class UInt64Extensions public static class UInt64Extensions
{ {
/// <summary>
/// Returns a value indicating whether the current integer, representing a year, is a leap year.
/// </summary>
/// <param name="value">The value whose leap year status to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> refers to a leap year; otherwise, <see langword="false" />.
/// </returns>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="value" /> is 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsLeapYear(this ulong value)
{
if (value == 0)
{
throw new ArgumentOutOfRangeException(nameof(value), ExceptionMessages.YearCannotBeZero);
}
return value % 4 == 0 && (value % 100 != 0 || value % 400 == 0);
}
/// <summary> /// <summary>
/// Returns a <see cref="TimeSpan" /> that represents this value as the number of ticks. /// Returns a <see cref="TimeSpan" /> that represents this value as the number of ticks.
/// </summary> /// </summary>