From b8360e383e2d4b25ee7cbba3d67a18d573295d1a Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 12 Oct 2026 22:03:50 +1100 Subject: [PATCH] Read Microsecond and Nanosecond straight from the ticks --- src/Polyfill/DateTimeOffsetPolyfill.cs | 13 +- src/Polyfill/DateTimePolyfill.cs | 11 +- src/Polyfill/TimeSpanPolyfill.cs | 11 +- src/Split/net461/DateTimeOffsetPolyfill.cs | 10 +- src/Split/net461/DateTimePolyfill.cs | 10 +- src/Split/net461/TimeSpanPolyfill.cs | 10 +- src/Split/net462/DateTimeOffsetPolyfill.cs | 10 +- src/Split/net462/DateTimePolyfill.cs | 10 +- src/Split/net462/TimeSpanPolyfill.cs | 10 +- src/Split/net47/DateTimeOffsetPolyfill.cs | 10 +- src/Split/net47/DateTimePolyfill.cs | 10 +- src/Split/net47/TimeSpanPolyfill.cs | 10 +- src/Split/net471/DateTimeOffsetPolyfill.cs | 10 +- src/Split/net471/DateTimePolyfill.cs | 10 +- src/Split/net471/TimeSpanPolyfill.cs | 10 +- src/Split/net472/DateTimeOffsetPolyfill.cs | 10 +- src/Split/net472/DateTimePolyfill.cs | 10 +- src/Split/net472/TimeSpanPolyfill.cs | 10 +- src/Split/net48/DateTimeOffsetPolyfill.cs | 10 +- src/Split/net48/DateTimePolyfill.cs | 10 +- src/Split/net48/TimeSpanPolyfill.cs | 10 +- src/Split/net481/DateTimeOffsetPolyfill.cs | 10 +- src/Split/net481/DateTimePolyfill.cs | 10 +- src/Split/net481/TimeSpanPolyfill.cs | 10 +- src/Split/net5.0/DateTimeOffsetPolyfill.cs | 10 +- src/Split/net5.0/DateTimePolyfill.cs | 10 +- src/Split/net5.0/TimeSpanPolyfill.cs | 10 +- src/Split/net6.0/DateTimeOffsetPolyfill.cs | 10 +- src/Split/net6.0/DateTimePolyfill.cs | 10 +- src/Split/net6.0/TimeSpanPolyfill.cs | 10 +- .../netcoreapp2.0/DateTimeOffsetPolyfill.cs | 10 +- src/Split/netcoreapp2.0/DateTimePolyfill.cs | 10 +- src/Split/netcoreapp2.0/TimeSpanPolyfill.cs | 10 +- .../netcoreapp2.1/DateTimeOffsetPolyfill.cs | 10 +- src/Split/netcoreapp2.1/DateTimePolyfill.cs | 10 +- src/Split/netcoreapp2.1/TimeSpanPolyfill.cs | 10 +- .../netcoreapp2.2/DateTimeOffsetPolyfill.cs | 10 +- src/Split/netcoreapp2.2/DateTimePolyfill.cs | 10 +- src/Split/netcoreapp2.2/TimeSpanPolyfill.cs | 10 +- .../netcoreapp3.0/DateTimeOffsetPolyfill.cs | 10 +- src/Split/netcoreapp3.0/DateTimePolyfill.cs | 10 +- src/Split/netcoreapp3.0/TimeSpanPolyfill.cs | 10 +- .../netcoreapp3.1/DateTimeOffsetPolyfill.cs | 10 +- src/Split/netcoreapp3.1/DateTimePolyfill.cs | 10 +- src/Split/netcoreapp3.1/TimeSpanPolyfill.cs | 10 +- .../netstandard2.0/DateTimeOffsetPolyfill.cs | 10 +- src/Split/netstandard2.0/DateTimePolyfill.cs | 10 +- src/Split/netstandard2.0/TimeSpanPolyfill.cs | 10 +- .../netstandard2.1/DateTimeOffsetPolyfill.cs | 10 +- src/Split/netstandard2.1/DateTimePolyfill.cs | 10 +- src/Split/netstandard2.1/TimeSpanPolyfill.cs | 10 +- src/Split/uap10.0/DateTimeOffsetPolyfill.cs | 10 +- src/Split/uap10.0/DateTimePolyfill.cs | 10 +- src/Split/uap10.0/TimeSpanPolyfill.cs | 10 +- src/Tests/PolyfillTests_MicroNanosecond.cs | 154 ++++++++++++++++++ 55 files changed, 264 insertions(+), 435 deletions(-) diff --git a/src/Polyfill/DateTimeOffsetPolyfill.cs b/src/Polyfill/DateTimeOffsetPolyfill.cs index 21e0370e..c8d05b69 100644 --- a/src/Polyfill/DateTimeOffsetPolyfill.cs +++ b/src/Polyfill/DateTimeOffsetPolyfill.cs @@ -14,26 +14,21 @@ static partial class Polyfill extension(DateTimeOffset target) { + // The offset is a whole number of minutes, so the UTC ticks have the same sub-second part as the clock time + /// /// Gets the nanosecond component of the time represented by the current object. /// //Link: https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond?view=net-11.0 public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// //Link: https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond?view=net-11.0 public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } #endif diff --git a/src/Polyfill/DateTimePolyfill.cs b/src/Polyfill/DateTimePolyfill.cs index 40b10380..b29896d7 100644 --- a/src/Polyfill/DateTimePolyfill.cs +++ b/src/Polyfill/DateTimePolyfill.cs @@ -15,21 +15,14 @@ static partial class Polyfill /// //Link: https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond?view=net-11.0 public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// //Link: https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond?view=net-11.0 public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } #endif diff --git a/src/Polyfill/TimeSpanPolyfill.cs b/src/Polyfill/TimeSpanPolyfill.cs index a9f3909b..e693159b 100644 --- a/src/Polyfill/TimeSpanPolyfill.cs +++ b/src/Polyfill/TimeSpanPolyfill.cs @@ -12,21 +12,14 @@ static partial class Polyfill /// //Link: https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds?view=net-11.0 public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// //Link: https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds?view=net-11.0 public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } #endif diff --git a/src/Split/net461/DateTimeOffsetPolyfill.cs b/src/Split/net461/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/net461/DateTimeOffsetPolyfill.cs +++ b/src/Split/net461/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/net461/DateTimePolyfill.cs b/src/Split/net461/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/net461/DateTimePolyfill.cs +++ b/src/Split/net461/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/net461/TimeSpanPolyfill.cs b/src/Split/net461/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/net461/TimeSpanPolyfill.cs +++ b/src/Split/net461/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/net462/DateTimeOffsetPolyfill.cs b/src/Split/net462/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/net462/DateTimeOffsetPolyfill.cs +++ b/src/Split/net462/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/net462/DateTimePolyfill.cs b/src/Split/net462/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/net462/DateTimePolyfill.cs +++ b/src/Split/net462/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/net462/TimeSpanPolyfill.cs b/src/Split/net462/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/net462/TimeSpanPolyfill.cs +++ b/src/Split/net462/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/net47/DateTimeOffsetPolyfill.cs b/src/Split/net47/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/net47/DateTimeOffsetPolyfill.cs +++ b/src/Split/net47/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/net47/DateTimePolyfill.cs b/src/Split/net47/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/net47/DateTimePolyfill.cs +++ b/src/Split/net47/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/net47/TimeSpanPolyfill.cs b/src/Split/net47/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/net47/TimeSpanPolyfill.cs +++ b/src/Split/net47/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/net471/DateTimeOffsetPolyfill.cs b/src/Split/net471/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/net471/DateTimeOffsetPolyfill.cs +++ b/src/Split/net471/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/net471/DateTimePolyfill.cs b/src/Split/net471/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/net471/DateTimePolyfill.cs +++ b/src/Split/net471/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/net471/TimeSpanPolyfill.cs b/src/Split/net471/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/net471/TimeSpanPolyfill.cs +++ b/src/Split/net471/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/net472/DateTimeOffsetPolyfill.cs b/src/Split/net472/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/net472/DateTimeOffsetPolyfill.cs +++ b/src/Split/net472/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/net472/DateTimePolyfill.cs b/src/Split/net472/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/net472/DateTimePolyfill.cs +++ b/src/Split/net472/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/net472/TimeSpanPolyfill.cs b/src/Split/net472/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/net472/TimeSpanPolyfill.cs +++ b/src/Split/net472/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/net48/DateTimeOffsetPolyfill.cs b/src/Split/net48/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/net48/DateTimeOffsetPolyfill.cs +++ b/src/Split/net48/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/net48/DateTimePolyfill.cs b/src/Split/net48/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/net48/DateTimePolyfill.cs +++ b/src/Split/net48/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/net48/TimeSpanPolyfill.cs b/src/Split/net48/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/net48/TimeSpanPolyfill.cs +++ b/src/Split/net48/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/net481/DateTimeOffsetPolyfill.cs b/src/Split/net481/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/net481/DateTimeOffsetPolyfill.cs +++ b/src/Split/net481/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/net481/DateTimePolyfill.cs b/src/Split/net481/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/net481/DateTimePolyfill.cs +++ b/src/Split/net481/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/net481/TimeSpanPolyfill.cs b/src/Split/net481/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/net481/TimeSpanPolyfill.cs +++ b/src/Split/net481/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/net5.0/DateTimeOffsetPolyfill.cs b/src/Split/net5.0/DateTimeOffsetPolyfill.cs index f0cf6a20..a9609c11 100644 --- a/src/Split/net5.0/DateTimeOffsetPolyfill.cs +++ b/src/Split/net5.0/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/net5.0/DateTimePolyfill.cs b/src/Split/net5.0/DateTimePolyfill.cs index f9aa48e9..b62fca00 100644 --- a/src/Split/net5.0/DateTimePolyfill.cs +++ b/src/Split/net5.0/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/net5.0/TimeSpanPolyfill.cs b/src/Split/net5.0/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/net5.0/TimeSpanPolyfill.cs +++ b/src/Split/net5.0/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/net6.0/DateTimeOffsetPolyfill.cs b/src/Split/net6.0/DateTimeOffsetPolyfill.cs index f0cf6a20..a9609c11 100644 --- a/src/Split/net6.0/DateTimeOffsetPolyfill.cs +++ b/src/Split/net6.0/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/net6.0/DateTimePolyfill.cs b/src/Split/net6.0/DateTimePolyfill.cs index f9aa48e9..b62fca00 100644 --- a/src/Split/net6.0/DateTimePolyfill.cs +++ b/src/Split/net6.0/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/net6.0/TimeSpanPolyfill.cs b/src/Split/net6.0/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/net6.0/TimeSpanPolyfill.cs +++ b/src/Split/net6.0/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/netcoreapp2.0/DateTimeOffsetPolyfill.cs b/src/Split/netcoreapp2.0/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/netcoreapp2.0/DateTimeOffsetPolyfill.cs +++ b/src/Split/netcoreapp2.0/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/netcoreapp2.0/DateTimePolyfill.cs b/src/Split/netcoreapp2.0/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/netcoreapp2.0/DateTimePolyfill.cs +++ b/src/Split/netcoreapp2.0/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/netcoreapp2.0/TimeSpanPolyfill.cs b/src/Split/netcoreapp2.0/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/netcoreapp2.0/TimeSpanPolyfill.cs +++ b/src/Split/netcoreapp2.0/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/netcoreapp2.1/DateTimeOffsetPolyfill.cs b/src/Split/netcoreapp2.1/DateTimeOffsetPolyfill.cs index f0cf6a20..a9609c11 100644 --- a/src/Split/netcoreapp2.1/DateTimeOffsetPolyfill.cs +++ b/src/Split/netcoreapp2.1/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/netcoreapp2.1/DateTimePolyfill.cs b/src/Split/netcoreapp2.1/DateTimePolyfill.cs index f9aa48e9..b62fca00 100644 --- a/src/Split/netcoreapp2.1/DateTimePolyfill.cs +++ b/src/Split/netcoreapp2.1/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/netcoreapp2.1/TimeSpanPolyfill.cs b/src/Split/netcoreapp2.1/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/netcoreapp2.1/TimeSpanPolyfill.cs +++ b/src/Split/netcoreapp2.1/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/netcoreapp2.2/DateTimeOffsetPolyfill.cs b/src/Split/netcoreapp2.2/DateTimeOffsetPolyfill.cs index f0cf6a20..a9609c11 100644 --- a/src/Split/netcoreapp2.2/DateTimeOffsetPolyfill.cs +++ b/src/Split/netcoreapp2.2/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/netcoreapp2.2/DateTimePolyfill.cs b/src/Split/netcoreapp2.2/DateTimePolyfill.cs index f9aa48e9..b62fca00 100644 --- a/src/Split/netcoreapp2.2/DateTimePolyfill.cs +++ b/src/Split/netcoreapp2.2/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/netcoreapp2.2/TimeSpanPolyfill.cs b/src/Split/netcoreapp2.2/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/netcoreapp2.2/TimeSpanPolyfill.cs +++ b/src/Split/netcoreapp2.2/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/netcoreapp3.0/DateTimeOffsetPolyfill.cs b/src/Split/netcoreapp3.0/DateTimeOffsetPolyfill.cs index f0cf6a20..a9609c11 100644 --- a/src/Split/netcoreapp3.0/DateTimeOffsetPolyfill.cs +++ b/src/Split/netcoreapp3.0/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/netcoreapp3.0/DateTimePolyfill.cs b/src/Split/netcoreapp3.0/DateTimePolyfill.cs index f9aa48e9..b62fca00 100644 --- a/src/Split/netcoreapp3.0/DateTimePolyfill.cs +++ b/src/Split/netcoreapp3.0/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/netcoreapp3.0/TimeSpanPolyfill.cs b/src/Split/netcoreapp3.0/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/netcoreapp3.0/TimeSpanPolyfill.cs +++ b/src/Split/netcoreapp3.0/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/netcoreapp3.1/DateTimeOffsetPolyfill.cs b/src/Split/netcoreapp3.1/DateTimeOffsetPolyfill.cs index f0cf6a20..a9609c11 100644 --- a/src/Split/netcoreapp3.1/DateTimeOffsetPolyfill.cs +++ b/src/Split/netcoreapp3.1/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/netcoreapp3.1/DateTimePolyfill.cs b/src/Split/netcoreapp3.1/DateTimePolyfill.cs index f9aa48e9..b62fca00 100644 --- a/src/Split/netcoreapp3.1/DateTimePolyfill.cs +++ b/src/Split/netcoreapp3.1/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/netcoreapp3.1/TimeSpanPolyfill.cs b/src/Split/netcoreapp3.1/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/netcoreapp3.1/TimeSpanPolyfill.cs +++ b/src/Split/netcoreapp3.1/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/netstandard2.0/DateTimeOffsetPolyfill.cs b/src/Split/netstandard2.0/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/netstandard2.0/DateTimeOffsetPolyfill.cs +++ b/src/Split/netstandard2.0/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/netstandard2.0/DateTimePolyfill.cs b/src/Split/netstandard2.0/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/netstandard2.0/DateTimePolyfill.cs +++ b/src/Split/netstandard2.0/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/netstandard2.0/TimeSpanPolyfill.cs b/src/Split/netstandard2.0/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/netstandard2.0/TimeSpanPolyfill.cs +++ b/src/Split/netstandard2.0/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/netstandard2.1/DateTimeOffsetPolyfill.cs b/src/Split/netstandard2.1/DateTimeOffsetPolyfill.cs index f0cf6a20..a9609c11 100644 --- a/src/Split/netstandard2.1/DateTimeOffsetPolyfill.cs +++ b/src/Split/netstandard2.1/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/netstandard2.1/DateTimePolyfill.cs b/src/Split/netstandard2.1/DateTimePolyfill.cs index f9aa48e9..b62fca00 100644 --- a/src/Split/netstandard2.1/DateTimePolyfill.cs +++ b/src/Split/netstandard2.1/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/netstandard2.1/TimeSpanPolyfill.cs b/src/Split/netstandard2.1/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/netstandard2.1/TimeSpanPolyfill.cs +++ b/src/Split/netstandard2.1/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Split/uap10.0/DateTimeOffsetPolyfill.cs b/src/Split/uap10.0/DateTimeOffsetPolyfill.cs index 012b944d..e2cbbc73 100644 --- a/src/Split/uap10.0/DateTimeOffsetPolyfill.cs +++ b/src/Split/uap10.0/DateTimeOffsetPolyfill.cs @@ -12,18 +12,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.UtcTicks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.UtcTicks / TicksPerMicrosecond % 1000); } extension(DateTimeOffset) { diff --git a/src/Split/uap10.0/DateTimePolyfill.cs b/src/Split/uap10.0/DateTimePolyfill.cs index 430683e1..c67303de 100644 --- a/src/Split/uap10.0/DateTimePolyfill.cs +++ b/src/Split/uap10.0/DateTimePolyfill.cs @@ -11,18 +11,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanosecond => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microsecond => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } extension(DateTime) { diff --git a/src/Split/uap10.0/TimeSpanPolyfill.cs b/src/Split/uap10.0/TimeSpanPolyfill.cs index 255ad1d2..9dfd4d31 100644 --- a/src/Split/uap10.0/TimeSpanPolyfill.cs +++ b/src/Split/uap10.0/TimeSpanPolyfill.cs @@ -10,18 +10,12 @@ static partial class Polyfill /// Gets the nanosecond component of the time represented by the current object. /// public int Nanoseconds => - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.Ticks % TicksPerMicrosecond) * 100; /// /// Gets the microsecond component of the time represented by the current object. /// public int Microseconds => - (int) (target.TicksComponent() / TicksPerMicrosecond % 1000); - long TicksComponent() - { - var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); - var secondsPart = target - noSeconds; - return secondsPart.Ticks; - } + (int) (target.Ticks / TicksPerMicrosecond % 1000); } const long MicrosecondsToTicks = TimeSpan.TicksPerMillisecond / 1000; const long MicrosecondsPerMillisecond = 1_000; diff --git a/src/Tests/PolyfillTests_MicroNanosecond.cs b/src/Tests/PolyfillTests_MicroNanosecond.cs index 5020e25f..8cf81d48 100644 --- a/src/Tests/PolyfillTests_MicroNanosecond.cs +++ b/src/Tests/PolyfillTests_MicroNanosecond.cs @@ -90,4 +90,158 @@ public async Task Microsecond_and_Nanosecond() await Assert.That(timeSpanValue.Microseconds).IsEqualTo(456); await Assert.That(timeSpanValue.Nanoseconds).IsEqualTo(700); } + + static IEnumerable SampleTicks(long min, long max) + { + yield return min; + yield return max; + foreach (var offset in new long[] {1, 9, 10, 11, 99, 100, 9_999, 10_000, 9_999_999, 10_000_000, 599_999_999, 600_000_000, 600_000_001}) + { + yield return min + offset; + yield return max - offset; + } + + // a fixed sequence spread over the whole range + var range = unchecked((ulong) (max - min)); + var state = 0x9E3779B97F4A7C15UL; + for (var i = 0; i < 2000; i++) + { + state = unchecked(state * 6364136223846793005UL + 1442695040888963407UL); + yield return unchecked(min + (long) (state % range)); + } + } + + [Test] + public async Task DateTime_Microsecond_and_Nanosecond_AllRanges() + { + var failures = new List(); + + foreach (var kind in new[] {DateTimeKind.Unspecified, DateTimeKind.Utc, DateTimeKind.Local}) + { + foreach (var ticks in SampleTicks(DateTime.MinValue.Ticks, DateTime.MaxValue.Ticks)) + { + var value = new DateTime(ticks, kind); + var microsecond = value.Microsecond; + var nanosecond = value.Nanosecond; + + // what is left over once the whole milliseconds are taken out + var whole = new DateTime(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second, value.Millisecond, kind); + var rest = ticks - whole.Ticks; + + if (microsecond != (int) (ticks / 10 % 1000) || + nanosecond != (int) (ticks % 10) * 100 || + microsecond * 10 + nanosecond / 100 != rest) + { + failures.Add($"{kind} {ticks}: {microsecond} {nanosecond}"); + } + } + } + + await Assert.That(failures).IsEmpty(); + } + + [Test] + public async Task DateTimeOffset_Microsecond_and_Nanosecond_AllRanges() + { + var failures = new List(); + var offsets = new[] + { + TimeSpan.Zero, + TimeSpan.FromHours(14), + TimeSpan.FromHours(-14), + new TimeSpan(5, 30, 0), + new TimeSpan(5, 45, 0), + new TimeSpan(-3, -30, 0), + TimeSpan.FromMinutes(1), + TimeSpan.FromMinutes(-1) + }; + + foreach (var offset in offsets) + { + // the range of clock times for which the UTC time is still valid + var min = Math.Max(DateTime.MinValue.Ticks, DateTime.MinValue.Ticks + offset.Ticks); + var max = Math.Min(DateTime.MaxValue.Ticks, DateTime.MaxValue.Ticks + offset.Ticks); + + foreach (var ticks in SampleTicks(min, max)) + { + var value = new DateTimeOffset(ticks, offset); + var microsecond = value.Microsecond; + var nanosecond = value.Nanosecond; + + var whole = new DateTimeOffset(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second, value.Millisecond, offset); + var rest = ticks - whole.Ticks; + + if (microsecond != (int) (ticks / 10 % 1000) || + nanosecond != (int) (ticks % 10) * 100 || + microsecond * 10 + nanosecond / 100 != rest || + microsecond != value.UtcDateTime.Microsecond || + nanosecond != value.UtcDateTime.Nanosecond) + { + failures.Add($"{offset} {ticks}: {microsecond} {nanosecond}"); + } + } + } + + await Assert.That(failures).IsEmpty(); + } + + [Test] + public async Task TimeSpan_Microseconds_and_Nanoseconds_AllRanges() + { + var failures = new List(); + var samples = SampleTicks(TimeSpan.MinValue.Ticks, TimeSpan.MaxValue.Ticks) + .Concat(SampleTicks(-700_000_000, 700_000_000)) + .Concat([0, 1, -1, 9, -9, 10, -10, 1234567, -1234567]); + + foreach (var ticks in samples) + { + var value = new TimeSpan(ticks); + var microseconds = value.Microseconds; + var nanoseconds = value.Nanoseconds; + + // the components add back up to the value, each carrying the sign of the value + var sum = + value.Days * TimeSpan.TicksPerDay + + value.Hours * TimeSpan.TicksPerHour + + value.Minutes * TimeSpan.TicksPerMinute + + value.Seconds * TimeSpan.TicksPerSecond + + value.Milliseconds * TimeSpan.TicksPerMillisecond + + microseconds * 10L + + nanoseconds / 100; + + if (microseconds != (int) (ticks / 10 % 1000) || + nanoseconds != (int) (ticks % 10) * 100 || + sum != ticks || + (ticks >= 0 && (microseconds < 0 || nanoseconds < 0)) || + (ticks <= 0 && (microseconds > 0 || nanoseconds > 0))) + { + failures.Add($"{ticks}: {microseconds} {nanoseconds}"); + } + } + + await Assert.That(failures).IsEmpty(); + } + + [Test] + public async Task TimeSpan_Microseconds_and_Nanoseconds_Limits() + { + // -9223372036854775808 and 9223372036854775807 ticks + await Assert.That(TimeSpan.MinValue.Microseconds).IsEqualTo(-580); + await Assert.That(TimeSpan.MinValue.Nanoseconds).IsEqualTo(-800); + await Assert.That(TimeSpan.MaxValue.Microseconds).IsEqualTo(580); + await Assert.That(TimeSpan.MaxValue.Nanoseconds).IsEqualTo(700); + + var negative = new TimeSpan(-1234567); + await Assert.That(negative.Microseconds).IsEqualTo(-456); + await Assert.That(negative.Nanoseconds).IsEqualTo(-700); + + await Assert.That(DateTime.MinValue.Microsecond).IsEqualTo(0); + await Assert.That(DateTime.MinValue.Nanosecond).IsEqualTo(0); + await Assert.That(DateTime.MaxValue.Microsecond).IsEqualTo(999); + await Assert.That(DateTime.MaxValue.Nanosecond).IsEqualTo(900); + await Assert.That(DateTimeOffset.MinValue.Microsecond).IsEqualTo(0); + await Assert.That(DateTimeOffset.MinValue.Nanosecond).IsEqualTo(0); + await Assert.That(DateTimeOffset.MaxValue.Microsecond).IsEqualTo(999); + await Assert.That(DateTimeOffset.MaxValue.Nanosecond).IsEqualTo(900); + } } \ No newline at end of file