Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a high resolution (microsecond, nanosecond) DateTime object available for the CLR?

I have an instrument that stores timestamps the microsecond level, and I need to store those timestamps as part of collecting information from the instrument. Note that I do not need to generate timestamps; these time stamps are pre-generated by the instrument itself using a high resolution real-time operating system. Parsing out these values is not an issue — they are stored using a standard format in UTC time. Originally I wanted to use the C# DateTime structure can only store time stamps up millisecond resolution.

Is there another object supplied with .NET or a common C# library that supports micro- and (ideally) nanosecond resolution timestamps, or am I going to have to roll my own?

like image 439
Robert P Avatar asked Mar 18 '11 23:03

Robert P


2 Answers

You might be able to use DateTime after all. DateTime.Ticks' resolution is 100 nanoseconds. You can set the ticks with DateTime.AddTicks.

like image 59
steinar Avatar answered Oct 01 '22 23:10

steinar


Looking at the answers, and the DateTime.Ticks property, it's possible to calculate Microseconds and Nanoseconds from the given values. As a result, I put together this extension method class to do it. (Sadly, I don't think I'll be able to use it given some other requirements, but other people may find it useful.)

/// <summary>
/// Extension methods for accessing Microseconds and Nanoseconds of a
/// DateTime object.
/// </summary>
public static class DateTimeExtensionMethods
{
   /// <summary>
   /// The number of ticks per microsecond.
   /// </summary>
   public const int TicksPerMicrosecond = 10;
   /// <summary>
   /// The number of ticks per Nanosecond.
   /// </summary>
   public const int NanosecondsPerTick = 100;

   /// <summary>
   /// Gets the microsecond fraction of a DateTime.
   /// </summary>
   /// <param name="self"></param>
   /// <returns></returns>
   public static int Microseconds(this DateTime self)
   {
      return (int)Math.Floor(
         (self.Ticks 
         % TimeSpan.TicksPerMillisecond )
         / (double)TicksPerMicrosecond);
   }
   /// <summary>
   /// Gets the Nanosecond fraction of a DateTime.  Note that the DateTime
   /// object can only store nanoseconds at resolution of 100 nanoseconds.
   /// </summary>
   /// <param name="self">The DateTime object.</param>
   /// <returns>the number of Nanoseconds.</returns>
   public static int Nanoseconds(this DateTime self)
   {
      return (int)(self.Ticks % TimeSpan.TicksPerMillisecond % TicksPerMicrosecond)
         * NanosecondsPerTick;
   }
   /// <summary>
   /// Adds a number of microseconds to this DateTime object.
   /// </summary>
   /// <param name="self">The DateTime object.</param>
   /// <param name="microseconds">The number of milliseconds to add.</param>
   public static DateTime AddMicroseconds(this DateTime self, int microseconds)
   {
      return self.AddTicks(microseconds * TicksPerMicrosecond);
   }
   /// <summary>
   /// Adds a number of nanoseconds to this DateTime object.  Note: this
   /// object only stores nanoseconds of resolutions of 100 seconds.
   /// Any nanoseconds passed in lower than that will be rounded using
   /// the default rounding algorithm in Math.Round().
   /// </summary>
   /// <param name="self">The DateTime object.</param>
   /// <param name="nanoseconds">The number of nanoseconds to add.</param>
   public static DateTime AddNanoseconds(this DateTime self, int nanoseconds)
   {
      return self.AddTicks((int)Math.Round(nanoseconds / (double)NanosecondsPerTick));
   }
}

This still won't let you set the Microseconds or Nanoseconds upon creation, but they can be added shortly after. It also doesn't give resolution better than what a DateTime can (eg, 1/10 of a microsecond aka 100 nanosecond resolution.)

DateTime time = new DateTime(year, month, day, hour, min, sec, msec);
time = time.AddMicroseconds(microseconds);
time = time.AddNanoseconds(nanoseconds); # note: rounds if not enough added

Here's hoping this works for someone else!

like image 30
Robert P Avatar answered Oct 01 '22 22:10

Robert P