locked
Clock Project- Clock tick errors RRS feed

  • Question

  • I am building a clock, and I have all the design work done, but the clock will not run properly

    Here is the code for the clock:

               

    //vars for Default

                //Is going to return a warning stating that these varibles have no value, and equal 0
                // This is good, because it is telling us that the varible IS assigned AND used
                 int ms;
                 int Min;
                 int Hr;
                 int Sec;
    //               bool WhileTrue = false;            Loop start/stop Controller 
                //vars for default

                //CURRENT ERROR- Tick only going to 1, not continuing, also improper spacing

                 private void Milisecond_Tick(object sender, EventArgs e)
                 {
                     Milisecond.Start();
                     lblMS.Text = (ms + 1).ToString();
                     //need to create a loop
                 } //Milisecond (tick)
                 private void Second_Tick_1(object sender, EventArgs e)
                 {
                     Second.Start();
                     lblSec.Text = (Sec + 1).ToString();
                 } //Seconds
                 private void Minute_Tick(object sender, EventArgs e) //Minutes
                 {
                     Minute.Start();
                     lblMin.Text = (Min + 01).ToString();
                 }
                 private void Hour_Tick(object sender, EventArgs e) //Hours
                 {
                     Hour.Start();
                     lblHour.Text = (Hr + 1).ToString();
                 }
                 private void Day_Tick(object sender, EventArgs e)
                 {
                     Day.Start();
                     //reset here
                     lblHour.Text = "00";
                     lblMin.Text  = "00";
                     lblSec.Text = "00";
                     lblMS.Text = "00";
                 } //Reset On Day 

    _____________ IF YOU NEED MORE OF THE CODE TO DEBUG, ASK!


    • Edited by XLG_DrTankHead Monday, December 1, 2014 3:10 PM Code change
    Monday, December 1, 2014 2:12 PM

Answers

  • The approach you're taking is doomed to fail.

    Just have one timer with a constant rate.  (Perhaps slightly faster than 1 second.)  An interval in the range 30-250 ms should be sufficient.

    Each time you observe a tick, get the current time, then you can extract the individual fields from the DateTime object and put them in your labels.

    private void timer1_Tick( object sender, EventArgs e )
    {
        DateTime currentTime = DateTime.Now;
        labelHour.Text = currentTime.Hour.ToString();
        labelMinute.Text = currentTime.Minute.ToString();
        labelSecond.Text = currentTime.Second.ToString();
    }
    


    Your display is not fast enough to display the time down to the nearest 1 millisecond.  Your screen only refreshes once every 16 milliseconds or so. But really, it's the same concept as the other fields if you continue using the above technique.  You will just fail to observe intermediate times.

    labelMillisecond.Text = currentTime.Millisecond.ToString();

    If you want to make a stopwatch-like timer, then create a TimeSpan object by subtracting the start time from the current time.

    private void timer1_Tick( object sender, EventArgs e )
    {
        DateTime currentTime = DateTime.Now;
        TimeSpan elapsed = currentTime - startTime;
        labelHour.Text = elapsed.Hours.ToString();
        labelMinute.Text = elapsed.Minutes.ToString();
        labelSecond.Text = elapsed.Seconds.ToString();
        labelMillisecond.Text = elapsed.Milliseconds.ToString();
    }
    

    • Proposed as answer by Cor Ligthert Thursday, December 11, 2014 2:24 PM
    • Marked as answer by Kristin Xie Wednesday, December 17, 2014 1:25 AM
    Monday, December 1, 2014 2:50 PM

