What is the default time precision of DateTime? - c#

I did a small winform program for data transferring in Visual Studio, and I used a method to provide the transferring time duration. After the transferring being done, the program will return a dialog window to show the time.
But here I don't know what is the time precision or the resolution of the timer, how can it be such a precision, even micro second?
var startTime = DateTime.Now;
this.transferdata();
var endTime = DateTime.Now;
var timeElapsed = endTime.Subtract(startTime);
when I saw the definition of class DateTime, there is only a precision in milisecond. can anybody tell me why there is such a high resolution timer in the visual studio 2012? Or there is related to the operating system?

The precision of the clock depends on the operating system. The system clock ticks a certain number of times per second, and you can only measure whole ticks.
You can test the resolution for a specific computer using code like this:
DateTime t1 = DateTime.Now;
DateTime t2;
while ((t2 = DateTime.Now) == t1) ;
Console.WriteLine(t2 - t1);
On my computer the result is 00:00:00.0156253, which means that the system clock ticks 64 times per second.
(Note: The DateTime type also has ticks, but that is not the same as the system clock ticks. A DateTime tick is 1/10000000 second.)
To measure time more precisely, you should use the Stopwatch class. Its resolution also depends on the system, but is much higher than the system clock. You can get the resolution from the Stopwatch.Frequency property, and on my computer it returns 2143566 which is a tad more than 64...
Start a stopwatch before the work and stop it after, then get the elapsed time:
Stopwatch time = Stopwatch.StartNew();
this.transferdata();
time.Stop();
TimeSpan timeElapsed = time.Elapsed;
That will return the time in the resolution that the TimeSpan type can handle, e.g. 1/10000000 second. You can also calculate the time from the number of ticks:
double timeElapsed = (double)s.ElapsedTicks / (double)Stopwatch.Frequency;

You are confusing several things. Precision, Accuracy, Frequency, and Resolution.
You might have a variable that is accurate to a billion decimal places. But if you can't actually measure that small of a number then that's the difference between precision and resolution. Frequency is the number of times per second a measurement is taken, while relates to resolution. Accuracy is how closely a given sample is to the real measurement.
So, given that DateTime has a precision much higher than the system clock, simply saying DateTime.Now will not necessarily give you an exact timestamp. There are, however, Higher resolution timers in Windows, and the Stopwatch class uses them to measure time elapsed, so if you use this class you get a much better accuracy.
DateTime has no "default precision". It has only one precision, and that's the Minimum and Maximum values it can store. DateTime internally stores it's values as a single value, and this value is formatted to whatever type you want to display (seconds, minutes, days, ticks, whatever...).

Related

C# - most efficient way of measuring ellapsed time

I am working on a C# console application in which I need to know the ellapsed time since the program has started.
I have a variable that stores the time on start (DateTime now = DateTime.Now;)
What is the most efficient way of measuring the ellapsed time?
The ellapsed time can be hours - this is why I am concerned about efficiency and memory usage.
Thanks in advance!
Subtract the current time from the time the program started. This will return a TimeSpan which exposes properties like TotalHours which you can use to calculate the elapsed time.
// on start
var startTime = DateTime.UtcNow;
// later on, to see hours elapsed since then
var elapsed = (DateTime.UtcNow - startTime).TotalHours;
Don't worry. Measuring a time span does not use any resources, as it just compares now with then.
DateTime start = DateTime.Now;
// do some heavy calculation
TimeSpan delta = DateTime.Now - start; // get the time that elapsed
This does not use any resources except the variable for the start, which is just a 64 bit counter.
Note that for short timespans you're better off using Stopwatch, as this is not subject to time adjustments that may happen between start and now.

Verify if a value is a tick in c#

I have a time tick (635655080937662522) I created with C# and stored in a database column. How can I verify that this value is a tick and not something else? Does a tick have a certain format?
As others have said, a tick is just a number, but there are some important differences, depending on where the tick came from.
Ticks from a DateTime or DateTimeOffset are 100ns each, and range from DateTime.MinValue.Ticks to DateTime.MaxValue.Ticks, which is 0 to 3155378975999999999. Note that this is much smaller than Int64.MaxValue.
Ticks from a TimeSpan are also 100ns each, but range from TimeSpan.MinValue.Ticks to TimeSpan.MaxValue.Ticks, which is the same as the range of Int64, which is -9223372036854775808 to 9223372036854775807.
Ticks from a Stopwatch (in the System.Diagnostics namespace) are of varying size, depending on the hardware capabilities of the system. They are usually around 4ns on modern hardware. You can adjust them to TimeSpan ticks by using Stopwatch.Elapsed.Ticks instead of Stopwatch.ElaspedTicks, or by taking the Stopwatch.Frequency into account in your calculations. The range is 0 to Int64.MaxValue.
Tick is a number, there is really not much more validation you can do.
You can check if actual time is in particular range that makes sense for your case, but it is application specific.

how to calculate difference between two DateTime in ms?

