Why is time not incrementing - c#

I am trying to show the timestamp of when a process begins and when it completes, but my time never increments (even though time in reality does)
DateTime now = DateTime.Now;
txt1.AppendText(now + Environment.NewLine);
//Lengthy process that usually takes 2 - 3 minutes
txt1.AppendText(now);

You are literally using the same variable with the same value as when you first displayed it. You would need to get the time again like this...
DateTime now = DateTime.Now;
txt1.AppendText(now + Environment.NewLine);
//Lengthy process that usually takes 2 - 3 minutes
DateTime timeHasPassed = DateTime.Now;
txt1.AppendText(timeHasPassed);

DateTime is a ValueType. When you assign it to a variable, you are making a copy of the value, not the reference.
This means that when you use DateTime.Now, you have to invoke it via the Get Property to get the latest time value.
txt1.AppendText(DateTime.Now + Environment.NewLine);
//Lengthy process that usually takes 2 - 3 minutes
txt1.AppendText(DateTime.Now);

That's because you captured and stored the DateTime.Now in a variable so it shows the stored value. Use DateTime.Now again instead of using now variable.

Don't use DateTime to measure your process time of your code.
You should never do any increment or math with DateTime.Now because it may be ambiguous due to DST and TimeZone issues.
Use StopWatch to measure elapsed time instead. This class offers high-precision timing in .NET. It is capable of measuring time with sensitivity of around 100s of nanoseconds.
You can use it's Start and Stop methods to control of a StopWatch object.

Related

C# - most efficient way of measuring ellapsed time

I am working on a C# console application in which I need to know the ellapsed time since the program has started.
I have a variable that stores the time on start (DateTime now = DateTime.Now;)
What is the most efficient way of measuring the ellapsed time?
The ellapsed time can be hours - this is why I am concerned about efficiency and memory usage.
Thanks in advance!
Subtract the current time from the time the program started. This will return a TimeSpan which exposes properties like TotalHours which you can use to calculate the elapsed time.
// on start
var startTime = DateTime.UtcNow;
// later on, to see hours elapsed since then
var elapsed = (DateTime.UtcNow - startTime).TotalHours;
Don't worry. Measuring a time span does not use any resources, as it just compares now with then.
DateTime start = DateTime.Now;
// do some heavy calculation
TimeSpan delta = DateTime.Now - start; // get the time that elapsed
This does not use any resources except the variable for the start, which is just a 64 bit counter.
Note that for short timespans you're better off using Stopwatch, as this is not subject to time adjustments that may happen between start and now.

datetime checking for specific time

I have a windows service and I would like to insert a timer. How can I check if the present time is 9:00 AM ?
I would like my service to check this every day. Thank you a lot
My try:
Datetime dt=Datetime.parse("09:00:00 everyday");
if(datetime.now -dt ==0)
{
//fire event
}
Thats kinda sily of me though.
You need to make a timer and sets its interval to the timespan between now and tomorrow 9:00 AM. Next time the timer tick, set the interval again in the same way.
You should use this Timer class:
http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Please use DateTime.UtcNow.Hour to check current hour
By using UtcNow you will gets a DateTime object that is set to the current date and time on the computer, expressed as the Coordinated Universal Time (UTC).
var now = DateTime.Now;
var today = now.Date;
var nineAm = today.AddHours(9);
TimeSpan ts = nineAm - now;
var timeInMillisecondsTill9Am = ts.Milliseconds;
If(timeInMillisecondsTill9Am==0)
{
//your code goes here
}
Since you don't know when someone may shutdown or reboot your computer or service then you need to make sure that you use a method robust enough to handle these kinds of interruptions.
I suggest that when your service checks every 5 minutes or so if the time is after 9am and if the last run date is yesterday. If so, you update the last run date to day (perhaps in a simple text file) and then run the "9:00am" task. In this way your task only runs once per day, fairly close to 9am, and is robust against reboots.
You'll need to use a standard .NET timer to trigger the checks - and if you're clever enough you can make it fire a few seconds after 9am.
Let me know if that's a good solution.

inaccurate .NET timer?

