HighPrecisionTimeStamps 1.0.0.4

There is a newer version of this package available.
See the version list below for details.
dotnet add package HighPrecisionTimeStamps --version 1.0.0.4
NuGet\Install-Package HighPrecisionTimeStamps -Version 1.0.0.4
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="HighPrecisionTimeStamps" Version="1.0.0.4" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add HighPrecisionTimeStamps --version 1.0.0.4
#r "nuget: HighPrecisionTimeStamps, 1.0.0.4"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install HighPrecisionTimeStamps as a Cake Addin
#addin nuget:?package=HighPrecisionTimeStamps&version=1.0.0.4

// Install HighPrecisionTimeStamps as a Cake Tool
#tool nuget:?package=HighPrecisionTimeStamps&version=1.0.0.4

High Precision Timestamps

A utility providing convenient and appropriate alternatives to DateTime.Now.

It is well known that DateTime.Now is often used inappropriately. For example, it may be used together with TimeSpan to produce a task's timeout point or subtracted from another DateTime to calculate a duration. This can cause subtle bugs because DateTime is not monotonic: the system clock can change, making the result of the subtraction inaccurate -- potentially causing a premature timeout or an infinite loop. Yet, DateTime is an incredibly convenient and widely used value type in .NET code and is especially useful when printed in ISO-8601 format (with the "O" format specifier).

With the "O" specifier, you can resolution down to tenths of a microsecond, which is nice. Until you learn that the resolution of the system clock is usually more coarse than several milliseconds, making the additional decimal places misleading garbage values. For calculating durations (time between events), it is better to use a high-resolution and monotonic clock like that provided by System.Diagnostics.Stopwatch: on most computers it is far more accurate than DateTime.Now even though, seemingly paradoxically, on a few systems, its resolution is lower than that of DateTime. Also, unsurprisingly, Stopwatch does not provide values that correlate to times of day: while it is appropriate for calculating durations, it is inappropriate for timestamping against a readable date and time.

