Search code examples
c#dispatchertimer

Start DispatcherTimer from N seconds, minutes, hours


I have been searching for information and couldn't find any. My question is how to start DispatcherTimer from N seconds or minutes or hours. I mean currently it starts from 00:00:00 (also displayed in CurrentTime Label) but if I would like to start it from 00:00:30 (also display in CurrentTime Label), what should be differently?

To clarify it more... When I start an application I execute StartWorkingTimeTodayTimer(). Then I have a Label (CurrentTime) that is starting to show time of application runtime. Currently it starts from 00:00:00. I would like to display for example 00:00:30 at Start and then tick by one second as it is right now... so 00:00:30 -> 00:00:31 -> 00:00:32 -> 00:00:33 -> 00:00:34 ->

I have tried to play with:

DateTime x30SecsLater = StartTimeWholeDay.AddSeconds(30);

without success.

Current code:

private static DateTime StartTimeWholeDay;
private DispatcherTimer _dailyTimer;

public void StartWorkingTimeTodayTimer()
{
    StartTimeWholeDay = DateTime.Now;
    DateTime x30SecsLater = StartTimeWholeDay.AddSeconds(30);

    _dailyTimer = new DispatcherTimer(DispatcherPriority.Render);
    _dailyTimer.Interval = TimeSpan.FromSeconds(1);
    _dailyTimer.Tick += (sender, args) =>
    {
        CurrentTime = (DateTime.Now - StartTimeWholeDay).ToString(@"hh\:mm\:ss"); // DateTime.Now.ToLongTimeString()
    };
    _dailyTimer.Start();
} 

EDIT:

I have tried already:

public void StartWorkingTimeTodayTimer()
{
    StartTimeWholeDay = DateTime.Now;
    DateTime x30SecsLater = StartTimeWholeDay.AddSeconds(30);

    _dailyTimer = new DispatcherTimer(DispatcherPriority.Render);
    _dailyTimer.Interval = TimeSpan.FromSeconds(1);
    _dailyTimer.Tick += (sender, args) =>
    {
        CurrentTime = (DateTime.Now - x30SecsLater).ToString(@"hh\:mm\:ss"); // DateTime.Now.ToLongTimeString()
    };
    _dailyTimer.Start();
}

but it calculates backwards...

enter image description here

It should go the other way 00:00:30 -> 00:00:31 -> 00:00:32 -> 00:00:33 -> 00:00:34 ->


Solution

  • After struggeling a LONG time to get WPF running with a console (in .NET 5) ...I failed, so I'll give the answer using System.Timers. But you get the idea.

    using System;
    using System.Timers;
    
    namespace TimerExample
    {
        class Program
        {
            private static DateTime _startTime;
    
            private static void OnTimedEvent(object source, ElapsedEventArgs eea)
            {
                Console.WriteLine((eea.SignalTime - _startTime)
                    .Add(TimeSpan.FromSeconds(29)) // 29, because the first trigger happens 1 sec after start
                    .ToString(@"hh\:mm\:ss"));
            }
    
            static void Main(string[] args)
            {
                _startTime = DateTime.Now;
                var timer = new Timer
                {
                    Interval = 1000, // msec
                    AutoReset = true,
                };
                timer.Elapsed += OnTimedEvent;
                timer.Start();
    
                Console.WriteLine("Press any key to stop");
                Console.ReadKey();
            }
        }
    }
    

    OR

    using System;
    using System.Timers;
    
    namespace TimerExample
    {
        class Program
        {
            private static DateTime _startTime;
    
            private static void OnTimedEvent(object source, ElapsedEventArgs eea)
            {
                Console.WriteLine((eea.SignalTime - _startTime)
                    .ToString(@"hh\:mm\:ss"));
            }
    
            static void Main(string[] args)
            {
                _startTime = DateTime.Now.AddSeconds(-29); // again 29 instead of 30
                var timer = new Timer
                {
                    Interval = 1000, // msec
                    AutoReset = true,
                };
                timer.Elapsed += OnTimedEvent;
                timer.Start();
    
                Console.WriteLine("Press any key to stop");
                Console.ReadKey();
            }
        }
    }