How to Get Timestamp of Tick Precision in .Net/C#

How to get timestamp of tick precision in .NET / C#?

The value of the system clock that DateTime.Now reads is only updated every 15 ms or so (or 10 ms on some systems), which is why the times are quantized around those intervals. There is an additional quantization effect that results from the fact that your code is running in a multithreaded OS, and thus there are stretches where your application is not "alive" and is thus not measuring the real current time.

Since you're looking for an ultra-accurate time stamp value (as opposed to just timing an arbitrary duration), the Stopwatch class by itself will not do what you need. I think you would have to do this yourself with a sort of DateTime/Stopwatch hybrid. When your application starts, you would store the current DateTime.UtcNow value (i.e. the crude-resolution time when your application starts) and then also start a Stopwatch object, like this:

DateTime _starttime = DateTime.UtcNow;
Stopwatch _stopwatch = Stopwatch.StartNew();

Then, whenever you need a high-resolution DateTime value, you would get it like this:

DateTime highresDT = _starttime.AddTicks(_stopwatch.Elapsed.Ticks);

You also may want to periodically reset _starttime and _stopwatch, to keep the resulting time from getting too far out of sync with the system time (although I'm not sure this would actually happen, and it would take a long time to happen anyway).

Update: since it appears that Stopwatch does get out of sync with the system time (by as much as half a second per hour), I think it makes sense to reset the hybrid DateTime class based on the amount of time that passes between calls to check the time:

public class HiResDateTime
{
private static DateTime _startTime;
private static Stopwatch _stopWatch = null;
private static TimeSpan _maxIdle =
TimeSpan.FromSeconds(10);

public static DateTime UtcNow
{
get
{
if ((_stopWatch == null) ||
(_startTime.Add(_maxIdle) < DateTime.UtcNow))
{
Reset();
}
return _startTime.AddTicks(_stopWatch.Elapsed.Ticks);
}
}

private static void Reset()
{
_startTime = DateTime.UtcNow;
_stopWatch = Stopwatch.StartNew();
}
}

If you reset the hybrid timer at some regular interval (say every hour or something), you run the risk of setting the time back before the last read time, kind of like a miniature Daylight Savings Time problem.

How to maintain precision using DateTime.Now.Ticks in C#

Do you need all the most-significant bits? (e.g. which year)

Do you need all the least significant bits? (e.g. sub-nanosecond precision)

How long an interval do you need to measure over?

If you need millisecond precision only, why not lose the least significant bits

int timeStamp = (int)(DateTime.Now.Ticks >> 10) // lose smallest 10 bits

edit

the OP wants to store times of recently used items: if this is user selections for a single user, you probably don't want anything shorter than a second! as there are 10^7 ticks per second, there are log(10^7)/log(2)=23 excess bits in the long value!

So how much space do you need? Well, your values ought to specify year, month, day, hour, minute and second; There are about 32 million seconds in a year = about 24 bits. add 3 bits if you want to store the last 10 years worth. So will easily fit into an int32.
I'd suggest

int timeStamp = (int)(DateTime.Now.Ticks >>23) // retain bits 23 to 55

How to get precise DateTime in C#

You can use Stopwatch for more precise measurements of time. You can then have each log entry record the time from the start of the first operation. If it's important, you can record the DateTime of the first operation and therefore calculate the times of the rest, but it sounds like just having the ticks/nanoseconds since the start of the first operation is good enough for your purposes.

High-precision timestamp getter, that returns milliseconds as Int64

If you're on Windows 8 or Server 2012 or higher, use GetSystemTimePreciseAsFileTime as follows:

[DllImport("Kernel32.dll", CallingConvention = CallingConvention.Winapi)]
static extern void GetSystemTimePreciseAsFileTime(out long filetime);

public DateTimeOffset GetNow()
{
long fileTime;
GetSystemTimePreciseAsFileTime(out fileTime);
return DateTimeOffset.FromFileTime(fileTime);
}

This has much, much better accuracy than DateTime.UtcNow.Ticks.

See MSDN for more info: http://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx

DateTime precision?

DateTime.Now calls internally :

public static DateTime Now
{
get
{
return DateTime.UtcNow.ToLocalTime();
}
}

which calls internally:

public static DateTime UtcNow
{
get
{
long systemTimeAsFileTime = DateTime.GetSystemTimeAsFileTime();
return new DateTime((ulong)(systemTimeAsFileTime + 504911232000000000L | 4611686018427387904L));
}
}

where GetSystemTimeAsFile is WindowsAPI function that return system clock information. The accurasy depends on system, so.

If you have a delay, for some reason between different gets (DateTime.Now ) it may produce different enough result that equality comparer fails. But I, personally, never met this kind of condition in my experience.

How to get the unix timestamp in C#

You get a unix timestamp in C# by using DateTime.UtcNow and subtracting the epoch time of 1970-01-01.

e.g.

Int32 unixTimestamp = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;

DateTime.UtcNow can be replaced with any DateTime object that you would like to get the unix timestamp for.

There is also a field, DateTime.UnixEpoch, which is very poorly documented by MSFT, but may be a substitute for new DateTime(1970, 1, 1)

EFCore Postgres timestamp loses tick precision

I tried searching the documentation but I could not find a way to
change the precision of the timestamp in the database. Is there a way?

No, there is not.

Postgres date / time types are alas only accurate to the microsecond (1 / 1,000,000 second).

.NET dates are measured in 100 nanosecond units called ticks (a tick is 1 / 10,000,000 second).

Since there are 10 ticks to every microsecond, .NET dates are not going to be round trippable through Postgres.

Failing that is there a consistent way to round the DateTime to a
precision that won't be lost by the database?

Yes - DateTime has a constructor which takes Ticks. You could, therefore, use item.CreateTime.Ticks to get your initial ticks value, alter it in some way (decide whether you want to ceiling or floor or round or whatever) and then pass it to the constructor. This value (accurate to the microsecond) would then round trip through Postgres just fine.

How to display millisecond on my Date time

You can use MessageBox.Show(highresDT.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));



Related Topics



Leave a reply



Submit