This library provides timestamps (both as DateTime and as analogous value types it defines) that use the Stopwatch (and your system's high performance event counter) as its clock, but returns values as DateTimes or an analog thereto so that these values can be used for a mixed purpose of timestamping and providing a meaningful way to calculate time elapsed between events.

It provides Monotonic timestamps and High Resolution timestamps.

High Resolution Timestamps

These timestamps are expressed as DateTime values and are derived from Stopwatch. They are calibrated (correlating a reference tick value of the Stopwatch to a reference time value of the system clock) on a per thread basis and have a calibration window that expires. These are suitable for logging times (in a way meaningful to humans) and can be used to measure the time elapsed between events on a single thread within one calibration window. A calibration window by default lasts for fifteen minutes. Eventually, there will be drift between the system clock and the Stopwatch, making re-calibration necessary. Nevertheless, for the resolution provided by Stopwatch, fifteen minutes should be a sufficient period for the intended use-case of these timestamps. Also, you can always manually trigger a calibration.

Monotonic Timestamps

These use the same source (Stopwatch) for their clock, but calibration happens exactly once per process and is the same across all threads. Thus, you can accurately log the time of events across multiple threads and have meaningful data to compare when events happen. Also, because calibration happens once these values are safe to use to calculate a timeout period, how long to perform a task, etc without the possibility that a change to the system clock can cause a bug. Like the High Resolution Timestamps, their fractional seconds are meaningful on every system I have tested. These are essentially dual-use values: they can be used to log timestamps and to calculate durations or time that your application should spend doing a task before quitting or timing out, etc. The monotonic clock provided returns a value type provided by this library rather than DateTime, though the value type is conveniently convertible into a DateTime. This choice was made because the Stopwatch's frequency can vary between systems and these stamps are intended to be used for calculating and measuring durations in addition to logging: it was desirable not to need to calculate a conversion to and from DateTime/TimeSpan scale when obtaining a stamp or performing a duration calculation. For a similar reason, there is a Duration value type that is to the monotonic stamp what System.TimeSpan is to DateTime: a duration value with a matching frequency.

Example Code

An example code project (available at ExampleCode) is available and used to provide a tour of the functionality and its recommended use-cases. All of the example code below can be found therein. For more elaboration, please consult the full Readme.md in the source repository as it is too long to be displayed on NuGet.

Release Notes

Version 1.0.0.4:

This release fixes two bugs.

First (see Issue 21), it fixes a bug where using monotonic timestamps close to the extreme values (within a month or so of 1-1-0001AD and 12-31-9999AD) was causing overflow in .NET 5.0. The fix increased the buffer around the min/max values so that overflow does not occur in .NET 5.0. You may have to alter your uses if you were (for some reason) storing portable monotonic stamps close to the extremes of permissible values.

Second (see Issue 22), it fixes a bug where subtracting a portable duration from a portable monotonic stamp was executing addition, not subtraction.

Finally, please note that unit test applications, example code and test application are now all built and run against .NET 5.0 rather than .NET Core 3.1.

Version 1.0.0.2:

This release fixes a bug (see Issue 19) where the PortableDuration type's FromDays factory methods (and perhaps other From factory methods taking a double as a parameter) used incorrect math and incorrect validation logic.

Version 1.0.0.1:

This release contains no changes to the code itself or to program behavior. Instead it merely fixes the repository url to refer to the source repository rather than the http page that hosts the Github repository. Also, it enables the nuget package to be built deterministically.

Version 1.0.0.0:

This is the non-beta release of the fix introduced with beta version 0.1.1.0-beta. The issues resolved by that release included problems with serialization and deserialization of portable monotonic stamps when serialized on a system with a different DateTime.MinValue.ToUniversalTime() value than the one on which it is deserialized. Those changes are discussed in pull request 14, issue 12 and issue 13. The changes to the code can be reviewed in pull request 14, commit x and, most particularly around these lines of code.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on HighPrecisionTimeStamps:

Package Downloads
DotNetVault

Synchronization Library and Static Analysis Tool for C# 8 DotNetVault is a library and static code analysis tool that makes managing shared mutable state in multi-threaded applications more manageable and less error prone. It also provides a common abstraction over several commonly used synchronization mechanisms, allowing you to change from one underlying type to another (such as from lock free synchronization to mutex/monitor lock based) without needing to refactor your code. Where errors do still occur, they are easier to locate and identify. The project description (a detailed design document) can be read here: https://github.com/cpsusie/DotNetVault/blob/master/DotNetVault_Description_v1.0.pdf. A quick start guide for installation (Windows, Vs 2019+) can be found here: https://github.com/cpsusie/DotNetVault/blob/v0.2.5.x/QuickStart_Install_VS2019_Windows.md. A quick start guide for installation (Tested on Amazon Linux, Rider 2019.3.1+) can be found here: https://github.com/cpsusie/DotNetVault/blob/v0.2.5.x/Quick_Start_Install_Rider_Amazon_Linux.md. A guided tour / quick start guide for this project's functionality can be found here: https://github.com/cpsusie/DotNetVault/blob/v0.2.5.x/Quick_Start_Functionality_Tour.md

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0.7-beta 235 2/1/2022
1.0.0.6 26,977 10/1/2021
1.0.0.4 366 9/19/2021
1.0.0.2 371 9/4/2021
1.0.0.1 462 8/21/2021
1.0.0 444 8/13/2021
0.1.1-beta 325 8/5/2021
0.1.0 505 12/13/2020
0.0.5.4-beta 307 12/6/2020
0.0.5.1-beta 291 11/27/2020
0.0.4-beta 304 11/18/2020
0.0.3-beta 360 11/15/2020
0.0.2-alpha 281 11/14/2020
0.0.1-alpha 386 1/25/2020

#### Version 1.0.0.4:
     This release fixes two bugs.

     First (see [Issue 21][8]), it fixes a bug where using monotonic timestamps close to the extreme values (within a month or so of 1-1-0001AD and 12-31-9999AD) was causing overflow in .NET 5.0.  The fix increased the buffer around the min/max values so that overflow does not occur in .NET 5.0.  You may have to alter your uses if you were (for some reason) storing portable monotonic stamps close to the extrema of permissible values.

     Second (see [Issue 22][9]), it fixes a bug where subtracting a portable duration from a portable monotonic stamp was executing addition, not subtraction.  

     Finally, please note that unit test applications, example code and test application are now all built and run against .NET 5.0 rather than .NET Core 3.1.
     #### Version 1.0.0.2:
     This release fixes a bug (see [Issue 19][1]) where the PortableDuration type's FromDays factory methods (and perhaps other From factory methods taking a double as a parameter) used incorrect math and incorrect validation logic.

     #### Version 1.0.0.1:
     This release contains no changes to the code itself or to program behavior.  Instead it merely fixes the repository url to refer to the source repository rather than the http page that hosts the Github repository.  Also, it enables the nuget package to be built deterministically.

     #### Version 1.0.0.0:
     This is the non-beta release of the fix introduced with beta version 0.1.1.0-beta.  The issues resolved by that release included problems with serialization and deserialization of portable monotonic stamps when serialized on a system with a different DateTime.MinValue.ToUniversalTime() value than the one on which it is deserialized.  Those changes are discussed in [pull request 14][2], [issue 12][3] and [issue 13][4].  The changes to the code can be reviewed in [pull request 14][2], [commit x][6] and, most particularly around [these lines of code][7].

     [1]: https://github.com/cpsusie/High-Precision-Time-Stamps/issues/19
     [2]: https://github.com/cpsusie/High-Precision-Time-Stamps/pull/14
     [3]: https://github.com/cpsusie/High-Precision-Time-Stamps/issues/12
     [4]: https://github.com/cpsusie/High-Precision-Time-Stamps/issues/13
     [5]: https://github.com/cpsusie/High-Precision-Time-Stamps/pull/14
     [6]: https://github.com/cpsusie/High-Precision-Time-Stamps/commit/01670d88755a4775100f7dd9d09eef61e0775555
     [7]: https://github.com/cpsusie/High-Precision-Time-Stamps/blob/01670d88755a4775100f7dd9d09eef61e0775555/PortableMonotonicStamp.cs#L540
     [8]: https://github.com/cpsusie/High-Precision-Time-Stamps/issues/21
     [9]: https://github.com/cpsusie/High-Precision-Time-Stamps/issues/22