According to msdn DateTime precision is 10 ms. So t2-t1 precision in the example below is also 10 ms. However the returned value is "double" what is confusing.
DateTime t1 = DateTime.Now; // precision is 10 ms
....
DateTime t2 = DateTime.Now; // precision is 10 ms
... (t2-t1).TotalMilliseconds; // double (so precision is less than 1 ms???)
I expect int value because double value doesn't make sense when precision is 10 ms. I need to use resulted value in Thread.Sleep(). Should I just cast to int?
The precision of DateTime itself is down to the tick.
The granularity of DateTime.Now is typically 10 or 15ms - it's the granularity of the system clock. (That doesn't mean the clock is accurate to the nearest 10 or 15ms, mind you.) The subtraction operator on DateTime shouldn't know or care about that though - the result is just a TimeSpan which again has a precision to the tick level.
Just casting to int should be absolutely fine.
(You might want to read Eric Lippert's blog post on this, by the way.)

Get time in milliseconds using C#

I'm making a program in which I need to get the time in milliseconds. By time, I mean a number that is never equal to itself, and is always 1000 numbers bigger than it was a second ago. I've tried converting DateTime.Now to a TimeSpan and getting the TotalMilliseconds from that... but I've heard it isn't perfectly accurate.
Is there an easier way to do this?
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
This is actually how the various Unix conversion methods are implemented in the DateTimeOffset class (.NET Framework 4.6+, .NET Standard 1.3+):
long milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds();
Use the Stopwatch class.
Provides a set of methods and
properties that you can use to
accurately measure elapsed time.
There is some good info on implementing it here:
Performance Tests: Precise Run Time Measurements with System.Diagnostics.Stopwatch
The DateTime.Ticks property gets the number of ticks that represent the date and time.
10,000 Ticks is a millisecond (10,000,000 ticks per second).
I use the following class. I found it on the Internet once, postulated to be the best NOW().
/// <summary>Class to get current timestamp with enough precision</summary>
static class CurrentMillis
{
private static readonly DateTime Jan1St1970 = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
/// <summary>Get extra long current timestamp</summary>
public static long Millis { get { return (long)((DateTime.UtcNow - Jan1St1970).TotalMilliseconds); } }
}
Source unknown.
You can try the QueryPerformanceCounter native method. See http://www.pinvoke.net/default.aspx/kernel32/QueryPerformanceCounter.html for more information. This is what the Stopwatch class uses.
See How to get timestamp of tick precision in .NET / C#? for more information.
Stopwatch.GetTimestamp() gives access to this method:
public static long GetTimestamp() {
if(IsHighResolution) {
long timestamp = 0;
SafeNativeMethods.QueryPerformanceCounter(out timestamp);
return timestamp;
}
else {
return DateTime.UtcNow.Ticks;
}
}
I used DateTime.Now.TimeOfDay.TotalMilliseconds (for current day), hope it helps you out as well.
Use System.DateTime.Now.ToUniversalTime(). That puts your reading in a known reference-based millisecond format that totally eliminates day change, etc.
Using Stopwatch class we can achieve it from System.Diagnostics.
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
stopwatch.Stop();
Debug.WriteLine(stopwatch.ElapsedMilliseconds);
System.DateTimeOffset.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt") to get the millisecond in the format of '04/01/2021 04:32:14.788 PM'
https://learn.microsoft.com/en-us/dotnet/standard/base-types/how-to-display-milliseconds-in-date-and-time-values
As I understand your requirements Environment.TickCount fits the bill. It returns number of milliseconds since startup, so it always increases and can be used for computing elapsed time in milliseconds. If you want absolute time also, you can get current time and current Environment.TickCount, and compute new absolute time based on that and new Environment.TickCount.

inaccurate .NET timer?

I'm developing an application and I need to get the current date from a server (it differs from the machine's date).
I receive the date from the server and with a simple Split I create a new DateTime:
globalVars.fec = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, int.Parse(infoHour[0]), int.Parse(infoHour[1]), int.Parse(infoHour[2]));
globalVars is a class and fec is a public static variable so that I can access it anywhere in the application (bad coding I know...).
Now I need to have a timer checking if that date is equal to some dates I have stored in a List and if it is equal I just call a function.
List<DateTime> fechas = new List<DateTime>();
Before having to obtain the date from a server I was using computer's date, so to check if the dates matched I was using this:
private void timerDatesMatch_Tick(object sender, EventArgs e)
{
DateTime tick = DateTime.Now;
foreach (DateTime dt in fechas)
{
if (dt == tick)
{
//blahblah
}
}
}
Now I have the date from the server so DateTime.Now can't be used here. Instead I have created a new timer with Interval=1000 and on tick I'm adding 1 second to globalVars.fec using:
globalVars.fec = globalVars.fec.AddSeconds(1);
But the clock isn't accurate and every 30 mins the clock loses about 30 seconds.
Is there another way of doing what I'm trying to do? I've thought about using threading.timer instead but I need to have access to other threads and non-static functions.
Store the difference between the server's time and local time. Calculate the servers' time when you need it using that difference.
If you create atimer with an interval of 1000ms, it will be called no sooner than 1000ms. So you can pretty much guarantee that it will be called in more than 1000ms, which means you will "lose" time by adding 1s on this timer tick - This will accumulate error with every tick. A better approach is to record a start time and use the current time to determine the current offset from that known start time, so that you don't accumulate any error in your time keeping. (There will still be some error, but you will not drift out of touch with real-time over time)
Different timers (Forms.Timer, Thread.Timer etc) will give different accuracies as well - Forms.Timer is particularly poor for accuracy.
You could also use a high performance time to keep track of the time better - see here, for example.
Here is a reliable 1 μs Timer
See https://stackoverflow.com/questions/15725711/obtaining-microsecond-precision-using-net-without-platform-invoke?noredirect=1#comment22341931_15725711
I guarantee its faster and more accurate then StopWatch and PerformanceCounters and uses the fractions of a second you have in the time slice wisely!

Categories

Resources