Making a countdown to multiple times of day - c#

Current code:
while (true)
{
// Gets current time
DateTime farD = DateTime.Now;
//Gets the departure time
DateTime s = DateTime.Now;
TimeSpan ts = new TimeSpan(15, 30, 0);
s = s.Date + ts;
// Countdown to departure.
TimeSpan apa = s-farD;
//Writes time left and clears console. With a 1 second interval.
Console.Clear();
Console.WriteLine("{0}:{1}:{2} Till färjan går",apa.Hours,apa.Minutes,apa.Seconds);
Thread.Sleep(1000);
}
}
}
}
What I am aiming towards, is to do a countdown a specific times each day, when the ferry leaves.
Problem is that the ferry have 50+~ departure times each day, And with this solution for a countdown gets very messy.
So questions:
Is there a quicker way to make a countdown that is not dependent on what date of the month/year it is?
(Diffrent ferry times will later be controlled with DateTime.DayOfWeek)
Ill post a link with the ferry times so you can see how the times differ per time of day and weekday:
Ferry departure times
I know Ive not come close to a final solution, but I rather want to start with the right calculation for making a countdown to a time, that is independent of what day, month or year it is.

As BugFinder said, this is not stack overflow question, but i can give you a tip:
Create a List AllDepartures where you can store all departures time.
And use it:
List<DateTime> DayDepartures = AllDepartures.FindAll (
o => o.DayOfWeek == DateTime.Now.DayOfWeek
);
This is how you can get all the departures on today.
And like this you can get the departures that are after now, sorted by hour:
List<DateTime> NextHourDepartures = DayDepartures.FindAll (
o => o.Hour >= DateTime.Now.Hour
).OrderBy(o => o.Hour).ToList();
And you can get the next departures on current hour, sorted by time like this:
List<DateTime> NextMinuteDepartures = NextHourDepartures.FindAll(
o => o == NextHourDepartures[0]
).FindAll (
o => o.Minute >= DateTime.Now.Minute
).OrderBy(o=>o.Minute).ToList();
and then you next departure time is:
DateTime nextDeparture = NextMinuteDepartures [0];
Hope this helps, but next time try to represent your problem better.

Related

Problem with time intervals with given start time and end time c#

I am trying to develop a simple app for my upskill for c#, however I am stuck and new to the functionality of time with c#,
what I need:
I have a 3 text boxes that will contain start time, end time and time interval.
say user entered 7:00 AM , 12:00 PM , and 60 minutes it will store it inside a datatable and add it inside a listbox.
7:00 AM
8:00 AM
9:00 AM
10:00 AM
11:00 AM
12:00 AM
current approach:
I think I need to use the DateTime.AddMinutes(interval) but how am I going to arrive to the logic of it will stop if it reaches the end time? using the DateTime method? I am really confused on what to use, I saw TimeRange, TimeSpan etc.
You can use TimeSpan and DateTime together (to calculate and print respectively)
TimeSpan start = DateTime.Parse("7:00 AM").TimeOfDay;
TimeSpan end = DateTime.Parse("12:00 PM").TimeOfDay;
TimeSpan interval = new TimeSpan(0, 60, 0);
// If Start is bigger than end, Add a day to the end.
if (start > end)
end = end.Add(new TimeSpan(1, 0, 0, 0));
while (true)
{
Console.WriteLine((new DateTime() + start).ToString("hh:mm tt"));
start = start.Add(interval);
if (start > end)
break;
}
Output looks like this,
07:00 AM
08:00 AM
09:00 AM
10:00 AM
11:00 AM
12:00 PM
MS Documentation on TimeSpan
You can use TimeSpan with boolean logical operator to test if the currentTime is less than your endTime.
Below is example code.
TimeSpan startTime;
int interval;
TimeSpan tInterval = new TimeSpan(interval, 0, 0);
TimeSpan endTime;
TimeSpan currentTime = startTime;
while( (currentTime = startTime + tInterval) <= endTime)
{
// add currentTime to list box
}
This should take care of the issue with the End Times being "earlier" than the Start Time:
private static void TestTimeSpan()
{
int minutes = 60;
var interval = new TimeSpan(0,minutes,0);
TimeSpan start = DateTime.Parse("7:00 PM").TimeOfDay;
TimeSpan end = DateTime.Parse("1:00 AM").TimeOfDay;
//End of input data--start of solution
var diffSpan = end - start;
var diffMinutes = diffSpan.TotalMinutes > 0 ? diffSpan.TotalMinutes : diffSpan.TotalMinutes + (60 * 24);
var myTimeList = new List<TimeSpan>();
for(int i = 0; i < diffMinutes + minutes; i += minutes)
{
myTimeList.Add(start);
start = start.Add(interval);
}
myTimeList.ForEach(x => Console.WriteLine((new DateTime() + x).ToString("hh:mm tt")));
}
EDIT
Creating a sequence of Time values based in two input times and an interval is straight forward until the "start time" is earlier than the "end time", because just checking to see if the "end time" is greater than the start time fails your algorithm immediately.
This code utilizes the fact that there are only 24 hours in the day. Since the interval value is given in minutes, we can use that to section those minutes into "steps" of time. This code proceeds to step through each interval in time and capture the time at that step and save that in a List of TimeSpan (the captured value could easily be of type string--formatted as desired).
The trick here is when the "end time" is earlier than the "start time" we get a negative TimeSpan which is then used to calculate the steps to the "end time" on the next day. This is where the (60 * 24) [60 minutes x 24 hrs] part comes in to create the correct "diffMinutes" using a ternary operator.
After that the code simple iterates over the List "myTimeList" to write the formatted TimeSpan to the console. However, this 'List' is just a portable collection that can be sent anywhere in you code to do anything needed.
There are lots of other solutions, this one just seems straightforward, to me.

