A just need a stable count of the current program's progression in milliseconds in C#. I don't care about what timestamp it goes off of, whether it's when the program starts, midnight, or the epoch, I just need a single function that returns a stable millisecond value that does not change in an abnormal manner besides increasing by 1 each millisecond. You'd be surprised how few comprehensive and simple answers I could find by searching.
Edit: Why did you remove the C# from my title? I'd figure that's a pretty important piece of information.
When your program starts create a StopWatch and Start() it.
private StopWatch sw = new StopWatch();
public void StartMethod()
{
sw.Start();
}
At any point you can query the Stopwatch:
public void SomeMethod()
{
var a = sw.ElapsedMilliseconds;
}
If you want something accurate/precise then you need to use a StopWatch, and please read Eric Lippert's Blog (formerly the Principal Developer of the C# compiler Team) Precision and accuracy of DateTime.
Excerpt:
Now, the question “how much time has elapsed from start to finish?” is a completely different question than “what time is it right now?” If the question you want to ask is about how long some operation took, and you want a high-precision, high-accuracy answer, then use the StopWatch class. It really does have nanosecond precision and accuracy that is close to its precision.
If you don't need an accurate time, and you don't care about precision and the possibility of edge-cases that cause your milliseconds to actually be negative then use DateTime.
Do you mean DateTime.Now? It holds absolute time, and subtracting two DateTime instances gives you a TimeSpan object which has a TotalMilliseconds property.
You could store the current time in milliseconds when the program starts, then in your function get the current time again and subtract
edit:
if what your going for is a stable count of process cycles, I would use processor clocks instead of time.
as per your comment you can use DateTime.Ticks, which is 1/10,000 of a millisecond per tick
Also, if you wanted to do the time thing you can use DateTime.Now as your variable you store when you start your program, and do another DateTime.Now whenever you want the time. It has a millisecond property.
Either way DateTime is what your looking for
It sounds like you are just trying to get the current date and time, in milliseconds. If you are just trying to get the current time, in milliseconds, try this:
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
Related
I just ran into some unexpected behavior with DateTime.UtcNow while doing some unit tests. It appears that when you call DateTime.Now/UtcNow in rapid succession, it seems to give you back the same value for a longer-than-expected interval of time, rather than capturing more precise millisecond increments.
I know there is a Stopwatch class that would be better suited for doing precise time measurements, but I was curious if someone could explain this behavior in DateTime? Is there an official precision documented for DateTime.Now (for example, precise to within 50 ms?)? Why would DateTime.Now be made less precise than what most CPU clocks could handle? Maybe it's just designed for the lowest common denominator CPU?
public static void Main(string[] args)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i=0; i<1000; i++)
{
var now = DateTime.Now;
Console.WriteLine(string.Format(
"Ticks: {0}\tMilliseconds: {1}", now.Ticks, now.Millisecond));
}
stopwatch.Stop();
Console.WriteLine("Stopwatch.ElapsedMilliseconds: {0}",
stopwatch.ElapsedMilliseconds);
Console.ReadLine();
}
Why would DateTime.Now be made less precise than what most CPU clocks could handle?
A good clock should be both precise and accurate; those are different. As the old joke goes, a stopped clock is exactly accurate twice a day, a clock a minute slow is never accurate at any time. But the clock a minute slow is always precise to the nearest minute, whereas a stopped clock has no useful precision at all.
Why should the DateTime be precise to, say a microsecond when it cannot possibly be accurate to the microsecond? Most people do not have any source for official time signals that are accurate to the microsecond. Therefore giving six digits after the decimal place of precision, the last five of which are garbage would be lying.
Remember, the purpose of DateTime is to represent a date and time. High-precision timings is not at all the purpose of DateTime; as you note, that's the purpose of StopWatch. The purpose of DateTime is to represent a date and time for purposes like displaying the current time to the user, computing the number of days until next Tuesday, and so on.
In short, "what time is it?" and "how long did that take?" are completely different questions; don't use a tool designed to answer one question to answer the other.
Thanks for the question; this will make a good blog article! :-)
DateTime's precision is somewhat specific to the system it's being run on. The precision is related to the speed of a context switch, which tends to be around 15 or 16 ms. (On my system, it is actually about 14 ms from my testing, but I've seen some laptops where it's closer to 35-40 ms accuracy.)
Peter Bromberg wrote an article on high precision code timing in C#, which discusses this.
I would like a precise Datetime.Now :), so I cooked this up:
public class PreciseDatetime
{
// using DateTime.Now resulted in many many log events with the same timestamp.
// use static variables in case there are many instances of this class in use in the same program
// (that way they will all be in sync)
private static readonly Stopwatch myStopwatch = new Stopwatch();
private static System.DateTime myStopwatchStartTime;
static PreciseDatetime()
{
Reset();
try
{
// In case the system clock gets updated
SystemEvents.TimeChanged += SystemEvents_TimeChanged;
}
catch (Exception)
{
}
}
static void SystemEvents_TimeChanged(object sender, EventArgs e)
{
Reset();
}
// SystemEvents.TimeChanged can be slow to fire (3 secs), so allow forcing of reset
static public void Reset()
{
myStopwatchStartTime = System.DateTime.Now;
myStopwatch.Restart();
}
public System.DateTime Now { get { return myStopwatchStartTime.Add(myStopwatch.Elapsed); } }
}
From MSDN you'll find that DateTime.Now has an approximate resolution of 10 milliseconds on all NT operating systems.
The actual precision is hardware dependent. Better precision can be obtained using QueryPerformanceCounter.
For what it's worth, short of actually checking the .NET source, Eric Lippert provided a comment on this SO question saying that DateTime is only accurate to approx 30 ms. The reasoning for not being nanosecond accurate, in his words, is that it "doesn't need to be."
From MSDN documentation:
The resolution of this property
depends on the system timer.
They also claim that the approximate resolution on Windows NT 3.5 and later is 10 ms :)
The resolution of this property depends on the system timer, which
depends on the underlying operating system. It tends to be between 0.5
and 15 milliseconds.
As a result, repeated calls to the Now property in a short time interval, such as in a loop, may return the same value.
MSDN Link
Imagine we have a dedicated OS thread, that must do something every 4.30 minutes.
You cannot suspend the thread, because it needs to check/do other things, nor can you use await/async, because that would cause the command to drop out of the dedicated OS thread, defeating the purpose of first creating one.
To solve the problem above, I found 2 solutions:
Use System.Diagnostics.Stopwatch to start a new Stopwatch object, and compare it every 1 second if it reached the desired time-frame: if (timer.ElapsedMilliseconds == 258000) { ...}
Use System.DateTime to initialize a DateTime object DateTime.UtcNow.AddMinutes(4.30) and compare that to the current date every 1 second: if (DateTime.UtcNow >= initializedDate) { ... }
First approach uses a Stopwatch. I think the Stopwatch uses a thread to do all the work, which is why I wanted to avoid it?
The second approach uses a lot of DateTime objects. Every 1 second we'd be constructing a new DateTime object of the current date.
The two solutions are equivalent unless you want very high precision: Stopwatch will use a high precision system timer if available and falls back to DateTime if not. To address your concerns:
Stopwatch does NOT use a separate thread. It just reads the system ticks (high or low precision) and does some math for you.
DateTime is a struct so creating a new instance every second should be cheap and put zero pressure on the GC.
I'd use the Stopwatch because it gives me the elapsed time for free. :)
This question is about System.Threading.Thread.Sleep(int). I know there is no method for a decimal value, but I really need to work with decimals.
I have a device which takes 20.37 milliseconds to turn by 1 degree. So, I need to put the code to sleep for an appropriate multiplication of 20.37 (2 degrees = 20.37*2 etc). Since the thread class got no decimal sleep method, how can I do this?
That does not work that way. Sleep will grant you that the thread sats idle for x time, but not that it won't stay idle for more. The end of the sleep period means that the thread is available for the scheduler to run it, but the scheduler may chose to run other threads/processes at that moment.
Get the initial instant, find the final instant, and calculate the current turn by the time passed. Also, do not forget to check how precise the time functions are.
Real-time programming has some particularities in its own as to advice you to seek for more info in the topic before trying to get something to work. It can be pretty extensive (multiprocessing OS vs monoprocessing, priorities, etc.)
Right, as pointed out in the comments, Thread.Sleep isn't 100% accurate. However, you can get it to (in theory) wait for 20.27 milliseconds by converting the milliseconds to ticks, and then making a new TimeSpan and calling the method with it, as follows:
Thread.Sleep(new TimeSpan(202700))
//202700 is 20.27 * TimeSpan.TicksPerMillisecond (which is 10,000)
Again, this is probably not going to be 100% accurate (as Thread.Sleep only guarantees for AT LEAST that amount of time). But if that's accurate enough, it'll be fine.
You can simply divide the integer - I just figured that out.
I needed less than a milisecond of time the thread sleeps so I just divided that time by an integer, you can either define a constant or just type in:
System.Threading.Thread.Sleep(time / 100);
Or what number you want.
Alternatively, as mentioned, you can do it like:
int thisIsTheNumberYouDivideTheTimeBy = 100;
Thread.Sleep(time / thisIsTheNumberYouDivideTheTimeBy);
Its actually quite simple. Hope that helped.
By the way, instead of
System.Threading.Thread.Sleep(x);
you can just type
Thread.Sleep(x);
unless you haven't written
using System.Threading;
in the beginning.
I had the same problem. But as a work around, i substitute the float vslie but convert to int value in the passing. The code itself rounds off for me and the thread sleeps for that long. As i said, its a work around and i'm just saying, not that it's accurate
You can use little bit of math as a workaround.
Let´s assume, that you don´t want to be extremely precise,
but still need overall float precise sleep.
Thread.Sleep(new Random().Next(20,21));
This should give you ~20.5 sleep timing. Use your imagination now.
TotalSleeps / tries = "should be wanted value", but for single sleep interval, this will not be true.
Dont use new Random() make an instance before.
From this article http://blogs.msdn.com/b/ericlippert/archive/2010/04/08/precision-and-accuracy-of-datetime.aspx:
Now, the question “how much time has elapsed from start to finish?” is a completely different question than “what time is it right now?” If the question you want to ask is about how long some operation took, and you want a high-precision, high-accuracy answer, then use the StopWatch class. It really does have nanosecond precision and accuracy that is close to its precision.
The question is - what should I use if I need elapsed time from start to finish and I need 20 ms precision?
StopWatch has much better precision so I'm afraid that I will pay processor time for "extra-precision" which I don't need.
DateTime.Now has exactly precision I need but it also has a lot of extra-stuff like Month, Year etc. and I'm again afraid that this makes it much slower.
This article should help you:
http://www.dijksterhuis.org/timing-function-performance-stopwatch-class/
In general it says that the Stopwatch is the better choice, which is even my personal opinion.
The only (considerable?) overhead of the StopWatch is the incorporation of QueryPerformanceFrequency determining if the StopWatch will go on with high resolution frequency or not. Actually it is an overhead only if it will go without high resolution frequency. Otherwise is a faster option as it gets the timestamp with a WIN32 QueryPerformanceCounter call instead of DateTime.UtcNow.Ticks.
From what I read on the internet untill now StopWatch class from System.Diagnostics namespace is the best class used for timing.
If you want precision under 1 ms remember to use the Elapsed.TotalMilliseconds property to retrieve elapsed time, sw.ElapsedMilliseconds jumps in increments of 1 ms.
using System;
using System.Diagnostics;
namespace MySolution
{
class Program
{
static void Main(string[] args)
{
var sw = Stopwatch.StartNew();
// code to be timed here
sw.Stop();
Console.WriteLine("Run time in ms = {0}", sw.Elapsed.TotalMilliseconds);
}
}
}
Ideally I would like to have something similar to the Stopwatch class but with an extra property called Speed which would determine how quickly the timer changes minutes. I am not quite sure how I would go about implementing this.
Edit
Since people don't quite seem to understand why I want to do this. Consider playing a soccer game, or any sport game. The halfs are measured in minutes, but the time-frame in which the game is played is significantly lower i.e. a 45 minute half is played in about 2.5 minutes.
Subclass it, call through to the superclass methods to do their usual work, but multiply all the return values by Speed as appropriate.
I would use the Stopwatch as it is, then just multiply the result, for example:
var Speed = 1.2; //Time progresses 20% faster in this example
var s = new Stopwatch();
s.Start();
//do things
s.Stop();
var parallelUniverseMilliseconds = s.ElapsedMilliseconds * Speed;
The reason your simple "multiplication" doesn't work is that it doesn't speeding up the passing of time - the factor applies to all time that has passed, as well as time that is passing.
So, if you set your speed factor to 3 and then wait 10 minutes, your clock will correctly read 30 minutes. But if you then change the factor to 2, your clock will immediately read 20 minutes because the multiplication is applied to time already passed. That's obviously not correct.
I don't think the stopwatch is the class you want to measure "system time" with. I think you want to measure it yoruself, and store elapsed time in your own variable.
Assuming that your target project really is a game, you will likely have your "game loop" somewhere in code. Each time through the loop, you can use a regular stopwatch object to measure how much real-time has elapsed. Multiply that value by your speed-up factor and add it to a separate game-time counter. That way, if you reduce your speed factor, you only reduce the factor applied to passing time, not to the time you've already recorded.
You can wrap all this behaviour into your own stopwatch class if needs be. If you do that, then I'd suggest that you calculate/accumulate the elapsed time both "every time it's requested" and also "every time the factor is changed." So you have a class something like this (note that I've skipped field declarations and some simple private methods for brevity - this is just a rough idea):
public class SpeedyStopwatch
{
// This is the time that your game/system will run from
public TimeSpan ElapsedTime
{
get
{
CalculateElapsedTime();
return this._elapsedTime;
}
}
// This can be set to any value to control the passage of time
public double ElapsedTime
{
get { return this._timeFactor; }
set
{
CalculateElapsedTime();
this._timeFactor = value;
}
}
private void CalculateElapsedTime()
{
// Find out how long (real-time) since we last called the method
TimeSpan lastTimeInterval = GetElapsedTimeSinceLastCalculation();
// Multiply this time by our factor
lastTimeInterval *= this._timeFactor;
// Add the multiplied time to our elapsed time
this._elapsedTime += lastTimeInterval;
}
}
According to modern physics, what you need to do to make your timer go "faster" is to speed up the computer that your software is running one. I don't mean the speed at wich it performs calculations, but the physical speed. The close you get to the speed of light ( the constant C ) the greater the rate at which time passes for your computer, so as you approach the speed of light, time will "speed up" for you.
It sounds like what you might actually be looking for is an event scheduler, where you specify that certain events must happen at specific points in simulated time and you want to be able to change the relationship between real time and simulated time (perhaps dynamically). You can run into boundary cases when you start to change the speed of time in the process of running your simulation and you may also have to deal with cases where real time takes longer to return than normal (your thread didn't get a time slice as soon as you wanted, so you might not actually be able to achieve the simulated time you're targeting.)
For instance, suppose you wanted to update your simulation at least once per 50ms of simulated time. You can implement the simulation scheduler as a queue where you push events and use a scaled output from a normal Stopwatch class to drive the scheduler. The process looks something like this:
Push (simulate at t=0) event to event queue
Start stopwatch
lastTime = 0
simTime = 0
While running
simTime += scale*(stopwatch.Time - lastTime)
lastTime = stopwatch.Time
While events in queue that have past their time
pop and execute event
push (simulate at t=lastEventT + dt) event to event queue
This can be generalized to different types of events occurring at different intervals. You still need to deal with the boundary case where the event queue is ballooning because the simulation can't keep up with real time.
I'm not entirely sure what you're looking to do (doesn't a minute always have 60 seconds?), but I'd utilize Thread.Sleep() to accomplish what you want.