Proper way to calculat time difference in c# - c#

I'm calculating overtime duration of a worker. I've load data into datagridview. I've named column as startot(5th in position) and endot(6th in position).
This is my code to calculate duration
TimeSpan duration = new TimeSpan();
foreach (DataGridViewRow row in attenViewGrid.Rows)
{
string start = row.Cells[5].Value.ToString();
string end = row.Cells[6].Value.ToString();
duration += DateTime.Parse(end).Subtract(DateTime.Parse(start));
}
Now I'm facing problem when overtime start at 10:00 am to nextday 9:00am. What can be the best way to calculate over time duration.

You should specify date and time in your table cell, when you create a datetime object from parsing a time string it sets a fixed date.
Otherwise you could put a condition for a one-day increment:
TimeSpan duration = new TimeSpan();
foreach (DataGridViewRow row in attenViewGrid.Rows)
{
string start = row.Cells[5].Value.ToString();
string end = row.Cells[6].Value.ToString();
if(DateTime.Parse(end).Compare(DateTime.Parse(start)) < 0)
duration += Timespan.FromDays(1);
duration += DateTime.Parse(end).Subtract(DateTime.Parse(start));
}

Related

Finding a DateTime After a TimeSpan Ignoring Weekdays and holidays [duplicate]

This question already has answers here:
AddBusinessDays and GetBusinessDays
(17 answers)
Closed 3 years ago.
I am trying to calculate a finishing date when adding a duration to a start date, but skipping weekends and holidays:
DateTime start = DateTime.Now;
TimeSpan duration = TimeSpan.FromHours(100);
List<DateTime> = //List of holidays
DateTime end = ?
For example if it is 11pm on a Friday and I add 2 hours, it would end on 1am Monday morning.
Is there a neat way of doing this?
I have a temporary fix which increments the time by an hour and checks the day of the week, but it is very inefficient.
Original Idea (untested):
public static DateTime calEndDate(DateTime start, TimeSpan duration, List<DateTime> holidays)
{
var startDay = start.Day;
var i = 0;
var t = 0;
while (TimeSpan.FromHours(t) < duration)
{
var date = start.Add(TimeSpan.FromHours(i));
if (date.DayOfWeek.ToString() != "Saturday" && date.DayOfWeek.ToString() != "Sunday") //and something like !holidays.contains(start)
{
t++;
}
i++;
}
return start.Add(TimeSpan.FromHours(t));
}
}
However is needs to run over 100 times for different start dates/durations on one asp.net page load. I don't know how to benchmark it, but it doesn't seem like an elegant solution?
Here's an algorithm I'd try.
I'm on my phone, and I'll get it wrong, but you should see the logic...
var end = start;
var timeToMidnight = start.Date.AddDays(1) -start;
if ( duration < timeToMidnight ) return start + duration;
end = endMoment + timeToMidnight;
duration = duration - timeToMidnight;
//Helper method
bool IsLeisure(Datetime dt) => (dt.DayOfWeek == DayOfWeek.Saturday) || (dt.DayOfWeek == DayOfWeek.Sunday) || holidays.Any( h => h.Date == dt.Date);
//We're at the first tick of the new day. Let's move to a work day, if needed.
while(IsLeisure(end)) { end = end.AddDays(1); };
//Now let's process full days of 'duration'
while(duration >= TimeSpan.FromDays(1) ) {
end = end.AddDays(1);
if(!IsLeisure(end)) duration = duration - TimeSpan.FromDays(1);
}
//Finally, add the reminder
end = end + duration;
Note: you haven't specified the logic for when start moment is a weekend or a holiday.
Yes there is :
DateTime currentT = DateTime.Now;
DateTime _time_ = currentTime.AddHours(10);
Simple and neat.

How would I calculate time left in winform?

Hi any ideas on how to calculate time left to a specific hour,
i.e. we start countdown with
if currentTime >= TimeSpan.Parse("06:40") && currentTime <= TimeSpan.Parse("07:25")
and then we parse current hour and end hour (in this example 7:25) and make a label show how many minutes and seconds are left.
I've tried making something with substracting timespan now and end time timespan but it didn't work out at all.
EDIT: The main idea is something like this, but I can't get it to work by using TimeSpan neither DateTime
string myTime;
void timer()
{
var endTime = DateTime.Parse(myTime);
var beginTime = DateTime.Now.TimeOfDay;
}
private void timer1_Tick(object sender, EventArgs e)
{
var endTime = DateTime.Parse(myTime);
var beginTime = DateTime.Now.TimeOfDay;
TimeSpan difference = endTime - beginTime;
TimeSpan currentTime = DateTime.Now.TimeOfDay;
if (currentTime >= TimeSpan.Parse("06:40") && currentTime <= TimeSpan.Parse("07:25"))
{
label5.Text = "0";
myTime = "07:25";
timer();
label6.Text = difference;
}
}
Use DateTime instead of TimeSpan when parsing points in time. TimeSpan is for durations. The difference between two points in time (DateTime) will be a duration (TimeSpan).
var end = DateTime.Parse("21:00");
var now = DateTime.Now; // Could also be some other point in time
TimeSpan timeLeft = end-now;
Console.WriteLine(timeLeft);
Result:
00:24:25.8581440
If you don't like the seconds and fractions of seconds, you can use a custom format, e.g.
Console.WriteLine(timeLeft.ToString("hh\\:mm"));