I'm developing an application and I need to get the current date from a server (it differs from the machine's date).
I receive the date from the server and with a simple Split I create a new DateTime:
globalVars.fec = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, int.Parse(infoHour[0]), int.Parse(infoHour[1]), int.Parse(infoHour[2]));
globalVars is a class and fec is a public static variable so that I can access it anywhere in the application (bad coding I know...).
Now I need to have a timer checking if that date is equal to some dates I have stored in a List and if it is equal I just call a function.
List<DateTime> fechas = new List<DateTime>();
Before having to obtain the date from a server I was using computer's date, so to check if the dates matched I was using this:
private void timerDatesMatch_Tick(object sender, EventArgs e)
{
DateTime tick = DateTime.Now;
foreach (DateTime dt in fechas)
{
if (dt == tick)
{
//blahblah
}
}
}
Now I have the date from the server so DateTime.Now can't be used here. Instead I have created a new timer with Interval=1000 and on tick I'm adding 1 second to globalVars.fec using:
globalVars.fec = globalVars.fec.AddSeconds(1);
But the clock isn't accurate and every 30 mins the clock loses about 30 seconds.
Is there another way of doing what I'm trying to do? I've thought about using threading.timer instead but I need to have access to other threads and non-static functions.
Store the difference between the server's time and local time. Calculate the servers' time when you need it using that difference.
If you create atimer with an interval of 1000ms, it will be called no sooner than 1000ms. So you can pretty much guarantee that it will be called in more than 1000ms, which means you will "lose" time by adding 1s on this timer tick - This will accumulate error with every tick. A better approach is to record a start time and use the current time to determine the current offset from that known start time, so that you don't accumulate any error in your time keeping. (There will still be some error, but you will not drift out of touch with real-time over time)
Different timers (Forms.Timer, Thread.Timer etc) will give different accuracies as well - Forms.Timer is particularly poor for accuracy.
You could also use a high performance time to keep track of the time better - see here, for example.
Here is a reliable 1 μs Timer
See https://stackoverflow.com/questions/15725711/obtaining-microsecond-precision-using-net-without-platform-invoke?noredirect=1#comment22341931_15725711
I guarantee its faster and more accurate then StopWatch and PerformanceCounters and uses the fractions of a second you have in the time slice wisely!

What variable should I use if I want to save time values?

I want to make an app that adds 1 minutes and 25 seconds to a TimeLeft variable.
Problem is I have no idea what type of variable this should be, or even how to add 1 minutes 25 seconds to the available time left.
Any guidance would be much appreciated. I'm good with C#, but since I've never done something like, I'm in the dark.
I would suggest you use a DateTime variable. This will let you manipulate the time. If you want to add 1m 25s to a varible, you could simply use:
DateTime newTime = DateTime.Now.AddSeconds(85);
That will add 85 seconds onto the current time (or, in your case, TimeLeft as long as the TimeLeft variable is also a DateTime type)
TimeSpan works well. It's specifically designed to hold a duration of time.
Use the DateTime type. Assuming your TimeLeft variable is an integer, you probably need to convert it to DateTime type first and then perform the add. More information here

How to determine time interval during DST transition in C#

I want to compute the time 4 hours later during the DST transition, either into DST or out of it.
Currently doing this:
DateTime now = DateTime.now();
DateTime later = now.AddHours(4);
System.Console.WriteLine(now + " isDST " + now.IsDaylightSavingTime());
System.Console.WriteLine(later + " isDST " + later.IsDaylightSavingTime());
Provides:
11/1/2009 12:45:54 AM isDST True
11/1/2009 4:45:54 AM isDST False
What I want to see is:
11/1/2009 12:45:54 AM isDST True
11/1/2009 3:45:54 AM isDST False
The "best" way I've found to do this is to take a round trip through UTC like this:
DateTime now = DateTime.now();
DateTime later = now.ToUniversalTime().AddHours(4).ToLocalTime;
System.Console.WriteLine(now + " isDST " + now.IsDaylightSavingTime());
System.Console.WriteLine(later + " isDST " + later.IsDaylightSavingTime());
It seems I should be able to specify to AddHours() that the time returned should be elapsed time or display time. What am I missing?
I don't think you're missing anything. It sounds like DateTime could have a better documented or richer interface, but MSDN recommends using UTC exactly like you are.
There's a cute time difference between .NET and win32 in displaying times from a different daylight savings' rule than the present. .NET will display the time as it would have been displayed at that time, while win32 will always give it in terms of the current daylight savings flag.
AddHours() deals with TimeSpans, which have no real concept of "display hours" or even timezones. It's essentially a whole number of ticks.
I think what you're doing is a pretty good way of handling it, if I understand your intent correctly.
Yes, you should use UTC.
You're effectively talking about an instant in time 4 hours after the current instant. Not 4 hours of a particular local time, but 4 hours in "experienced" time, if you will. (Let's leave relativity out of it.) Imagine one person calls another and says, "I'll call you again in 4 hours" - both will know what that means, even if they're in completely different time zones with different DST transitions involved.
Instants are usually best expressed in UTC to avoid confusion - they're inherently "universal" rather than being in a particular time zone.
I'd avoid using local time until you need it:
DateTime localTimeInFourHours = DateTime.UtcNow.AddHours(4).ToLocalTime;
Or you could use DateTimeOffset if you want to end up with a "local time" in a time zone other than the one your computer is set to.

Categories

Resources