Get undertime and overtime automatically

Could you please help me? I'm trying to create an attendance system wherein the undertime and overtime will be automatically computed, but there's an error. For example the employee's scheduled out is 11 PM, and their overtime 12 AM which is 1 hour, but the output is 23. Can anyone help me how to compute elapsed time?
string datetime = "12:00 AM"; // this is the time you are going to time out
string OUT = "11:00 PM"; // this is your scheduled out
DateTime d1 = Convert.ToDateTime(datetime);
DateTime d2 = Convert.ToDateTime(OUT);
TimeSpan ts = d2.Subtract(d1);
MessageBox.Show(ts.TotalHours.ToString()); // output is 23 which is wrong, it must be 1 hour overtime only
IMO, in order to fix your problem, you have to work with the actual datetime objects.
Always record actual system datetime without manipulating parts of it.
For your case you should have the fields for record scheduled_work_start, scheduled_work_finished and actual_work_finished
for an instance, say one of the employees starts work at 10-01-2019 14:00:00 (2 PM) and finishes her time at 10-01-2019 23:00:00 (11 PM) and assume she did one hour overtime.
The system should record the actual_work_finished time as 11-01-2019 00:00:00 (12 AM)
When you require to calculate or find out the extra time
calculate:
var over_time_in_hours =
actual_work_finished.Substract(scheduled_work_finished).TotalHours;
Hope this makes sense.
If you print your d1 and d2 times:
d1 time => "09.01.2019 00:00:00".
d2 time => "09.01.2019 23:00:00".
Then 23-0 = 23 is the expected result.
By the way you can achieve your result by adding 1 day to d1 time object and subtract this result from d2 object:
TimeSpan ts = d1.AddDays(1).Subtract(d2);
Console.WriteLine(ts.TotalHours.ToString());
Let's start by naming your variables something that helps us to reason about the code.
// this is the time you are going to time out
DateTime actual = Convert.ToDateTime("12:00 AM");
// this is your scheduled out
DateTime scheduled = Convert.ToDateTime("11:00 PM");
TimeSpan overtime = scheduled.Subtract(actual);
What we find is that you're performing the wrong calculation to start with. This would be the correct calculation:
TimeSpan overtime = actual.Subtract(scheduled);
When we do that though we are now getting -23 hours. This is because your actual time isn't after your scheduled time. For that you need to add a day.
Try this:
// this is the time you are going to time out
DateTime actual = Convert.ToDateTime("12:00 AM").AddDays(1);
// this is your scheduled out
DateTime scheduled = Convert.ToDateTime("11:00 PM");
TimeSpan overtime = actual.Subtract(scheduled);
Then you get the result that you want - i.e. 1 hour.

Calculate the difference between two dates and times