Increment previous date time

I'm trying to display date time of previous date, The date time will be incremented according to actual time, This is done to display some data on previous date time which will be incremented according actual time, Please suggest any alternate method any.The below code gets duration of base time and will increment it according to current date time.
class Program
{
private static double? Duration { get; set; }
static void Main(string[] args)
{
var startDate = DateTime.Parse("2016-11-02 11:17:55 AM");
if (!Duration.HasValue)
Duration = (DateTime.Now - startDate).TotalMinutes;
for (var count = 0; count < 10000; count++)
{
Console.WriteLine(DateTime.Now.AddMinutes(-Duration.Value).ToString("dd/MM/yyyy hh:mm:ss.fff tt"));
Thread.Sleep(100);
}
}
}
If I get your question you might need something like this:
DateTime previous = DateTime.Now;
for (var count = 0; count < 10000; count++)
{
Console.WriteLine((DateTime.Now - previous).ToString("dd/MM/yyyy hh:mm:ss.fff tt"));
previous = DateTime.Now
Thread.Sleep(100);
}
Basically you just need to store the current date now to be able to use it as previous date next time.

Time range is invalid statement

I am trying to create an if statement based on the dropdown created below. That determines whether the Time from is before or after Time To. According to the results, show validation.
For Example: Time From 4:00 and Time To 4:30. Should be acceptable.
However if Time From 4:00 and Time To 3:30. This should not be acceptable.
Any ideas?
private void BindTime()
{
// Set the start time (00:00 means 12:00 AM)
DateTime StartTime = DateTime.ParseExact("00:00", "HH:mm", null);
// Set the end time (23:55 means 11:55 PM)
DateTime EndTime = DateTime.ParseExact("23:55", "HH:mm", null);
//Set 15 minutes interval
TimeSpan Interval = new TimeSpan(0, 15, 0);
//To set 1 hour interval
//TimeSpan Interval = new TimeSpan(1, 0, 0);
ddlTimeFrom.Items.Clear();
ddlTimeTo.Items.Clear();
while (StartTime <= EndTime)
{
ddlTimeFrom.Items.Add(StartTime.ToShortTimeString());
ddlTimeTo.Items.Add(StartTime.ToShortTimeString());
StartTime = StartTime.Add(Interval);
}
ddlTimeFrom.Items.Insert(0, new ListItem(" Select ", "0"));
ddlTimeTo.Items.Insert(0, new ListItem(" Select ", "0"));
}
When you want to validate, use this function:
private bool IsSelectionValid()
{
DateTime fromTime;
DateTime toTime;
if(!DateTime.TryParse(ddlTimeFrom.SelectedValue, out fromTime) ||
!DateTime.TryParse(ddlTimeTo.SelectedValue, out toTime))
{
return false;
}
return fromTime < toTime;
}
IsSelectionValid would give return false if fromTime is not less than toTime.

Sum all the Timespan per row in DataGridView

This is my front end, in my case, I would like to add all the total hours of time in and time out of all my rows in my datagridview. My datagridview fields are id, employee code, date, timein and timeout.
Here is my back end, in here I computed the the late, the total hours, the day difference and the night difference. Is it possible to display on my textboxes the total hours, the late, the day diff and night based on the data on my datagridview. Sorry for my english, clarify my questions with yours.
string timeIn = datagridAttendance.CurrentRow.Cells["timeIn"].Value.ToString();
string timeOut = datagridAttendance.CurrentRow.Cells["timeOut"].Value.ToString();
DateTime tIn = Convert.ToDateTime(timeIn);
DateTime tOut = Convert.ToDateTime(timeOut);
TimeSpan span = tOut - tIn;
txtTotalHours.Text = Convert.ToString(span);
DateTime start = Convert.ToDateTime(txtStart.Text);
txtMe.Text = tIn.ToShortTimeString();
DateTime inTime = Convert.ToDateTime(txtMe.Text);
if (inTime > start)
{
TimeSpan late = inTime - start;
txtLate.Text = Convert.ToString(late);
}
else
{
txtLate.Text = "Not Late";
}
TimeSpan passLength = new TimeSpan(0, 0, 0, 1);
TimeSpan nightTime = new TimeSpan();
while (tIn < tOut)
{
tIn = tIn.Add(passLength);
if (tIn.Hour < 6 || tIn.Hour == 23)
{
nightTime = nightTime.Add(passLength);
}
}
txtNightDif.Text = Convert.ToString(nightTime);
TimeSpan day = span - nightTime;
txtDayDif.Text = Convert.ToString(day);
Your code will look like below with the arrays timein[] timeout[] being the values in each row of DataGridView
DateTime[] timein = { DateTime.Parse("1:00"), DateTime.Parse("3:00"), DateTime.Parse("5:00"), DateTime.Parse("7:00") };
DateTime[] timeout = { DateTime.Parse("2:00"), DateTime.Parse("4:00"), DateTime.Parse("6:00"), DateTime.Parse("8:00") };
TimeSpan totalTime = new TimeSpan();
for (int i = 0; i < timein.Count(); i++)
{
totalTime += timeout[i] - timein[i];
}​
You can do this in your database, and then return the sum of timespans as a column. That would be better and far easier.

Categories

Resources