I Have This in C#
private void counter_Tick(object sender, EventArgs e)
{
Time.Text = String.Format("{0:000}", Hour) + ":" + String.Format("{0:00}", Minute) + ":" + String.Format("{0:00}", Second);
if (Second != 00)
{
Second = Second - 1;
}
else if (Minute != 00)
{
Minute = Minute - 1;
Second = 59;
}
else if (Hour != 00)
{
Hour = Hour - 1;
Minute = 59;
}
else
{
counter.Stop();
Time.ForeColor = Color.Red;
}
}
Which Does work but when it gets to minus an hour to add to minutes, it goes from 00 minutes to 58 minutes instead of 59
EG.
From: 001:00:00
To: 000:58:59
And is there a better way to make a countdown timer that does something when it hits 000:00:00???
Well let's see what happens when the time is 10:00:00.
Subtract one hour: 09:00:00.
Set minutes to 59: 09:59:00.
If you notice the time is off by one minute (10:00:00 - 09:59:00 = 00:01:00). The solution is to set the seconds to 59 also. So now our code is.
// ...
else if (Hour != 00)
{
Hour = Hour - 1;
Minute = 59;
Second = 59;
}
// ...
You can use standard .Net classes for subtracting time:
private TimeSpan timeSpan;
private TimeSpan oneSecond = new TimeSpan(0, 0, 1);
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Time.Text = timeSpan.ToString();
if (timeSpan == TimeSpan.Zero)
{
Time.ForeColor = Color.Red;
timer.Stop();
return;
}
timeSpan -= oneSecond;
}
Initialize timespan when you starting your timer (I used System.Timers.Timer):
timeSpan = new TimeSpan(1, 0, 0);
Timer timer = new Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
You also need to set Second to 59. Else, once the timer ticks again, it immediately switches to else if (Minute != 00) and decrements Minute (which is already 59) by one.
DateTime start;
DateTime final;
private void start()
{
start = DateTime.Now;
final = start + TimeSpan.FromHours(1);
}
private void counter_Tick(object sender, EventArgs e)
{
start = DateTime.Now;
Time.Text = (final-start).Hours.ToString() + ":" + (final-start).Minutes.ToString() + ":" + (final-start).Seconds.ToString();
if (final == start)
{
//final code
}
}
Related
I want to get the timespan in milliseconds by comparing two timestamps with DateTime.Now and the previous DateTime. I want to check if there is an event every 10 Milliseconds or later but the totalmilliseconds from DeltaT is like 188 or so. It is too high than I am expecting that is why I think there must be somethimg wrong. Or does everything look alright?
DateTime timestamp;
DateTime timestampAlt;
TimeSpan deltaT;
public void OnSensorChanged(SensorEvent e)
{
timestamp = System.DateTime.Now;
deltaT = timestamp - timestampAlt;
if (deltaT.TotalSeconds <= 0.01)
{
return;
}
UPDATE:
I really appreciate all of you answers but I think there is a misunderstanding (my mistake sry). So here again:
Whenever the listener recognizes an event, I want to save the timestamp and compare with the timespamp of the event before. If there is a gap of more than 10 Milliseconds between the 2 events, then I do want to know more about this new event. If not, I dont even want to continue and will leave by a return.
public void OnSensorChanged(SensorEvent e)
{
timestamp = System.DateTime.Now;
deltaT = timestamp - timestampAlt;
//int deltaT2 = timestamp.Millisecond - timestampAlt.Millisecond;
String timestampStr = timestamp.ToString("ff");
String timestampStrA = timestampAlt.ToString("ff");
if (deltaT.TotalMilliseconds <= 10 || deltaT.TotalMilliseconds <= -10) //deltaT.Seconds <= 0.01
{
return;
}
timestampAlt = timestamp;
newValue = e.Values[2];
//if (buffer[99] != 0.00)
// if last element of list is empty, add elements to buffer
if (buffer.Count <=99)
{
buffer.Add(newValue);
zeitbuffer.Add(timestamp);
}
else
{
Ableitung(DeltaBuffer(), DeltaTime()); // if last index of list is filled, do that function
}
if (e.Values[2] >= 11)
{
try
{
lock (_syncLock)
{
String z2 = newValue.ToString("0.0");
//noteInt2 = Convert.ToInt32(newValue);
try
{
_sensorTextView2.Text = string.Format("Note: {0}", z2 );
eventcounter.Add(z2);
You can use deltaT.TotalMilliseconds which expresses your delta in milliseconds. Therefore your check could be rewritten as
if (deltaT.TotalMilliseconds <= 10)
{
return;
}
10 is a value I inferred. It might not be what you need, but your question is partial. This answer addresses your particular question, however if you need to measure the duration of a task you should use the Stopwatch class, which is designed for that purpose.
if you want to fire an event every n-Seconds you can use a timer that fires an event when he elapses:
Timer timer = new Timer();
timer.Interval = 100;
timer.Elapsed += YourAmasingEvent;
timer.Start();
private void YourAmasingEvent(object sender, ElapsedEventArgs e)
{
//do something here
(sender as Timer).Start();
}
Using your code:
I guess you want to wait until the time elapsed in this case you would have to use a loop like this:
timestamp = System.DateTime.Now;
deltaT = timestamp - timestampAlt;
while(true)
{
if (deltaT.TotalSeconds <= 0.01)
{
return;
}
timestamp = System.DateTime.Now;
deltaT = timestamp - timestampAlt;
}
Well, this question is related to this one, so you guys can understand it better
How to convert the "time" from DateTime into int?
My Answer to it:
txtAtiv.Text = dataGridView1.Rows[0].Cells[1].Value + "";
string value = dataGridView1.Rows[0].Cells[2].Value + "";
lblLeft.Text = value.Split(' ')[1];
textStatus.Text = "";
DateTime timeConvert;
DateTime.TryParse(value, out timeConvert);
double time;
time = timeConvert.TimeOfDay.TotalMilliseconds;
var timeSpan = TimeSpan.FromMilliseconds(time);
lblSoma.Text = timeSpan.ToString();
timer2.Start();
According to the answer I wrote right there, I want to know if there's a way I can apply it to a timer and do the DataGrid values (converted) turn into a timer value. So if I press a button they start the countdown.
I have tried to insert this code inside the timer:
private void timer2_Tick(object sender, EventArgs e)
{
string timeOp = dataGridView1.Rows[0].Cells[2].Value + "";
DateTime timeConvert;
DateTime dateTime = DateTime.Now;
DateTime.TryParse(timeOp, out timeConvert);
double time;
time = timeConvert.TimeOfDay.TotalMilliseconds;
var timeSpan = TimeSpan.FromMilliseconds(time);
if (time > 0)
{
time = time - 1000; //(millisec)
lblCountdown.text = time.ToString();
}
}
didn't count down or anything, does someone has an idea of what should I do or why it isn't working?
The value of time never changes, because you create it again fresh each time.
To solve this, you have to declare the variable you decrement outside of the Tick event.
Put these two variables on your form:
private int milliSecondsLeft = 0;
private bool timeSet = false;
Then change the 'tick' event to this:
private void timer2_Tick(object sender, EventArgs e)
{
if (!timeSet) // only get the value once
{
string dateTimeFromGrid = "4/29/2016 5:00:00 AM"; //hardcoded for simplicity, get the string from your grid
DateTime fromGrid;
DateTime.TryParse(dateTimeFromGrid, out fromGrid);
milliSecondsLeft = (int)fromGrid.TimeOfDay.TotalMilliseconds;
timeSet = true;
}
milliSecondsLeft = milliSecondsLeft - 100; // timer's default Interval is 100 milliseconds
if (milliSecondsLeft > 0)
{
var span = new TimeSpan(0, 0, 0, 0, milliSecondsLeft);
lblCountdown.Text = span.ToString(#"hh\:mm\:ss");
}
else
{
timer2.Stop();
}
}
Make sure
In the top of form1 i have:
private int seconds;
private int minutes;
private int hours;
In the constructor:
seconds = 0;
minutes = 20;
hours = 0;
label9.Visible = false;
label9.Text = "00:00:00";
Then the timer 3 tick event. I used a breakpoint on the timer3 tick event i see that the minutes and seconds are coundting backwards but label 9 is not updating.
Maybe the string.Format on label9 is not right ?
private void timer3_Tick(object sender, EventArgs e)
{
// Verify if the time didn't pass.
if ((minutes == 0) && (hours == 0) && (seconds == 0))
{
// If the time is over, clear all settings and fields.
// Also, show the message, notifying that the time is over.
timer3.Enabled = false;
label9.Visible = true;
label9.Text = "00:00:00";
}
else
{
// Else continue counting.
if (seconds < 1)
{
seconds = 59;
if (minutes == 0)
{
minutes = 59;
if (hours != 0)
hours -= 1;
}
else
{
minutes -= 1;
}
}
else
seconds -= 1;
// Display the current values of hours, minutes and seconds in
// the corresponding fields.
label7.Visible = true;
label9.Visible = true;
label9.Text = string.Format("{00} : {00} : {00}", hours.ToString(), minutes.ToString(),seconds.ToString());
}
}
All i see in the end on label 9 is: 0:0:0 thats it and i dont see 20 minutes counting backward.
You need to fix your string formatting, that's the culprit:
label9.Text = string.Format("{0:00} : {1:00} : {2:00}", hours, minutes, seconds);
Also - consider using some other mechanism (e.g. Stopwatch class) for calculating elapsed time; you can't guarantee that the code as written will execute exactly every 1000 ms.
I am writing a WinForm application to use SNMP calls either every 30 seconds or 1 minute.
I have a timer working for calling my SNMP commands, but I want to add a texbox counter that display the total time elapsed during the operation.
There are many problems I am having so here is a list:
I want my SNMP timer 'timer' to execute once before waiting the allotted time so I have it going off at 3 seconds and then changing the interval in my handler. But this sometimes makes the timer go off multiple times which is not what I want.
Every time 'timer' goes off and my SNMP calls execute my counter timer 'appTimer' becomes out of sync. I tried a work around where I check if it is in the other handler and then just jump the timer to its appropriate time. Which works but I feel this is making it too complicated.
My last issue, that I know of, happens when I stop my application using my stop button which does not completely exit the app. When I go to start another run the time between both timers is becomes even greater and for some reason my counting timer 'appTimer' starts counting twice as fast.
I hope this description isn't too confusing but here is my code anyway:
using System;
using System.Net;
using SnmpSharpNet;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public static bool stop = false;
static bool min = true, eye = false, firstTick = false;
static string ipAdd = "", fileSaveLocation = "";
static System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
static System.Windows.Forms.Timer appTimer = new System.Windows.Forms.Timer();
static int alarmCounter = 1, hours = 0, minutes = 0, seconds = 0, tenthseconds = 0, count = 0;
static bool inSNMP = false;
static TextBox textbox, timeTextbox;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
textbox = outputBox;
timeTextbox = timeBox;
ipAdd = "192.168.98.107";
fileSaveLocation = "c:/Users/bshellnut/Desktop/Eye.txt";
min = true;
inSNMP = false;
}
private void IPtext_TextChanged(object sender, EventArgs e)
{
ipAdd = IPtext.Text;
}
private void stopButton_Click(object sender, EventArgs e)
{
stop = true;
timer.Stop();
appTimer.Stop();
count = 0;
hours = minutes = seconds = tenthseconds = 0;
inSNMP = false;
}
// This is the method to run when the timer is raised.
private static void TimerEventProcessor(Object myObject,
EventArgs myEventArgs)
{
inSNMP = true;
timer.Stop();
if (firstTick == true)
{
// Sets the timer interval to 60 seconds or 1 second.
if (min == true)
{
timer.Interval = 1000 * 60;
}
else
{
timer.Interval = 1000 * 30;
}
}
// Displays a message box asking whether to continue running the timer.
if (stop == false)
{
textbox.Clear();
// Restarts the timer and increments the counter.
alarmCounter += 1;
timer.Enabled = true;
System.IO.StreamWriter file;
//if (eye == true)
//{
file = new System.IO.StreamWriter(fileSaveLocation, true);
/*}
else
{
file = new System.IO.StreamWriter(fileSaveLocation, true);
}*/
// SNMP community name
OctetString community = new OctetString("public");
// Define agent parameters class
AgentParameters param = new AgentParameters(community);
// Set SNMP version to 2 (GET-BULK only works with SNMP ver 2 and 3)
param.Version = SnmpVersion.Ver2;
// Construct the agent address object
// IpAddress class is easy to use here because
// it will try to resolve constructor parameter if it doesn't
// parse to an IP address
IpAddress agent = new IpAddress(ipAdd);
// Construct target
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1);
// Define Oid that is the root of the MIB
// tree you wish to retrieve
Oid rootOid;
if (eye == true)
{
rootOid = new Oid("1.3.6.1.4.1.128.5.2.10.14"); // ifDescr
}
else
{
rootOid = new Oid("1.3.6.1.4.1.128.5.2.10.15");
}
// This Oid represents last Oid returned by
// the SNMP agent
Oid lastOid = (Oid)rootOid.Clone();
// Pdu class used for all requests
Pdu pdu = new Pdu(PduType.GetBulk);
// In this example, set NonRepeaters value to 0
pdu.NonRepeaters = 0;
// MaxRepetitions tells the agent how many Oid/Value pairs to return
// in the response.
pdu.MaxRepetitions = 5;
// Loop through results
while (lastOid != null)
{
// When Pdu class is first constructed, RequestId is set to 0
// and during encoding id will be set to the random value
// for subsequent requests, id will be set to a value that
// needs to be incremented to have unique request ids for each
// packet
if (pdu.RequestId != 0)
{
pdu.RequestId += 1;
}
// Clear Oids from the Pdu class.
pdu.VbList.Clear();
// Initialize request PDU with the last retrieved Oid
pdu.VbList.Add(lastOid);
// Make SNMP request
SnmpV2Packet result;
try
{
result = (SnmpV2Packet)target.Request(pdu, param);
}
catch (SnmpSharpNet.SnmpException)
{
timer.Stop();
textbox.Text = "Could not connect to the IP Provided.";
break;
}
// You should catch exceptions in the Request if using in real application.
// If result is null then agent didn't reply or we couldn't parse the reply.
if (result != null)
{
// ErrorStatus other then 0 is an error returned by
// the Agent - see SnmpConstants for error definitions
if (result.Pdu.ErrorStatus != 0)
{
// agent reported an error with the request
textbox.Text = "Error in SNMP reply. " + "Error " + result.Pdu.ErrorStatus + " index " + result.Pdu.ErrorIndex;
lastOid = null;
break;
}
else
{
// Walk through returned variable bindings
foreach (Vb v in result.Pdu.VbList)
{
// Check that retrieved Oid is "child" of the root OID
if (rootOid.IsRootOf(v.Oid))
{
count++;
textbox.Text += "#" + count + " " + v.Oid.ToString() + " " + SnmpConstants.GetTypeName(v.Value.Type) +
" " + v.Value.ToString() + Environment.NewLine;
file.WriteLine("#" + count + ", " + v.Oid.ToString() + ", " + SnmpConstants.GetTypeName(v.Value.Type) +
", " + v.Value.ToString(), true);
if (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW)
lastOid = null;
else
lastOid = v.Oid;
}
else
{
// we have reached the end of the requested
// MIB tree. Set lastOid to null and exit loop
lastOid = null;
}
}
}
}
else
{
//Console.WriteLine("No response received from SNMP agent.");
textbox.Text = "No response received from SNMP agent.";
//outputBox.Text = "No response received from SNMP agent.";
}
}
target.Close();
file.Close();
}
else
{
// Stops the timer.
//exitFlag = true;
count = 0;
}
}
private static void ApplicationTimerEventProcessor(Object myObject,
EventArgs myEventArgs)
{
tenthseconds += 1;
if (tenthseconds == 10)
{
seconds += 1;
tenthseconds = 0;
}
if (inSNMP && !firstTick)
{
if (min)
{
seconds = 60;
}
else
{
textbox.Text += "IN 30 SECONDS!!!";
if (seconds < 30)
{
seconds = 30;
}
else
{
seconds = 60;
}
}
}
if(seconds == 60)
{
seconds = 0;
minutes += 1;
}
if(minutes == 60)
{
minutes = 0;
hours += 1;
}
timeTextbox.Text = (hours < 10 ? "00" + hours.ToString() : hours.ToString()) + ":" +
(minutes < 10 ? "0" + minutes.ToString() : minutes.ToString()) + ":" +
(seconds < 10 ? "0" + seconds.ToString() : seconds.ToString()) + "." +
(tenthseconds < 10 ? "0" + tenthseconds.ToString() : tenthseconds.ToString());
inSNMP = false;
firstTick = false;
}
private void eyeButton_Click(object sender, EventArgs e)
{
outputBox.Text = "Connecting...";
eye = true;
stop = false;
count = 0;
hours = minutes = seconds = tenthseconds = 0;
timer.Tick += new EventHandler(TimerEventProcessor);
timer.Interval = 3000;
firstTick = true;
appTimer.Tick += new EventHandler(ApplicationTimerEventProcessor);
appTimer.Interval = 100;
appTimer.Start();
timer.Start();
}
private void jitterButton_Click(object sender, EventArgs e)
{
outputBox.Text = "Connecting...";
eye = false;
stop = false;
count = 0;
hours = minutes = seconds = tenthseconds = 0;
timer.Tick += new EventHandler(TimerEventProcessor);
timer.Interval = 3000;
firstTick = true;
appTimer.Tick += new EventHandler(ApplicationTimerEventProcessor);
appTimer.Interval = 100;
appTimer.Start();
timer.Start();
}
private void Seconds_CheckedChanged(object sender, EventArgs e)
{
min = false;
}
private void Minutes_CheckedChanged(object sender, EventArgs e)
{
min = true;
}
private void exitButton_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void savetextBox_TextChanged(object sender, EventArgs e)
{
fileSaveLocation = savetextBox.Text;
}
}
}
This is very easy to do with a single timer. The timer has a 1/10th second resolution (or so) and can be used directly to update the elapsed time. You can then use relative elapsed time within that timer to fire off your SNMP transaction, and you can reschedule the next one dynamically.
Here's a simple example
using System;
using System.Drawing;
using System.Windows.Forms;
class Form1 : Form
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
DateTime lastSnmpTime;
TimeSpan snmpTime = TimeSpan.FromSeconds(30);
DateTime startTime;
TextBox elapsedTimeTextBox;
Timer timer;
public Form1()
{
timer = new Timer { Enabled = false, Interval = 10 };
timer.Tick += new EventHandler(timer_Tick);
elapsedTimeTextBox = new TextBox { Location = new Point(10, 10), ReadOnly = true };
Controls.Add(elapsedTimeTextBox);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
startTime = DateTime.Now;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
// Update elapsed time
elapsedTimeTextBox.Text = (DateTime.Now - startTime).ToString("g");
// Send SNMP
if (DateTime.Now - lastSnmpTime >= snmpTime)
{
lastSnmpTime = DateTime.Now;
// Do SNMP
// Adjust snmpTime as needed
}
}
}
Updated Q&A
With this code the timer fires once at the beginning where after I
press the stop button and call timer.Stop() and then press my start
button the timer doesn't fire until roughly 12 seconds later. Will
resetting the DateTimes fix this?
When the user presses the Start button, set lastSnmpTime = DateTime.MinValue. This causes the TimeSpan of (DateTime.Now - lastSnmpTime) to be over 2,000 years, so it will be greater than snmpTime and will fire immediately.
Also my output time in the text box looks like this: 0:00:02.620262.
Why is that? Is there a way to make it display only 0:00:02.62?
When you subtract two DateTime values, the result is a TimeSpan value. I used a standard TimeSpan formatting string of "g". You can use a custom TimeSpan formatting string of #"d\:hh\:mm\:ss\.ff" to get days:hours:minutes:seconds.fraction (2 decimal places).
Also will the timer go on and print out to the text box when it is run
for over 9 hours? Because I plan to have this running for 24 hrs+
If you use the custom format with 'd' to show the number of days, it will run for TimeSpan.MaxValue which is slightly more than 10,675,199 days, which is more than 29,000 years.
i have a windows service set to run at certain times, it runs first time but i cant seem to work out how to tell it to run the next day when it gets to end of times..
this is what i am trying...
protected override void OnStart(string[] args)
{
log.Info("Info - Service Start");
string timeToRunStr = "17:11";
var timeStrArray = timeToRunStr.Split(';');
foreach (var strTime in timeStrArray)
{
timeToRun.Add(TimeSpan.Parse(strTime));
}
ResetTimer();
}
void ResetTimer()
{
log.Info("Info - Reset Timer");
try
{
TimeSpan currentTime = DateTime.Now.TimeOfDay;
TimeSpan nextRunTime = timeToRun[0];
foreach (TimeSpan runTime in timeToRun)
{
if (currentTime < runTime)
{
nextRunTime = runTime;
// log.Info("Info - in loop");
break;
}
else {
TimeSpan test = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 16, 51, 0).Subtract(DateTime.Now);
nextRunTime = test;
}
}
_timer = new Timer((nextRunTime - currentTime).TotalSeconds * 1000);
log.Info("Info - Timer : " + (nextRunTime - currentTime).TotalSeconds * 1000);
log.Info("Info - nextRuntime : " + nextRunTime);
log.Info("Info - currentTime : " + currentTime);
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Start();
}
catch (Exception ex)
{
log.Error("This is my timer error - ", ex);
}
}
check out these alternatives: :
DateTime of next 3am occurrence
Control activities with a timer, see model:
class Program
{
static void my_task(Object obj)
{
Console.WriteLine("task being performed.");
}
static TimerCallback timerDelegate;
static Timer timer;
static void Main(string[] args)
{
DateTime now = DateTime.Now;
DateTime today = now.Date.AddHours(12);
DateTime next = now <= today ? today : today.AddDays(1);
timerDelegate = new TimerCallback(my_task);
// hence the first after the next
timer = new Timer(timerDelegate, null, next - DateTime.Now, TimeSpan.FromHours(24));
}
}