How to display Timer with day, hour etc - c#

I'm trying to create a Timer which records the users 'Time Played' as you can expect the Timer should be ticking every second. I want it to be displayed as:
0d 12h 11m 23s
This is what I have so far:
private void TimePlayedTimer_Start()
{
timePlayedStr = "00:00:00:00";
timePlayed = new DispatcherTimer();
timePlayed.Tick += timePlayedTimer_Tick;
timePlayed.Interval = new TimeSpan(0, 0, 0, 1);
timePlayed.Start();
}
timePlayedStr is what is retrieved from the localStorage but in this example I have just set it to "00:00:00:00" to make it easier to understand
Then I have a tick event:
void timePlayedTimer_Tick(object sender, object e)
{
DateTime newDateTime = Convert.ToDateTime(timePlayedStr).AddSeconds(1);
string newDateTimeStr = newDateTime .ToString("dd:HH:mm:ss");
}
So I basically want it to add a second every tick then when it gets to 60 seconds it'll add a minute, then hour then day, but then I want it displayed like:
0d 12h 11m 23s
Does anyone know what I am doing wrong?

To display your "time" in the "0d 12h 11m 23s" format, use
string newDateTimeStr = newDateTime.ToString("d'd ' H'h ' m'm ' s's'");
the parts between the ' are used verbatim, not interpreted as placeholder.
EDIT
When you have a TimeSpan, use this to get to your display format:
string displayTimeStr = storedTimespan.ToString(#"d\d\ h\h\ m\m\ s\s");
here all non-format characters (including spaces) need to be escaped by a backslash, which itself doesn't need to be escaped because of the #verbatim string.

Two Steps:
1.
Save the time when you have started playing.
2. Create a timer with a update function and substract the actual time with the time started. then you get a TimeSpan which is the time played.
using System.Timers;
public class Test
{
DateTime StartTime { get; set; }
TimeSpan TimePlayed { get; set; }
Timer Timer { get; set; }
public Test()
{
Timer = new Timer() {Interval = 1000};
Timer.Elapsed += Update;
Timer.Start();
StartTime = DateTime.Now;
}
private void Update(object sender, ElapsedEventArgs e)
{
TimePlayed = DateTime.Now - StartTime;
}
}
For sure you can do .ToString(...) and get the format you like - as you did in your code.
I am no App developer so i don't know how C# works on phone. but if you quit the app you should save the time. a super easy way should be saving the time in a file like this:
private const string FileNameAndLocation = "yourfilename.txt";
private void AppClosing()
{
using (StreamWriter sw = new StreamWriter(FileNameAndLocation))
{
sw.WriteLine(StartTime.ToString());
}
}
private void AppStarting()
{
if (!File.Exists(FileNameAndLocation))
{
StartTime = DateTime.Now;
return;
}
using (StreamReader sr = new StreamReader(FileNameAndLocation))
{
var line = sr.ReadLine();
StartTime = Convert.ToDateTime(line);
}
}

Related

C# / Xamarin how to make 24hour count down timer from one point

here is what i want to do.
i'm using Xamarin Android and trying to make a 24hour count down timer.
the timer text should be updated every second
when the app relaunches it should continue with saved time.
DateTime timeStartedCountDown;
timer should calculate time from one point. (not runtime delay)
eg) what i want =
DateTime timeStartedCountDown;
every second
DisplayLeftTime(24 + (timeStartedCountDown - currentTime)) ? some like this
not what i want =
int timeElapsed;
every second
timeElapsed += 1;
text.Text = twentyFourHoursSec - timeElapsed
i'm not familiar with time & Threading sorry..
ps. android java code is fine!
This starts a timer the first time you open the app.
It recalls the startTime by using ISharedPreferences. And updates the date each second in the Thread.
public class MainActivity : Activity
{
DateTime startTime = DateTime.Now;
Thread thread;
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences (this);
ISharedPreferencesEditor editor = prefs.Edit ();
long memStartTime = prefs.GetLong ("startTime", 0);
if (memStartTime != 0) {
startTime = new DateTime (memStartTime);
} else {
editor.PutLong ("startTime", startTime.Ticks);
editor.Apply();
}
TimerUpdate ();
}
void TimerUpdate () {
if (thread == null) {
thread = new Thread (delegate () {
while (true) {
Thread.Sleep (1000);
DateTime curTime = DateTime.Now;
Console.WriteLine (curTime - startTime);
//Update your on screen textview.
}
});
thread.Start ();
}
}
}

Issue with DispatcherTimer for a Countdown clock

