String format error - c#

I've coded a uptime to my application and it's just displaying random numbers?
the program time is this code
public static DateTime TimeStarted { get; set; }
public static void Time(string[] args)
{
//set start time
Program.TimeStarted = DateTime.Now;
}
and then this is a class to display the uptime
case "uptime":
{
TimeSpan sinceStarted = (TimeSpan)(DateTime.Now - Program.TimeStarted);
double secondsRunning = sinceStarted.TotalSeconds;
string message = string.Format("{0} Days, {1} hours, and {2} minutes", sinceStarted.Days, sinceStarted.Hours, sinceStarted.Minutes);
Session.SendData(UserAlertModernComposer.Compose("Stats", message));
return true;
}
its currently saying 735096 days 7 hours and 34 minutes when the uptime is around 20 minutes,

There is no need to keep yourself this value. It is already available in the Process.StartTime property. You only need to get an handle to the current process
Process p = Process.GetCurrentProcess();
TimeSpan sinceStarted = (TimeSpan)(DateTime.Now - p.StartTime);
string message = string.Format("{0} Days, {1} hours, and {2} minutes",
sinceStarted.Days, sinceStarted.Hours, sinceStarted.Minutes);

Consider using the Stopwatch class for your purposes. Its in the System.Diagnostics namespace and should be better suited for you.
using System;
using System.Diagnostics;
using System.Threading;
class Program
{
static void Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Thread.Sleep(10000);
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);
}
}

As mentioned in my comment you are never calling your Time method. Which means TimeStarted will have the DateTime.MinValue. DateTime.MinValue is equivalent to 01/01/0001 00:00:00. Hence the result you are getting.
What you need to do is to write the following line in program.cs
Program.TimeStarted = DateTime.Now;
Rest is fine

Related

Method execution time not showing

Im trying to measure method execution time, but it didn't show the execution time. Can anyone help me to solve the problem?
public static int SequentialSearch(int[] point, int findPoint)
{
DateTime start = DateTime.Now;
int i;
for (i = 0; i < point.Length; i++)
{
if (findPoint== point[i])
{
return i;
}
}
DateTime end = DateTime.Now;
TimeSpan ts = (end - start);
Console.WriteLine("Elapsed Time is {0} ms", ts.TotalMilliseconds);
return -1;
}
There is actually a better way to do this, use StopWatch
//You need this using statement
using System.Diagnostics;
//Set it up, and then start it.
var timer = new Stopwatch();
timer.Start();
//Run your code
MethodToTime();
//Now stop the timer
timer.Stop();
//You can output either directly the elapsed MS
Console.WriteLine($"RunTime {timer.ElapsedMilliseconds}ms");
//Or you can get the elasped time span and output
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);

Running Timers in the Background c# Console