All replies

  • The approach you're taking is doomed to fail.

    Just have one timer with a constant rate.  (Perhaps slightly faster than 1 second.)  An interval in the range 30-250 ms should be sufficient.

    Each time you observe a tick, get the current time, then you can extract the individual fields from the DateTime object and put them in your labels.

    private void timer1_Tick( object sender, EventArgs e )
    {
        DateTime currentTime = DateTime.Now;
        labelHour.Text = currentTime.Hour.ToString();
        labelMinute.Text = currentTime.Minute.ToString();
        labelSecond.Text = currentTime.Second.ToString();
    }
    


    Your display is not fast enough to display the time down to the nearest 1 millisecond.  Your screen only refreshes once every 16 milliseconds or so. But really, it's the same concept as the other fields if you continue using the above technique.  You will just fail to observe intermediate times.

    labelMillisecond.Text = currentTime.Millisecond.ToString();

    If you want to make a stopwatch-like timer, then create a TimeSpan object by subtracting the start time from the current time.

    private void timer1_Tick( object sender, EventArgs e )
    {
        DateTime currentTime = DateTime.Now;
        TimeSpan elapsed = currentTime - startTime;
        labelHour.Text = elapsed.Hours.ToString();
        labelMinute.Text = elapsed.Minutes.ToString();
        labelSecond.Text = elapsed.Seconds.ToString();
        labelMillisecond.Text = elapsed.Milliseconds.ToString();
    }
    

    • Proposed as answer by Cor Ligthert Thursday, December 11, 2014 2:24 PM
    • Marked as answer by Kristin Xie Wednesday, December 17, 2014 1:25 AM
    Monday, December 1, 2014 2:50 PM
  • The millisecond timer is there to tell me that the timers are running...

    Anyways, having one timer Kind of defeats the purpose of having a HH:MM:SS timer layout

    Monday, December 1, 2014 3:07 PM

  • private void timer1_Tick( object sender, EventArgs e )
    {
        DateTime currentTime = DateTime.Now;
        TimeSpan elapsed = currentTime - startTime;
        labelHour.Text = elapsed.Hours.ToString();
        labelMinute.Text = elapsed.Minutes.ToString();
        labelSecond.Text = elapsed.Seconds.ToString();
        labelMillisecond.Text = elapsed.Milliseconds.ToString();
    }

    This will not work either, it returns error at:

    TimeSpan elapsed = currentTime - startTime;

    error: 

    startTime does not exist in current content
    Monday, December 1, 2014 3:25 PM

  • private void timer1_Tick( object sender, EventArgs e )
    {
        DateTime currentTime = DateTime.Now;
        TimeSpan elapsed = currentTime - startTime;
        labelHour.Text = elapsed.Hours.ToString();
        labelMinute.Text = elapsed.Minutes.ToString();
        labelSecond.Text = elapsed.Seconds.ToString();
        labelMillisecond.Text = elapsed.Milliseconds.ToString();
    }

    This will not work either, it returns error at:

    TimeSpan elapsed = currentTime - startTime;

    error: 

    startTime does not exist in current content

    Well, it's just an example.  In conversation I assumed you would set a start time for a stopwatch-like timer.  I'm not going to write the whole thing for you.  If startTime is the DateTime at which the stopwatch was started, the code works just fine.

    Monday, December 1, 2014 7:35 PM
  • The millisecond timer is there to tell me that the timers are running...

    Anyways, having one timer Kind of defeats the purpose of having a HH:MM:SS timer layout

    I'm very interested to hear from you why you think that "having one timer Kind of defeats the purpose of having a HH:MM:SS timer layout."

    If by "layout" you are referring to formatting the display of the current time, then it doesn't matter.  You can reformat the current time however you wish.  And different cultures will go at it differently.

    I believe you are thinking like this:

    • once per second, the "second" quantity gets incremented.
    • once per minute, the "minute" quantity gets incremented.
    • once per hour, the "hour" quantity gets incremented.

    This is backwards thinking.

    Time is a single scalar quantity that is steadily advancing (relativity aside, for the time being).  You can subdivide the elapsed time into groups of smaller units for display.  Such conversions are complex and involve time zones, leap years, calendars, and a reference point in time, etc.  You shouldn't do those conversions yourself if you can help it.  Rely on your framework to get you the correct conversions.

    ***

    Also, timer events don't correspond well to actual time and they can be delayed or skipped.  So you should rely on DateTime.Now for the actual time and just use timers to control the rate at which you want to update your interface.

    You wouldn't be able to control the phase of how the 1-hour granularity timer fired with respect to the 1-minute granularity timer.  

    You would expect them to fire at slightly different moments.

    With your technique:

    • If hours updates first:  4:59 might first say 5:59, then 5:00.
    • If mins updates first:  4:59 might first say 4:00, then 5:00.

    Your approach is flawed and doesn't keep time.

    If it's the rate at which you want to receive events, then rest assured you can derive an interval timer of any rate based on a single highest resolution timer.  Just like you can keep track of kind of recurring event in your schedule with a single calendar even though they happen scattered throughout the days of the year.


    Monday, December 1, 2014 7:52 PM
  • What you are saying is 1) overly complex for a simple project. 2) STILL NOT WORKING

    private void timer1_Tick( object sender, EventArgs e )
    {
        DateTime currentTime = DateTime.Now;
        TimeSpan elapsed = currentTime - startTime;
        labelHour.Text = elapsed.Hours.ToString();
        labelMinute.Text = elapsed.Minutes.ToString();
        labelSecond.Text = elapsed.Seconds.ToString();
        labelMillisecond.Text = elapsed.Milliseconds.ToString();
    }

    This will not work either, it returns error at:

    TimeSpan elapsed = currentTime - startTime;

    error: 

    startTime does not exist in current content

    START TIME DOES NOT EXIST!

    everything else works.

    Monday, December 1, 2014 8:54 PM
  • My "Backwards thinking" is how I want it to run, I guess i miss-stated my problem, I will grab Screenshots, to show the current errors 
    Monday, December 1, 2014 8:55 PM
  • Well, now I know why you're stuck.

    DateTime startTime = DateTime.Now;
    
    private void timer1_Tick( object sender, EventArgs e )
    {
        DateTime currentTime = DateTime.Now;
        TimeSpan elapsed = currentTime - startTime;
        labelHour.Text = elapsed.Hours.ToString();
        labelMinute.Text = elapsed.Minutes.ToString();
        labelSecond.Text = elapsed.Seconds.ToString();
        labelMillisecond.Text = elapsed.Milliseconds.ToString();
    }
    
    private void buttonStart_Click(object sender, EventArgs e)
    {
        startTime = DateTime.Now;
        timer1.Enabled = true;
    }

    Tuesday, December 2, 2014 12:16 PM
  • I have a complete working wpf clock which I wrote years back as part of learning wpf.
    Do you want it?

    I think I pretty much glommed a few bits of code and xaml together off the internet and played about with them but there's not much code in it.

    There's one timer in it:

        public class ClockTimer : INotifyPropertyChanged
        {
            private Timer timer = new Timer(1000);
    
            public ClockTimer()
            {
                timer.Elapsed += new ElapsedEventHandler((sender, e) => OnPropertyChanged(null));
                timer.Start();
            }
    
            public int SecondsDegrees
            {
                get
                {
                    return DateTime.Now.Second * 6;
                }
            }
    
            public int MinutesDegrees
            {
                get
                {
                    return DateTime.Now.Minute * 6;
                }
            }
    
            public int HoursDegrees
            {
                get
                {
                    return DateTime.Now.Hour * 30 + (int)(DateTime.Now.Minute / 2);
                }
            }
            public String DayOfMonth
            {
                get
                {
                    return DateTime.Now.Day.ToString();
                }
            }


    Hope that helps
    Please don't forget to upvote posts which you like and mark those which answer your question.

    • Edited by Andy ONeill Tuesday, December 2, 2014 3:21 PM
    Tuesday, December 2, 2014 3:20 PM
  • This has helped a little, but I have one more question. How do I get the value of the timer to display on a label
    Thursday, December 11, 2014 1:42 PM
  • It sounds like you want four different labels: one for each of Hours, Minutes, Seconds, and Milliseconds.  Is that absolutely necessary?  You could conceivably just use a single label to display all four values as a single formatted text string.

    Can you please clarify something for me.?  Are you trying to create:

    1. A CLOCK that displays the CURRENT TIME?  Such a clock has no end and no beginning.
    2. A STOPWATCH TIMER that displays a count-up timer relative to when you click a "start" button?  It has a beginning moment (e.g.: when you click the start button) but can count up indefinitely.  Useful for timing how long something takes, and often has a "stop" button to assist in making an accurate measurement.
    3. A COUNTDOWN TIMER that displays remaining time?  Such a timer would display steadily decreasing values that will eventually reach zero, at which point usually some kind of alarm will happen.  This also requires you to decide at which absolute moment in time the alarm will occur (as in an alarm clock set to go off at a specific time in the morning), or how much time is on the timer at the beginning (as in a cooking timer), and when it starts counting down (e.g.: count down for 5 minutes, starting when you click a button.)

    Thursday, December 11, 2014 2:11 PM
  • Sounds to me in an analogy likewise you wise to make H2O (Water)

    However it is already available in the DateTime Struct

    http://msdn.microsoft.com/en-us/library/system.datetime(v=vs.110).aspx

    Keep in mind that the Windows OS is a multitasking OS so more processes are running.


    Success
    Cor


    • Edited by Cor Ligthert Thursday, December 11, 2014 2:26 PM
    Thursday, December 11, 2014 2:23 PM
  • I Have 4 labels and 4 timers for the purpose of debugging
    Thursday, December 11, 2014 2:45 PM
  • You can instance every datetime structure you want with a constructor

    DateTime WhateverTime = new DateTime(1,1,1,12,0,0);



    Success
    Cor


    • Edited by Cor Ligthert Thursday, December 11, 2014 2:58 PM
    Thursday, December 11, 2014 2:57 PM
  • I Have 4 labels and 4 timers for the purpose of debugging

    This is a very brief response and doesn't really clarify anything for me apart from the fact that you are attached to the idea of having 4 timers.  I believe the 4-timer thing will be a problem for you and I'd like to help you do what you want in a simpler way.

    Can you, instead, please provide a screenshot of your form in its current state?  (You mentioned in a previous post that you would do this, but you haven't yet -- maybe now is a good time to follow through on that.) Perhaps it will help us visualize exactly what it is that you're trying to accomplish.  Please include a description.

    I'm trying to help you, but the most you'll get from me is what you ask for, so please try to be more descriptive about what it is that you want.

    Friday, December 12, 2014 1:42 PM