I have started developing a quiz app that will have a 60 second count down for each question. I searched other issues but could not find my specific issue. When the first question is displayed the screen dsplays "60" and the countdown proceeds normally. However, when the second questions is generated (after a button click submit) the counter starts again, but this time uses 2 second intervals. Then when the third question generates after a click, it counts down in 3 second intervals! I then noticed that the timer display starts 1 second less in each question. (ex Question 1 starts with 60, Question 2 starts with 59......)
This is my first time using DispatcherTimer so I'm learning as I go. My goal is for the timer to always countdown in 1 second intervals.
public sealed partial class QuickPage : Page
{
DispatcherTimer timeLeft = new Dispatcher();
int timesTicked = 60;
public void CountDown()
{
timeLeft.Tick += timeLeft_Tick;
timeLeft.Interval = new TimeSpan(0,0,0,1);
timeLeft.Start();
}
public void timeLeft_Tick(object sender, object e)
{
lblTime.Text = timesTicked.ToString();
if (timesTicked > 0)
{
timesTicked--;
}
else
{
timeLeft.Stop();
lblTime.Text = "Times Up";
}
}
}
I then use a button click where if th user is right:
timeLeft.Stop();
timesTicked = 60
QuestionGenerator();
The Question Generator fucntion looks like this:
private void QuestionGenerator()
{
CountDownTimer();
if (iAsked < 6)
{
//Code to generate random question
}
}
Do not subscribe to the DispatcherTimer every time you call CountDown.
DispatcherTimer timeLeft;
int timesTicked = 60;
public QuickPage()
{
timeLeft = new Dispatcher();
timeLeft.Tick += timeLeft_Tick;
timeLeft.Interval = new TimeSpan(0,0,0,1);
}
private void QuestionGenerator()
{
timeLeft.Start();
if (iAsked < 6)
{
//Code to generate random question
}
}

WPF Dispatchertimer is not stopping, nor restarting

I want a DispatcherTimer to restart everytime the conditions are not met. Only when the if-condition is met for 5 seconds, the method can continue.
How should I stop the Dispatchertimer? The timeToWait variable is set to 3000, that works as intended.
Below is the code in C#. It is not responding as I want. It only starts, but never stops or restarts. I am making a WPF application.
dispatcherTimerStart = new DispatcherTimer();
if (average >= centerOfPlayingField - marginOfDetection && average <= centerOfPlayingField + marginOfDetection)
{
dispatcherTimerStart.Interval = TimeSpan.FromMilliseconds(timeToWait);
dispatcherTimerStart.Tick += new EventHandler(tick_TimerStart);
startTime = DateTime.Now;
dispatcherTimerStart.Start();
} else
{
dispatcherTimerStart.Stop();
dispatcherTimerStart.Interval = TimeSpan.FromMilliseconds(timeToWait);
}
private void tick_TimerStart(object sender, EventArgs args)
{
DispatcherTimer thisTimer = (DispatcherTimer) sender;
thisTimer.Stop();
}
you need to preserve the dispatcherTimer that enter your if block because in your else block you are stopping the new instance of DispatcherTimer not the one that entered the if block.
take a class level field
DispatcherTimer preservedDispatcherTimer=null;
var dispatcherTimerStart = new DispatcherTimer();
if (average >= centerOfPlayingField - marginOfDetection && average <= centerOfPlayingField + marginOfDetection)
{
**preservedDispatcherTimer = dispatcherTimerStart;**
dispatcherTimerStart.Interval = TimeSpan.FromMilliseconds(timeToWait);
dispatcherTimerStart.Tick += new EventHandler(tick_TimerStart);
startTime = DateTime.Now;
dispatcherTimerStart.Start();
}
//use preservedDispatcherTimer in else
else if(preservedDispatcherTimer!=null)
{
preservedDispatcherTimer.Stop();
preservedDispatcherTimer.Interval = TimeSpan.FromMilliseconds(timeToWait);
}

Dynamically changing background color

In my Windows Phone 7 app, I want ContentPanel's background to change its color within a specified time (3 seconds in this case). Basically I want it to be "flashing".
But the problem is that the changes do not appear while the loop is working, the color changes only once, after the loop is done working. Why?
byte R;
TimeSpan ts = new System.TimeSpan(0, 0, 0, 3);
DateTime dt1 = new DateTime();
DateTime dt2 = new DateTime();
requirement = true;
while (requirement)
{
R = Convert.ToByte(0.5 * 255 * (1 + Math.Sin(DateTime.Now.Millisecond)));
ContentPanel.Background = new SolidColorBrush(Color.FromArgb(255, R, 125, 70));
dt1 = DateTime.Now;
dt2 = DateTime.Now;
dt2.Subtract(dt1);
if (dt2.Subtract(ts).CompareTo(dt1) > 0) requirement = false;
}
Is it even possible?
Looks like your loop is too tight.
Try this instead:
private DispatcherTimer _timer;
private void StartFlash()
{
_timer = new DispatcherTimer();
_timer.Interval = new TimeSpan(0,0,1);
_timer.Tick += (s,e) => ChangeColour;
}
private void StopFlash()
{
_timer = null;
}
private void ChangeColour() {
// Your colour changing logic goes here
ContentPanel.Background = new SolidColorBrush(Color.FromArgb(a,r,g,b));
}
Put that code in a class. Call StartFlash() somewhere. ChangeColour will execute every second.
You are asking for DateTime.Now way too fast so the difference will equate to 0 as DateTime's accuracy does not go as far as nanoseconds (Dates are marked by milliseconds from the unix epoch after all).
You might want to limit the while with more solid logic.
Try using the DispatcherTimer to do in async way.
The UI is not updated during your method execution, moreover if you work in the UI thread.

