DateTime newDate = new DateTime(2013, 1, 1);
void AddTime()
{
timer1.Interval = 600000;
timer1.Enabled = true;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
void timer1_Tick(object sender, EventArgs e)
{
newDate = newDate.AddMonths(+3);
lblDate.Text = newDate.ToString();
}
For some reason changing the timer1.Interval does not change the speed of 3 months being added to the newDate, it is always constant. I am trying to have 1 minute real life time equal 3 months in the game.
I am using C#.
Your initial timer interval is bit larger. Below is sample complete application. working as expected
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
DateTime newDate = new DateTime(2013, 1, 1);
public Form1()
{
InitializeComponent();
AddTime(); // call the method, otherwise timer will not start
}
void AddTime()
{
timer1.Interval = 60000; // every minute (1 minute = 60000 milliseconds)
timer1.Enabled = true;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
void timer1_Tick(object sender, EventArgs e)
{
newDate = newDate.AddMonths(3);
label1.Text = newDate.ToString();
}
// if you need to set timet interval after timer start, do as below
private void button1_Click(object sender, EventArgs e)
{
timer1.Stop();
timer1.Interval = 30000; // set interval 30 seconds
timer1.Start();
}
}
}
Make sure the value .Interval is the one you want.
You have 600 000 that is 600 seconds or 10 min.
Did you give enough time to run the event?
Debug it and put a breakpoing.
Your interval is way too high currently, it's 600 seconds instead of 60:
DateTime newDate = new DateTime(2013, 1, 1);
void AddTime()
{
timer1.Interval = 60000; // was 600 seconds, now 60
timer1.Enabled = true;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
void timer1_Tick(object sender, EventArgs e)
{
newDate = newDate.AddMonths(3); // + sign shouldn't be here
lblDate.Text = newDate.ToString();
}
Edit:
Now I see that you aren't calling AddTime() at the moment, and are unclear of where to do it. It is hard to say without more information, but if you are using Winforms you could use the form's load event. Or if it's a class you could use the constructor to call it.
Basically the method that initialises the object that you are working with.
You're going about it the wrong way. First compute the RATIO of "game time" to "normal time". Months, however, are problematic since the number of days in a month is variable. Instead, we can use a quarter (365 / 4) and work from there. Use a Stopwatch to track how much time has elapsed, and add that to the reference date to get "real time". "Game time", then, is simply the elapsed time multiplied by the ratio, and then added to the reference time. Using this model, the Timer Interval() is IRREVELANT; we could update once a minute, once a second, or four times a second, and the code for determining real/game time is completely the same...and all times remain accurate when we update the display:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// update once per second, but the rate here is IRREVELANT...
// ...and can be changed without affecting the real/game timing
timer1.Interval = 1000;
timer1.Tick += new EventHandler(timer1_Tick);
}
private DateTime dtReal;
private DateTime dtGame;
private DateTime dtReference;
private System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
private double TimeRatio = (TimeSpan.FromDays(365).TotalMilliseconds / 4.0) / TimeSpan.FromMinutes(1).TotalMilliseconds;
private void button1_Click(object sender, EventArgs e)
{
StartTime();
}
private void StartTime()
{
dtReference = new DateTime(2013, 1, 1);
SW.Restart();
timer1.Start();
}
void timer1_Tick(object sender, EventArgs e)
{
UpdateTimes();
DisplayTimes();
}
private void UpdateTimes()
{
double elapsed = (double)SW.ElapsedMilliseconds;
dtReal = dtReference.AddMilliseconds(elapsed);
dtGame = dtReference.AddMilliseconds(elapsed * TimeRatio);
}
private void DisplayTimes()
{
lblReference.Text = dtReference.ToString();
lblReal.Text = dtReal.ToString();
lblGame.Text = dtGame.ToString();
}
}
Edit: Added screenshots...
Just after ONE minute = approx 3 months
Just after FOUR minutes = approx 1 year
Related
i'm trying to implement a simple countdown using Timer (using https://www.geoffstratton.com/cnet-countdown-timer code). it does work if i run the timer once but if i stop the timer or the timer goes to 00:00 the next time i'll start it, it will go 2x faster. if i stop it and start it again it will go 3x faster.
(my explaination may be not clear, i did a gif that demonstrate the problem)
https://media.giphy.com/media/fQr7sX6LNRECvQpCYP/giphy.gif
i'm very novice at c#, i usually figure things out but i cant get what's happening here.
I included the timer code. if somebody can help me with this it would be awesome!
Thanks !!!
private void btnStartTimer_Click(object sender, EventArgs e)
{
if (txtTimer.Text == "00:00")
{
MessageBox.Show("Please enter the time to start!", "Enter the Time", MessageBoxButtons.OK);
}
else
{
string[] totalSeconds = txtTimer.Text.Split(':');
int minutes = Convert.ToInt32(totalSeconds[0]);
int seconds = Convert.ToInt32(totalSeconds[1]);
timeLeft = (minutes * 60) + seconds;
btnStartTimer.Enabled = false;
btnCleartimer.Enabled = false;
txtTimer.ReadOnly = true;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
}
private void btnStopTimer_Click(object sender, EventArgs e)
{
timer1.Stop();
timeLeft = 0;
btnStartTimer.Enabled = true;
btnCleartimer.Enabled = true;
txtTimer.ReadOnly = false;
}
private void btnCleartimer_Click(object sender, EventArgs e)
{
txtTimer.Text = "00:00";
}
private void timer1_Tick(object sender, EventArgs e)
{
if (timeLeft > 0)
{
timeLeft = timeLeft - 1;
// Display time remaining as mm:ss
var timespan = TimeSpan.FromSeconds(timeLeft);
txtTimer.Text = timespan.ToString(#"mm\:ss");
// Alternate method
//int secondsLeft = timeLeft % 60;
//int minutesLeft = timeLeft / 60;
}
else
{
timer1.Stop();
SystemSounds.Exclamation.Play();
MessageBox.Show("Time's up!", "Time has elapsed", MessageBoxButtons.OK);
}
}
You need to unsubscribe from the event in your btnStopTimer_Click method:
timer1.Tick -= timer1_Tick;
You are adding the event to Count every time you start the timer. As a result, the first time you call it there is only one event, the second time two events and so on. As a result, you first go down one second, then two,....
I would recommend creating the timer separately and just call Start and Stop.
Alternativ, user Dmitry Korolev answered a good Approach if you don't want to create the timer somewhere else
timer1.Tick -= timer1_Tick;
Quick question. I'm doing a project that when I open the the form it starts a timer.
When the timer is 1:00 after 1 minute it goes to 0:59 like it's supposed to happen.
But when I put the timer to 2:00 after 1 minute it goes to 1:59. I put the timer interval faster just to see what it would look like. And when it reachs 1:00 instead of becoming 0:59 becomes 1:59. I know that my code is wrong but I can't correct it.
public partial class Form9 : Form
{
private int quick = 1800;
public Form9()
{
InitializeComponent();
}
private void Form9_Load(object sender, EventArgs e)
{
timer1 = new System.Windows.Forms.Timer();
timer1.Interval = 60000;
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
quick--;
label1.Text = quick / 900 + ":" + ((quick % 60) >= 10 ? (quick % 60).ToString() : "0" + (quick % 60));
}
}
Thanks in advance!
You can use built-in type TimeSpan instead.
private TimeSpan quick = TimeSpan.FromHours(2); // 2 hours
private void timer1_Tick(object sender, EventArgs e)
{
quick -= TimeSpan.FromMinutes(1); // subtract 1 minute
label1.Text = string.Format("{0:h\\:mm}", quick);
}
How to format Timespan
I wrote a simple program that uses a timer to fade out a label. I found that the timer is so imprecise and the interval is shorter and shorter.
The following code proves my thought:
(I also implement it by StopWatch. The interval between ticks is almost equal.)
private void timer1_Tick(object sender, EventArgs e)
{
elapsed += timer1.Interval;
timerTest.AppendText(DateTime.UtcNow.Second.ToString() + "." + DateTime.UtcNow.Millisecond.ToString() + "\r\n");
if (elapsed >= target)
timer1.Stop();
}
int elapsed = 0;
int target = 4000;
private void button_Click(object sender, EventArgs e)
{
labelFadeout.ForeColor = Color.Greed;
elapsed = 0;
timer1.Interval = 100;
timer1.Tick += timer1_Tick;
timer1.Start();
}
And the 1st and 5th output result in a large difference!
[1st] [5th]
20.318 42.955
20.377 42.956
20.491 42.957
20.595 42.958
20.707 42.959
20.814 43.68
20.929 43.69
21.34 43.7
21.142 43.71
21.257 43.72
21.365 43.173
21.471 43.176
21.584 43.177
21.692 43.179
21.8 43.18
21.909 43.286
22.19 43.288
22.127 43.289
22.242 43.291
22.347 43.293
22.454 43.397
22.569 43.4
22.673 43.402
22.784 43.404
22.892 43.406
23.4 43.649
23.112 43.652
23.221 43.655
23.331 43.657
23.494 43.66
23.549 43.746
23.662 43.749
23.779 43.751
23.879 43.754
23.991 43.756
24.95 43.846
24.209 43.848
24.316 43.851
24.427 43.853
24.534 43.855
I've checked
Comparing the Timer Classes in the .NET Framework Class Library
and Limitations of the Windows Forms Timer Component's Interval Property
and still curious about how it could be so imprecise. Anyone could explain this??
Your method for testing your interval is off. You're really just getting a part of the current time at an interval and expecting it to be comparable to the last time you took it.
If you want to test how much time a timer really takes to tick at a 100 interval. Use an actual Stopwatch, and check out it's Elapsed to find out how much time as passed.
Stopwatch stopwatch = new Stopwatch();
int elapsed = 0;
int target = 4000;
private void timer1_Tick(object sender, EventArgs e)
{
elapsed += timer1.Interval;
timerTest.AppendText(stopwatch.Elapsed.TotalSeconds.ToString());
stopwatch.Restart();
if (elapsed >= target)
timer1.Stop();
}
private void button1_Click(object sender, EventArgs e)
{
elapsed = 0;
timer1.Interval = 100;
timer1.Tick += timer1_Tick;
stopwatch.Start();
timer1.Start();
}
My result:
0.1055445
0.0872668
0.1121169
0.1032453
0.1066107
0.1097218
0.103818
0.1079014
...
so, i want this: if specific time passed (for example 9 hours) from loading form, than i want to show messagebox said "9 hours passed". my code is this:
public partial class Form1 : Form
{
Stopwatch stopWatch = new Stopwatch();
public Form1()
{
InitializeComponent();
stopWatch.Start();
}
private void button1_Click(object sender, EventArgs e)
{
double sec = stopWatch.ElapsedMilliseconds / 1000;
double min = sec / 60;
double hour = min / 60;
if (hour == 9.00D)
{
stopWatch.Stop();
MessageBox.Show("passed: " + hour.ToString("0.00"));
}
}
}
and the problem is that i don't know where to write this part of code:
if (hour == 9.00D)
{
stopWatch.Stop();
MessageBox.Show("passed: " + hour.ToString("0.00"));
}
so, where i write this code? if you have better way of doing this, please show me.
In addition to using a Timer as outlined by the others, you can directly use the TotalHours() property of the TimeSpan returned by Stopwatch.Elapsed:
TimeSpan ts = stopWatch.Elapsed;
if (ts.TotalHours >= 9)
{
MessageBox.Show("passed: " + ts.TotalHours.ToString("0.00"));
}
What people are not appreciating is that it is very unlikely that the double hours will be exactly 9.00! Why not just ask your timer to fire once, after the time you want, 9 hours.
Timer timer;
public Form1()
{
InitializeComponent();
timer.Tick += timer_Tick;
timer.Interval = TimeSpan.FromHours(9).TotalMilliseconds;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
MessageBox.Show("9 hours passed");
}
In order to do a specific task after a specific period of time System.Forms.Timer should be used (in case of windows forms). You can use its Elapsed event and in that you can implement your conditions.
Try using Timer instead. Example from here
Timer timer;
public Form1()
{
InitializeComponent();
timer.Tick += new EventHandler(timer_Tick); // when timer ticks, timer_Tick will be called
timer.Interval = (1000) * (10); // Timer will tick every 10 seconds
timer.Enabled = true; // Enable the timer
timer.Start(); // Start the timer
}
void timer_Tick(object sender, EventArgs e)
{
double sec = stopWatch.ElapsedMilliseconds / 1000;
double min = sec / 60;
double hour = min / 60;
if (hour == 9.00D)
{
stopWatch.Stop();
MessageBox.Show("passed: " + hour.ToString("0.00"));
}
}
Use Timer:
Timer regularly invokes code. Every several seconds or minutes, it
executes a method. This is useful for monitoring the health of an
important program, as with diagnostics. The System.Timers namespace
proves useful.
see this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
stopWatch.Start();
tm.Interval = 1000;
tm.Enabled = true;
tm.Tick += new EventHandler(tm_Tick);
tm.Start();
}
void tm_Tick(object sender, EventArgs e)
{
double sec = stopWatch.ElapsedMilliseconds / 1000;
double min = sec / 60;
double hour = min / 60;
if (hour == 9.00D)
{
stopWatch.Stop();
MessageBox.Show("passed: " + hour.ToString("0.00"));
}
}
}
I have a sync timer in my app that fires up a function at a given time... now I want to know how much time is left until the next call to that function.
This is my call to the timer:
var syncTime = time.activitylog;
double time = TimeSpan.Parse(syncTime).TotalMilliseconds;
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler(DisplayTimeEvent);
myTimer.Interval = time;
myTimer.Start();
How do I get the time until next call?
Thanks
You can use another timer, and set the Interval of that the value that you want,exactly a part time of the Interval of original timer.
Then start them Simultaneously,I mean at the same time.
UPDATE :
Maybe this code describes my solution better :
public Form1()
{
InitializeComponent();
}
System.Windows.Forms.Timer trOriginal = new System.Windows.Forms.Timer();
System.Windows.Forms.Timer trRemain = new System.Windows.Forms.Timer();
double remain = 0;
private void button1_Click(object sender, EventArgs e)
{
trOriginal.Interval = 1000;
trRemain.Interval = 1;
trOriginal.Tick += new EventHandler(trOriginal_Tick);
trRemain.Tick += new EventHandler(trRemain_Tick);
trOriginal.Start();
trRemain.Start();
}
void trRemain_Tick(object sender, EventArgs e)
{
remain -= trRemain.Interval;
Console.WriteLine("remain MS to next event : " + remain);
}
void trOriginal_Tick(object sender, EventArgs e)
{
remain = trOriginal.Interval;
}
You can use a System.Diagnostics.Stopwatch to keep track of how much time has passed already and restart the Stopwatch with every tick of your Timer.
Stopwatch watch = new Stopwatch();
private void DisplayTimeEvent(object sender, EventArgs e)
{
watch.Restart();
// Whatever is supposed to happen, when the timer ticks
}
Now whenever you want to know how much time is left until the event is fired next, you can do this:
long timeLeft = myTimer.Interval - watch.ElapsedMilliseconds;