I'm having problem in calculating the difference between two days using form in Visual Studio c#. I was trying to use TimeSpan but I want the messagebox to display a message. How to use if statement in this matter?
DateTime startDate = (DateTime)datePreviDate.Value;
DateTime endDate = (DateTime)datecurrentTime.Value;
TimeSpan ts = endDate.Subtract(startDate);
//Here i want to put if statemnet like
//if the difference of days are less than 2 AND PREVTIME + CURRENT TIME
//IS LESS THEN 24
//then MessageBox.Show.("you CANNOT CHANGE THE DATE")
//else MessageBox.Show.("you APPOINTMENT HAS BEEN CHANGED")
MessageBox.Show(ts.Days.ToString());
form image here
It's kind of hard to understand what you want. But this might help you. I am assuming "PREVTIME" and "CURRENTTIME" are assigned previously. I'm also just turning your comments into logic. Not sure if this is what you meant.
DateTime start = (DateTime)datePreviDate.Value;
DateTime end = (DateTime)datecurrentTime.Value;
var timespan = end - start
var totalTime = PREVTIME + CURRENTTIME;
if(timespan.TotalDays > 2 && totalTime < 24){
MessageBox.Show("You Cannot Change The Date");
//Continue Code Here
} else {
MessageBox.Show("Your Appointment Has Been Changed");
//Continue Code Here
}

How to calculate when current pay period ends?

I want to know how to calculate the last date of this pay period?
I know that the pay is bi-weekly and the first period started on 01/09/2012.
so far here what i have done
DateTime d = new DateTime();
d = Convert.ToDateTime("01/09/2012");
while (d <= Convert.ToDateTime("01/06/2013")) {
PayPeriod.Items.Add(new ListItem(d.ToString("MM/dd/yyyy"), d.ToString("MM/dd/yyyy")));
d = d.Date.AddDays(14);
}
And this work perfect, but it work perfect because I have manually put the ending of the current pay period "01/06/2013".
My question is how can I automatically figure out the last date of the current pay period?
You can easily do this with the following logic:
DateTime startTime = new DateTime(2012,09,01);
DateTime now = DateTime.Now;
var diff = now.Subtract (startTime);
int daysToEndPeriod = diff.Days % 14;
if (daysToEndPeriod == 0)
Console.WriteLine("end of pay period");
else
Console.WriteLine("end of pay period is: " + DateTime.Now.AddDays(14-daysToEndPeriod).Date);
This works because you'll always get the Modulo operator returns how many days past the pay period you have left.

Time Math Guidance needed

I have a DateTime object that is 10:00 AM
This time represents what time of day a report should be run.
I want to calculate the amount of time remaining from NOW until 10:00 AM
part of my confusion is NOW might be after 10:am or BEFORE 10am,
I keep playing around with TimeSpan, but my results are not quite right... I am sure this is simple, but it is one of those things I have been working of for a few hours and I need a push in the right direction...
I want the timespan object timeTillRun to be correct...here is what I have tried:
{
DateTime scheduledRun = DateTime.Today.AddHours(_timeToStart);//_timeToStart = 10
TimeSpan timeTillRun = DateTime.Now - scheduledRun;
}
This will work... but you need to reverse the order of subtraction:
TimeSpan timeTillRun = scheduledRun - DateTime.Now;
Note that if it's currently after 10AM, timeTillRun will be negative. You will presumably also need to check if the current time is on or after 10AM, then add 10 hours and one day to DateTime.Today to obtain the next run time. Alternatively, you could test if timeTillRun is negative; if so, just add one day to it (timeTillRun += new TimeSpan(1, 0, 0, 0)).
Try this
DateTime timeToStart = DateTime.Today.AddHours(10);
TimeSpan timeTillRun;
// Checking to see if current time is passed schedule run, if it is then we add a day (this is assuming this is run daily, if days are skipped like weekends for example then this would need some tweaking)
if (DateTime.Now > timeToStart)
timeTillRun = DateTime.Now.AddDays(1.0) - timeToStart;
else
timeTillRun = DateTime.Today - timeToStart;
double totalHoursRemaining = timeTillRun.TotalHours; // get total hours remaining
string prettyRemaining = String.Format("{0} day and {1} hours", timeTillRun.Days, timeTillRun.Hours); // can do some outputting here

Categories