How to execute the loop for specific time

How can i execute the a particluar loop for specified time
Timeinsecond = 600
int time = 0;
while (Timeinsecond > time)
{
// do something here
}
How can i set the time varaible here, if i can use the Timer object start and stop method it doesnot return me time in seconds
Regards
NewDev
May be the following will help:
Stopwatch s = new Stopwatch();
s.Start();
while (s.Elapsed < TimeSpan.FromSeconds(600))
{
//
}
s.Stop();
If you want ease of use:
If you don't have strong accuracy requirements (true millisecond level accuracy - such as writing a high frames per second video game, or similar real-time simulation), then you can simply use the System.DateTime structure:
// Could use DateTime.Now, but we don't care about time zones - just elapsed time
// Also, UtcNow has slightly better performance
var startTime = DateTime.UtcNow;
while(DateTime.UtcNow - startTime < TimeSpan.FromMinutes(10))
{
// Execute your loop here...
}
Change TimeSpan.FromMinutes to be whatever period of time you require, seconds, minutes, etc.
In the case of calling something like a web service, displaying something to the user for a short amount of time, or checking files on disk, I'd use this exclusively.
If you want higher accuracy:
look to the Stopwatch class, and check the Elapsed member. It is slightly harder to use, because you have to start it, and it has some bugs which will cause it to sometimes go negative, but it is useful if you need true millisecond-level accuracy.
To use it:
var stopwatch = new Stopwatch();
stopwatch.Start();
while(stopwatch.Elapsed < TimeSpan.FromSeconds(5))
{
// Execute your loop here...
}
Create a function for starting, stopping, and elapsed time as follows:
Class CustomTimer
{
private DateTime startTime;
private DateTime stopTime;
private bool running = false;
public void Start()
{
this.startTime = DateTime.Now;
this.running = true;
}
public void Stop()
{
this.stopTime = DateTime.Now;
this.running = false;
}
//this will return time elapsed in seconds
public double GetElapsedTimeSecs()
{
TimeSpan interval;
if (running)
interval = DateTime.Now - startTime;
else
interval = stopTime - startTime;
return interval.TotalSeconds;
}
}
Now within your foreach loop do the following:
CustomTimer ct = new CustomTimer();
ct.Start();
// put your code here
ct.Stop();
//timeinsecond variable will be set to time seconds for your execution.
double timeinseconds=ct.GetElapsedTime();
use Timers in c#
http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx
It's ugly .... but you could try this:
DateTime currentTime = DateTime.Now;
DateTime future = currentTime.AddSeconds(5);
while (future > currentTime)
{
// Do something here ....
currentTime = DateTime.Now;
// future = currentTime.AddSeconds(5);
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Accord.Video.FFMPEG;
namespace TimerScratchPad
{
public partial class Form1 : Form
{
VideoFileWriter writer = new VideoFileWriter();
int second = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
writer.VideoCodec = VideoCodec.H264;
writer.Width = Screen.PrimaryScreen.Bounds.Width;
writer.Height = Screen.PrimaryScreen.Bounds.Height;
writer.BitRate = 1000000;
writer.Open("D:/DemoVideo.mp4");
RecordTimer.Interval = 40;
RecordTimer.Start();
}
private void RecordTimer_Tick(object sender, EventArgs e)
{
Rectangle bounds = Screen.GetBounds(Point.Empty);
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
writer.WriteVideoFrame(bitmap);
}
textBox1.Text = RecordTimer.ToString();
second ++;
if(second > 1500)
{
RecordTimer.Stop();
RecordTimer.Dispose();
writer.Close();
writer.Dispose();
}
}
}
}
Instead of such an expensive operation I'd recommend this: It's nasty but it's better to sit than running for doing nothing heating the cpu unnecesarily, the question is may be academic.
using System.Threading;
Thread.Sleep(600000);

Categories