Wondering if there's a way to have a timer running in the background of a project that can be accessed if the user inputs a certain thing. At the moment this doesn't work
Timer t = new Timer(Program.TimerCallback, null, 0, 1000);
if (Console.ReadLine() == "i")
{
TimeSpan time = TimeSpan.FromSeconds(Program.seconds);
string str = time.ToString(#"mm\:ss");
Console.WriteLine("Time :" + str);
}
public static void TimerCallback(object o)
{
seconds +=1;
}
I used to have to code above within the Callback but then I couldn't do anything while it was running the timer. Thanks for any help
If I understand correctly, you don't actually need a timer:
DateTime startTime = DateTime.Now; // Just have a reference time
if (Console.ReadLine() == "i")
{
TimeSpan time = DateTime.Now - startTime; // Compute difference between "now" and "then"
string str = time.ToString(#"mm\:ss");
Console.WriteLine("Time :" + str);
}
should do the trick.
Subtracting two DateTimes like this gives you a TimeSpan: DateTime.Subtraction Operator
If you need better precision, you can make use of the StopWatch class, which also has a little more convenient API:
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
if (Console.ReadLine() == "i")
{
TimeSpan time = stopWatch.Elapsed;
string str = time.ToString(#"mm\:ss");
Console.WriteLine("Time :" + str);
}
BUT do not think you can do (micro-)benchmarks with this. If you intend to do so, consider Benchmark.NET (not affiliated).

Sorting System.Diagnostics.Stopwatch from a text file into a top 10

The format is:
ElapsedTime(min, seconds, milliseconds) CurrentDate(day, month, year) DateTime(hours, minutes, seconds)
00:00:00 23/08/2020 12:24:37
00:00:00 23/08/2020 12:25:13
00:00:00 23/08/2020 12:25:18
I had a look at the Array.Sort methods, but not sure how to implement it. My idea is, sort them by ElapsedTime, less time goes first, and then display what date and what time they were recorded at. How can I sort this into an array?
FWIW, this is how I write to the text file, and also how I get and sort the time.
// Content of file
string content = timer.ts.ToString() + " " + System.DateTime.Now + "\n";
// Add text to file
File.AppendAllText(path, content);
timer is a reference to the Timer class, ts is stopwatch.Elapsed()
ts = stopwatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}.{2:00}",
ts.Minutes, ts.Seconds, ts.Milliseconds / 10);
Note : Below is the concept that you can take reference from. This is not a running code
class Program
{
static void Main(string[] args)
{
Stopwatch st = Stopwatch.StartNew();
LogPerformance lf = new LogPerformance { TotalTicks = st.ElapsedTicks, LoggingText = "format of your lgging string" };
List<LogPerformance> performanceList = new List<LogPerformance>() {lf,.... };
LogPerformanceComparer comparer = new LogPerformanceComparer();
performanceList.Sort(comparer);
performanceList.ForEach(x => logger.Log(x.LoggingText));
}
public class LogPerformance
{
public long TotalTicks { get; set; }
public string LoggingText { get; set; }
}
public class LogPerformanceComparer : IComparer<LogPerformance>
{
public int Compare([NotNull] LogPerformance x, [NotNull] LogPerformance y)
{
return x.TotalTicks.CompareTo(y.TotalTicks);
}
}
}

TimeSpan and DispatchTimer

I'm using a class to modify a DateTime and using a TimeSpan to display X hours, Y minutes, Z seconds to a WPF label every second with a DispatchTimer. The code itself gives the proper timespan, however the DispatchTimer is giving the wrong output. Can I get some input on what is going on here?
The ModifiedTime Minutes properties is still being queried during debug breaks (hovering over ModifiedTime.Minutes keeps giving an increasing number.), is this the norm?
Runtime output starts at 3 minutes, then displays 8 minutes, 13, 18, 23, 28, etc.
Library:
public Clock() {
load_ = DateTime.Now;
time_ = new DateTime();
time_ = DateTime.Now;
modifiedTime_ = new DateTime();
modifiedTime_ = DateTime.Now;
difference = TimeSpan.Zero;
}
public TimeSpan ModifiedTime {
//Convert the real time to timespan.
//display X Years, Y Days, Z Hours...
get {
modifiedTime_ = modifiedTime_.AddMinutes(1.0);
difference = modifiedTime_.Subtract(time_);
return difference;
}
set { difference = value; }
}
WPF:
DispatcherTimer dispatcherTimer;
public MainWindow() {
InitializeComponent();
dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e) {
lblModTime.Content = clock.ModifiedTime.Hours + " hours, " + clock.ModifiedTime.Minutes + " minutes, " + clock.ModifiedTime.Seconds + " seconds, " + clock.ModifiedTime.Milliseconds + " milliseconds.";
}
Right, every time you call clock.ModifiedTime. in your dispatcher (4 times!) you add a minute to the modified time, plus possibly once more for evaluating the statement in the debugger. That would explain your incrementing your display by 5 each time.
If I understand correctly, you want to add one minute to the time started for every second that passed. So take the difference in seconds, then add that as minutes to time started for your new time.
public TimeSpan ModifiedTime
{
get
{
TimeSpan elapsed = DateTime.Now - TimeStarted;
return TimeStarted.AddMinutes(elapsed.TotalSeconds);
}
}

Time elapse computation in milliseconds C#

I need to time the execution of a code sequence written in C#. Using DateTime.Now I get incorrect values for the millisecond field.
For example:
int start_time, elapsed_time;
start_time = DateTime.Now.Millisecond;
for(int i = 0; i < N_ITER; i++) {
// cpu intensive sequence
}
elapsed_time = DateTime.Now.Millisecond - start_time;
elapsed_time gives negative values.
How may I replace DateTime in order to obtain the actual value of the elapsed time?
using System.Diagnostics;
//...
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < N_ITER; i++) {
// cpu intensive sequence
}
stopwatch.Stop();
elapsed_time = stopwatch.ElapsedMilliseconds;
Answer EDITED based on comments
This answer is only trying to count the total elapsed Milliseconds between two times, where the times are derived directly from DateTime.Now. As per the conversation, it's understood that DateTime.Now is vulnerable to outside influences. Hence the best solution would be to use the Stopwatch class. Here's a link that better explains (IMO) and discusses the performance between DateTimeNow, DateTime.Ticks, StopWatch.
Original Answer
The way you cast it into a int is the issue. You need better casting and extra elements :)
This may looks simple compared to an efficient timer. But it works:
DateTime startTime, endTime;
startTime = DateTime.Now;
//do your work
endTime = DateTime.Now;
Double elapsedMillisecs = ((TimeSpan)(endTime - startTime)).TotalMilliseconds;
There is a reference on the web, you may want to check out as well.
You're looking for the Stopwatch class. It is specifically designed to bring back high-accuracy time measurements.
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < N_ITER; i++)
{
// cpu intensive sequence
}
stopwatch.Stop();
var elapsed = stopwatch.ElapsedMilliseconds;
Stopwatch there are examples in the URL
https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=netframework-4.8
using System.Diagnostics;
//...
Stopwatch watch = new Stopwatch();
watch.Start();
// here the complex program.
//...
watch.Stop();
TimeSpan timeSpan = watch.Elapsed;
Console.WriteLine("Time: {0}h {1}m {2}s {3}ms", timeSpan.Hours, timeSpan.Minutes,
timeSpan.Seconds, timeSpan.Milliseconds);
DateTime.Millisecond just returns the millisecond fraction of the second, from 0-999. You would need to take the rest of the datetime into consideration when doing timings.
However, you should look at using the StopWatch class for these kinds of performance timings.
This works for me:
var lapsedTime = DateTime.Now.Subtract(beginTime).TotalMilliseconds;
Here is what I used to obtain the time for a simple computation:
class Program
{
static void Main(string[] args)
{
Decimal p = 0.00001m;
Decimal i = 0m;
DateTime start = new DateTime();
DateTime stop = new DateTime();
for (i = p; i <= 5; i = i + p)
{
Console.WriteLine("result is: " + i);
if (i==p) start = DateTime.Now;
if (i==5) stop = DateTime.Now;
}
Console.WriteLine("Time to compute: " + (stop-start));
}
}

Categories

Resources