I am trying to make a timer in C#. I do this by counting frames then making a variable(seconds) that is equal to the number of frames divided by 60. I also count minutes by having another variable(minutes) that is equal to seconds divided by 60.
The problem
When minutes is upped by one, seconds keeps counting and i am not sure how to fix this. I want to add one to minutes whenever seconds reaches 60 but then go back down to zero without seting minutes to zero.
Here is what I've tried:
int frames = 0;
int seconds = 0;
int minutes = 0;
This is in update:
protected override void Update(GameTime gameTime)
{
minutes = seconds / 60;
seconds = frames / 60;
frames += 1;
I would suggest you just count frames, and derive seconds and minutes from that, whenever you need to. So if you really need to update all the variables in each Update call, you'd have:
frames++;
seconds = (frames / 60) % 60;
minutes = frames / (60 * 60);
Or to be clearer, define some constants:
const int FramesPerSecond = 60;
const int SecondsPerMinute = 60;
const int FramesPerMinute = FramesPerSecond * SecondsPerMinute;
...
frames++;
seconds = (frames / FramesPerSecond) % SecondsPerMinute;
minutes = frames / FramesPerMinute;
(If you need to reset minutes to 0 after an hour, you would need to extend this further.)
It's not clear what you're trying to do though - there may well be a better way of achieving it. If you're definitely trying to count frames, this is fine... but if you're trying to compute elapsed time, you should remember a base time and then subtract that from the current time, rather than relying on a timer firing exactly once per second.
Attention: If you count from 0 to 60 (for minutes and second) you count 61 seconds. So go from 0 to 59 in your conditions.
for example there are 5 fingers at a hand but if we count from 0 we have 6 finger. (are we mutand?)
:)
So, if you don't need System.Threading.Timer or System.Threading.DispatcherTimer, you can just use standard TimeSpan and add miliseconds to it.
Or create your own TimeSpan-like class with automatically incrementing properties.
Related
I'm taken c# class and have to write a program. You burn 5 calories per minute when running on a treadmill. Write a program that uses a loop to display the number of calories burned after 20,35,45 minutes. I know I can use a while or for loop. But problem I have those you use step say of 5 or 10 but as you see 20,35,45 is step 15 then 10 how would I work that into while or for loop?
There are several ways to do this.
Create a for loop and step 5 and check if any matches the given minutes to display. But there are better ways.
I'd rather write something like:
// just make a variable and put the calories per minute in it.
// it's just more clear to read and if you need to use it multiple times,
// it avoids to put the value multiple times in your code.
var caloriesBurnedPerMinute = 5;
// this specifies an array of integers, (it detects that the values are integers.
var minutesToDisplay = new[] { 20, 25, 45 };
// make a loop over each value in the array
foreach(var minutes in minutesToDisplay)
{
// I'd rather don't put the calculations in the writeline, easier to debug.
var caloriesBurned = minutes * caloriesBurnedPerMinute;
// display the value.
Console.WriteLine($"Calories burned after {minutes} is {caloriesBurned}");
}
This way you don't need to write bruteforce loops, which just waste time/energy.
You can test this out by creating a console app and pasting the code in this method into it. It sets calories burned per minute to a constant value of 5. Then iterates through minutes on treadmill starting at 1 minute and ending at 45. After each minute 5 calories are burned and at the minutes specified in the switch statement, the number of calories burned are stored in a variable and displayed to the screen.
private static void Main(string[] args)
{
const int calsBurnedPerMinute = 5;
// i represents minutes between 1 and 45
for (var i = 1; i <= 45; i++)
{
var calsBurned = 0;
switch (i)
{
case 20:
calsBurned = calsBurnedPerMinute * i;
Console.WriteLine("Calories Burned After 20 minutes: " + calsBurned);
break;
case 35:
calsBurned = calsBurnedPerMinute * i;
Console.WriteLine("Calories Burned After 35 minutes: " + calsBurned);
break;
case 45:
calsBurned = calsBurnedPerMinute * i;
Console.WriteLine("Calories Burned After 45 minutes: " + calsBurned);
break;
}
}
Console.ReadKey();
}
Output:
Calories burned after 20 minutes: 100
Calories burned after 35 minutes: 175
Calories burned after 45 minutes: 225
I have a progress that advances according to three operation.
The first operation takes 10 seconds, the second operation takes 15 seconds and the third operation takes 15 seconds.
The progress percentage can be calculated using this formula:
elapsedTime/totalTime * 100%
where totalTime is 10+15+15 = 40 seconds.
Suppose now that each operation can have an error that is calculated at the end of each operation (for example the first operation takes 3 seconds more, so the time to complete it is 13 seconds).
What is the new way to recalculate the progress percentage so that the progress
always goes forward (it should proceed slowly but never go backwards)?
The Maximum of my progress is set to 100.
what if you added the error_Time to both sides? I mean something like this:
(op1+ error_Time_op1 + op2 +op3 )/(totalTime + error_Time_op1 ) * 100%
increase the totalTime by the amount that the error has added to the overall progress
totalTime + error_time
for the progress to go always forward you should freeze the display at the value when the error happens and only proceed to update when the newly_calculated percentage exceeds the remembered value.
image you are at the end of operation 2:
totalTime = 40;
elapsedTime = 25;
old_progress = 25 / 40 * 100 [62.5%]
then the error occurs:
errorTime = 3;
totalTime = 40 + errorTime ;
elapsedTime = 25;
new_progress = 25 / 43 * 100 [58.1%]
now you wait until the new_progress value exceeds the old_progess value and then you can update again. This way it will never go backwards
i want a timer that doesn't count every second. i want it to run slower
timer = timer + Time.deltaTime;
int itimer = (int)timer;
int minutes = itimer % 60;
int hours = itimer / 60;
string time = hours.ToString() + ":" + minutes.ToString().PadLeft(2, '0');
this is the code now. the clock currently starts at 19:20 and i want the minute counter to go up every 4 seconds or something(i still have to figure the exact timing out). i tried doing "Time.deltaTime*0.9", but the code doesn't work like that. how can i best slow it down with this code? also, when it's 20:00 (or 1200 before conversion) i'd like for something to happen, so i still need access to that number
thank you
Likely the problem you had was a casting error when you tried assigning the result back to timer. This is because by default when you did 0.9 it did it as a double and your variable timer was a float. Add a f to the end of the number to mark it a float and it should work.
timer = timer + Time.deltaTime * 0.9f;
int itimer = (int)timer;
int minutes = itimer % 60;
int hours = itimer / 60;
string time = hours.ToString() + ":" + minutes.ToString().PadLeft(2, '0');
I have this absurd situation where i need to support a Custom TimeSpan Format with a unit of Tenths of minutes with Timespan.TryParse.
i.e. hh:mm:t
where t denotes 10ths of minute (6 second intervals)
What would be the easiest way of adding this to the Custom Timespan format parsing specifies?
Is there some override facility that would make this easy?
Edit
var mask = "hmmt";
var value = "0011";
// 0 hours
// 01 minutes
// 1 tenths of minutes
TimeSpan.TryParseExact(value, mask, null, out time)
the mask is configurable by the user and i need the ability to add some sort of custom specifier like "t" to denote tenths of minutes
the user in essence adds this mask, as the value comes from various pabx phone systems that output duration's in many weird and wonderful ways. one of those ways is the use of 10ths of minutes
if I understand correctly, then for example .3 at the end means 3/10 of a minute, making it 18 seconds. If so, this is the way, in case you have time like "hh:mm:t" as you wrote:
public static class TimeSpanExtension
{
public static TimeSpan TryParseTenth(string timeSpanString)
{
//change following line to accomodate date format if needed
timeSpanString += "0";
TimeSpan ts = new TimeSpan();
if (TimeSpan.TryParse(timeSpanString, out ts))
{
// recalculate from tenth of minute into seconds
float realSeconds = ts.Seconds * 60 / 100;
//final operation to correct
return ts.Subtract(new TimeSpan(0, 0, ts.Seconds - (int)realSeconds));
}
else
return TimeSpan.Zero;
}
}
usage:
string time = "06:55:3";
var timeSpan = TimeSpanExtension.TryParseTenth(time);
resulting in 6h55m18s as I wrote at the top
I need to calculate the time difference faken for division most accurately in nano seconds. Please tell me to do this.
At Present i'm using a lower accuracy method in which the problem is that : when the first calculation is performed it shows 87 milliseconds or 65 milliseconds as answer. But when the function is called again second time or more, it only show 0 milliseconds.
The code is :
long startTick = DateTime.Now.Ticks;
double result = (double)22 / 7;
result = System.Math.Round(result, digit);
long endTick = DateTime.Now.Ticks;
long tick = endTick - startTick;
double milliseconds = tick / TimeSpan.TicksPerMillisecond;
time.Text = result + "\nThe division took " + milliseconds + " milliseconds to complete.";
digit is the parameter of function which is variable. No matter what the value of digit is the milliseconds value remains 0 after first calling of function....
Please suggest more accurate way in which calling the same function with different decimal digits will result in different time interval in c# for windows Phone.
I think the memory flush should be done before and after each calculation. But i dont know how to do this.
I don't like this tick method personally for accuracy. I've tried stopwatch also but its not working. Please suggest another method best suited in my case. I want result like : 0.0345 or 0.0714 seconds.
Thanks
You are performing integer division on this line:
double milliseconds = tick / TimeSpan.TicksPerMillisecond;
Even though you are declaring it as a double, a long divided by a long will truncate the decimal. You are better off doing:
double milliseconds = (double)tick / TimeSpan.TicksPerMillisecond;
Or better yet, just ditch the tick stuff all together:
DateTime start = DateTime.Now;
double result = (double)22 / 7;
result = System.Math.Round(result, digit);
DateTime end = DateTime.Now;
double milliseconds = (end - start).TotalMilliseconds;
time.Text = result + "\nThe division took " + milliseconds + " milliseconds to complete.";
You won't be able to get micro or nano level precision, but you will get millisecond precision with a margin of error.
You still may get zero, however. You are trying to time how long a simple division operation takes. You could do millions of division operations in less than a second. You may want to do it 1,000,000 times, then divide the result by a 1,000,000:
DateTime start = DateTime.Now;
for (var i = 0; i < 1000000; i++)
{
double result = (double)22 / 7;
result = System.Math.Round(result, digit);
}
DateTime end = DateTime.Now;
double milliseconds = (end - start).TotalMilliseconds / 1000000;
This still won't be completely realistic, but should get you an actual number.
Since you have the time in ticks, just increase the resolution by multiplying the denominator:
double microseconds = tick / (TimeSpan.TicksPerMillisecond * 1000.0);
Why are you not using StopWatch Class to do your time calulation.
It is meant to the calculate the time the you want ..
Here is a link for your reference.
http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx
//if you want to get the full milliseconds you could also do something like this.
dateStartTime = Convert.ToDateTime(DateTime.Now.TimeOfDay.ToString());
//then where you end the code do this
dateEndTime = Convert.ToDateTime(DateTime.Now.TimeOfDay.ToString());
ddateDuration = (TimeSpan)(dateEndTime - dateStartTime);
then to display out what you are actually looking for in terms of miliseconds do
Console.WriteLine(ddateDuration.ToString().Substring(0, 8));
// or some other method that you are using to display the results