I'm trying to write a fixed timestep.
Stopwatch timer = Stopwatch.StartNew();
TimeSpan dt = TimeSpan.FromSeconds(1/50);
TimeSpan elapsedTime = TimeSpan.Zero;
while(window.IsOpen())
{
timer.Restart();
elapsedTime = timer.Elapsed;
while(elapsedTime > dt)
{
window.DispatchEvents();
elapsedTime -= dt;
gameObject.FixedUpdate(deltaTime goes here as double);
}
}
I want to pass dt as argument to FixedUpdate as a double, is there a way to convert it somehow?
I'm also not quite sure about this line TimeSpan dt = TimeSpan.FromSeconds(1/50); Basically I want dt to hold 1/50th of a second.
Regarding this part TimeSpan.FromSeconds(1/50). TimeSpan.FromSeconds accepts double, 1/50 is int(int/int gives int w/o floating point part), and its value is equal to 0, when passed to method this values gets implicitly converted to double and eventually you get: TimeSpan.FromSeconds(1/50) -> 00:00:00
To make it right, you have to work with double from the beginning and use 1.0/50(1.0 is double):
TimeSpan.FromSeconds(1.0/50) -> 00:00:00.0200000
Regarding this one: gameObject.FixedUpdate(deltaTime goes here as double);
I assume you want to pass milliseconds as and argument value. For that you can write:
gameObject.FixedUpdate(dt.TotalMilliSeconds);
Without knowing the internals of FixedUpdate, you probably want TotalMilliseconds.
Stopwatch timer = Stopwatch.StartNew();
TimeSpan dt = TimeSpan.FromSeconds(1.0/50.0);
TimeSpan elapsedTime = TimeSpan.Zero;
while(window.IsOpen())
{
timer.Restart();
elapsedTime = timer.Elapsed;
while(elapsedTime > dt)
{
window.DispatchEvents();
elapsedTime -= dt;
gameObject.FixedUpdate(dt.TotalMilliseconds);
}
}
Related
Im trying to measure method execution time, but it didn't show the execution time. Can anyone help me to solve the problem?
public static int SequentialSearch(int[] point, int findPoint)
{
DateTime start = DateTime.Now;
int i;
for (i = 0; i < point.Length; i++)
{
if (findPoint== point[i])
{
return i;
}
}
DateTime end = DateTime.Now;
TimeSpan ts = (end - start);
Console.WriteLine("Elapsed Time is {0} ms", ts.TotalMilliseconds);
return -1;
}
There is actually a better way to do this, use StopWatch
//You need this using statement
using System.Diagnostics;
//Set it up, and then start it.
var timer = new Stopwatch();
timer.Start();
//Run your code
MethodToTime();
//Now stop the timer
timer.Stop();
//You can output either directly the elapsed MS
Console.WriteLine($"RunTime {timer.ElapsedMilliseconds}ms");
//Or you can get the elasped time span and output
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);
I have datetime like 2019-02-10 20:39:23 and I want to round this time to the next one apart 15 min to the closest one. So it means the next one should be 2019-02-10 21:45:00 or another example 21:24:17 should became 21:45:00... The code below works fine until I have datetime like 2019-02-10 23:54:20. Then the next one rounded should be 2019-03-10 00:00:00 but I get 2019-02-10 00:00:00.
Here is how I'm doing it:
static void Main(string[] args)
{
DateTime dt = DateTime.Parse("2019-02-10 23:54:23");
var interval = TimeSpan.FromMinutes(15);
DateTime last = NextTime(dt, interval);
Console.WriteLine(last);
}
private static DateTime NextTime(DateTime value, TimeSpan interval)
{
var temp = value.Add(new TimeSpan(interval.Ticks / 2));
var time = new TimeSpan((temp.TimeOfDay.Ticks / interval.Ticks) * interval.Ticks);
return value.Date.Add(time);
}
For output I get 2019-02-10 00:00:00 instead of 2019-03-10 00:00:00
Can't figure out why doesn't turn to next day...
The return value is being calculated from the wrong variable. Use temp instead of value:
private static DateTime NextTime(DateTime value, TimeSpan interval)
{
var temp = value.Add(new TimeSpan(interval.Ticks / 2));
var time = new TimeSpan((temp.TimeOfDay.Ticks / interval.Ticks) * interval.Ticks);
return temp.Date.Add(time);
}
The reason for this is because you're adding your interval to the value. If it rolls over a midnight/end of day your value.Date will return the wrong day. Since you store temp, you can return temp.Date.Add(time)
Using DateTime.Add(TimeSpan) the time is concat in the date.
I'v changed your code in this way and it did the trick:
private static DateTime NextTime(DateTime value, TimeSpan interval)
{
var temp = value.Add(new TimeSpan(interval.Ticks / 2));
var time = new TimeSpan((temp.TimeOfDay.Ticks / interval.Ticks) * interval.Ticks);
if (time == new TimeSpan(0, 0, 0)) { time = new TimeSpan(24, 0,0); }
var timeDiff = time - value.TimeOfDay;
var finalDate = value.AddHours(timeDiff.Hours);
finalDate = finalDate.AddMinutes(timeDiff.Minutes);
finalDate = finalDate.AddSeconds(timeDiff.Seconds);
return finalDate;
}
I believe that must have some way more beautifull to do that but it works.
Hi any ideas on how to calculate time left to a specific hour,
i.e. we start countdown with
if currentTime >= TimeSpan.Parse("06:40") && currentTime <= TimeSpan.Parse("07:25")
and then we parse current hour and end hour (in this example 7:25) and make a label show how many minutes and seconds are left.
I've tried making something with substracting timespan now and end time timespan but it didn't work out at all.
EDIT: The main idea is something like this, but I can't get it to work by using TimeSpan neither DateTime
string myTime;
void timer()
{
var endTime = DateTime.Parse(myTime);
var beginTime = DateTime.Now.TimeOfDay;
}
private void timer1_Tick(object sender, EventArgs e)
{
var endTime = DateTime.Parse(myTime);
var beginTime = DateTime.Now.TimeOfDay;
TimeSpan difference = endTime - beginTime;
TimeSpan currentTime = DateTime.Now.TimeOfDay;
if (currentTime >= TimeSpan.Parse("06:40") && currentTime <= TimeSpan.Parse("07:25"))
{
label5.Text = "0";
myTime = "07:25";
timer();
label6.Text = difference;
}
}
Use DateTime instead of TimeSpan when parsing points in time. TimeSpan is for durations. The difference between two points in time (DateTime) will be a duration (TimeSpan).
var end = DateTime.Parse("21:00");
var now = DateTime.Now; // Could also be some other point in time
TimeSpan timeLeft = end-now;
Console.WriteLine(timeLeft);
Result:
00:24:25.8581440
If you don't like the seconds and fractions of seconds, you can use a custom format, e.g.
Console.WriteLine(timeLeft.ToString("hh\\:mm"));
I need to time the execution of a code sequence written in C#. Using DateTime.Now I get incorrect values for the millisecond field.
For example:
int start_time, elapsed_time;
start_time = DateTime.Now.Millisecond;
for(int i = 0; i < N_ITER; i++) {
// cpu intensive sequence
}
elapsed_time = DateTime.Now.Millisecond - start_time;
elapsed_time gives negative values.
How may I replace DateTime in order to obtain the actual value of the elapsed time?
using System.Diagnostics;
//...
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < N_ITER; i++) {
// cpu intensive sequence
}
stopwatch.Stop();
elapsed_time = stopwatch.ElapsedMilliseconds;
Answer EDITED based on comments
This answer is only trying to count the total elapsed Milliseconds between two times, where the times are derived directly from DateTime.Now. As per the conversation, it's understood that DateTime.Now is vulnerable to outside influences. Hence the best solution would be to use the Stopwatch class. Here's a link that better explains (IMO) and discusses the performance between DateTimeNow, DateTime.Ticks, StopWatch.
Original Answer
The way you cast it into a int is the issue. You need better casting and extra elements :)
This may looks simple compared to an efficient timer. But it works:
DateTime startTime, endTime;
startTime = DateTime.Now;
//do your work
endTime = DateTime.Now;
Double elapsedMillisecs = ((TimeSpan)(endTime - startTime)).TotalMilliseconds;
There is a reference on the web, you may want to check out as well.
You're looking for the Stopwatch class. It is specifically designed to bring back high-accuracy time measurements.
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < N_ITER; i++)
{
// cpu intensive sequence
}
stopwatch.Stop();
var elapsed = stopwatch.ElapsedMilliseconds;
Stopwatch there are examples in the URL
https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=netframework-4.8
using System.Diagnostics;
//...
Stopwatch watch = new Stopwatch();
watch.Start();
// here the complex program.
//...
watch.Stop();
TimeSpan timeSpan = watch.Elapsed;
Console.WriteLine("Time: {0}h {1}m {2}s {3}ms", timeSpan.Hours, timeSpan.Minutes,
timeSpan.Seconds, timeSpan.Milliseconds);
DateTime.Millisecond just returns the millisecond fraction of the second, from 0-999. You would need to take the rest of the datetime into consideration when doing timings.
However, you should look at using the StopWatch class for these kinds of performance timings.
This works for me:
var lapsedTime = DateTime.Now.Subtract(beginTime).TotalMilliseconds;
Here is what I used to obtain the time for a simple computation:
class Program
{
static void Main(string[] args)
{
Decimal p = 0.00001m;
Decimal i = 0m;
DateTime start = new DateTime();
DateTime stop = new DateTime();
for (i = p; i <= 5; i = i + p)
{
Console.WriteLine("result is: " + i);
if (i==p) start = DateTime.Now;
if (i==5) stop = DateTime.Now;
}
Console.WriteLine("Time to compute: " + (stop-start));
}
}
I have a counter that counts up every 1 second and add 1 to an int.
Question
How can I format my string so the counter would look like this:
00:01:23
Instead of:
123
Things I've tried
Things I've tried so far:
for (int i = 0; i < 1; i++)
{
_Counter += 1;
labelUpTime.Text = _Counter.ToString();
}
My timer's interval is set to: 1000 (so it adds 1 every second).
I did read something about string.Format(""), but I don't know if it is applicable.
Thanks if you can guide me through this :D!
Use a TimeSpan:
_Counter += 1;
labelUpTime.Text = TimeSpan.FromSeconds(_Counter).ToString();
You could make it a TimeSpan (for that's what it is, a span of time), then format that:
labelUpTime.Text = TimeSpan.FromSeconds(_Counter).ToString();
Don't use a counter, and don't rely on the timer firing exactly every second. It won't. Do something like this.
class TimerTest
{
private DateTime _start = DateTime.Now;
private Timer _timer = new Timer(1000);
public TimerTest()
{
// (DateTime.Now - _start) returns a TimeSpan object
// Default TimeSpan.ToString() returns 00:00:00
_timer.Elapsed = (o, e) => labelUpTime.Text = (DateTime.Now - _start).ToString();
}
}
You can adjust the formatting with the TimeSpan.ToString method.
TimeSpan timer = new TimeSpan(0);
and on your interval:
timer += TimeSpan.FromSeconds(1);
Use timespan. To add a second use
mytimespan.Add(new TimespanFromSeconds(1));
Console.WriteLine(mytimespan); //Output in the form of xx:xx:xx
http://www.dotnetperls.com/timespan
it worked well for me
public TimeSpan ElapsedTimeFormatted
{
get
{
if (FinishedOn != null &&
StartedAt != null)
{
TimeSpan durationCount = new TimeSpan();
int hours = 0;
int minutes = 0;
int seconds = 0;
var times = Segments.Select(c => c.ElapsedTimeFormatted).ToList();
foreach (var time in times)
{
TimeSpan timeParse = TimeSpan.Parse(time);
hours = hours + (int)timeParse.Hours;
minutes = minutes + (int)timeParse.Minutes;
seconds = seconds + (int)timeParse.Seconds;
durationCount = new TimeSpan(hours, minutes, seconds);
}
return durationCount;
}
return new TimeSpan();
}
}