Sum of multiple TimeSpan - c#

I have to do the sum of more time spans in a DataTable to use the code below, but the total sum is wrong, what is due to this:
DataTable(dt) values:
09:21
08:28
08:46
04:23
Total hours: 30,97 //97 minutes is not correct
C# Code:
TimeSpan totaleOreMarcaTempo = TimeSpan.Zero;
int conta = 0;
foreach (DataRow dr in dt.Rows)
{
String OreMarcaTempo = tm.ConteggioOreGiornaliere(dr["Data"].ToString()); //This string contains at each cycle 09:21 08:28 08:46 04:23
TimeSpan oreMarcatempo = TimeSpan.Parse(OreMarcaTempo.ToString());
totaleOreMarcaTempo = totaleOreMarcaTempo + oreMarcatempo;
conta++;
}
labelTotaleOreMarcaTempoMod.Text = "" + (int)totaleOreMarcaTempo.TotalHours + ":" + totaleOreMarcaTempo.Minutes.ToString(); //30:58

30.97 is the correct number of hours. It does not mean "30 hours and 97 minutes".
30.97 hours is 30 hours and 58 minutes. 58 / 60 is roughly 0.97.
I think you just need to format your string properly. One way to format it is:
#"{(int)yourTimeSpan.TotalHours}:{yourTimeSpan.Minutes}"

Value 30.97 is correct (30.97 hours, where 0.97 is hour (60 minutes * 0.97 = 58 minutes),
you just need convert fraction of TotalHours to minutes.
var raw = "09:21 08:28 08:46 04:23";
var totalTimespan =
raw.Split(" ")
.Select(TimeSpan.Parse)
.Aggregate(TimeSpan.Zero, (total, span) => total += span);
// Use integer value of TotalHours
var hours = (int)totalTimespan.TotalHours;
// Use actual minutes
var minutes = totalTimespan.Minutes
var output = $"{hours}:{minutes}";
var expected = "30:58";
output.Should().Be(expected); // Pass Ok

You have to change the Format. 0,98 hours = 58,2 minutes
labelTotaleOreMarcaTempoMod.Text =string.Format ("{0:00}:{1:00}:{2:00}",
(int)totaleOreMarcaTempo.TotalHours,
totaleOreMarcaTempo.Minutes,
totaleOreMarcaTempo.Seconds);

To print out a TimeSpan "correctly", just use the correct formatting:
labelTotaleOreMarcaTempoMod.Text = totaleOreMarcaTempo.ToString("c");
or
labelTotaleOreMarcaTempoMod.Text = totaleOreMarcaTempo.ToString("hh':'mm");
EDIT Do note (thanks, Basin) that the second form ignores days.
Reference: Standard TimeSpan Format Strings and Custom TimeSpan Format Strings

30.97 is the correct value but not HH:mm format.
For me the correct solution is :
var total = Math.Floor( totaleOreMarcaTempo.TotalMinutes / 60).ToString() + ":" + Math.Floor( totaleOreMarcaTempo.TotalMinutes % 60).ToString();

Related

Converting string hours and minutes into Days/Hours/Minutes in C#?

I have the sum of the working duration of Employees in a specific period. I need to convert this Working Duration into days, hours and minutes. The problem is my day is equal to 9 Hours, not 24 Hours. Means I am dividing my Duration with 9. But the result I am getting is in points and I can't convert to my yearning format. Following is my code:
var Durations = TimeSpan.FromMinutes(db.Attendances.Where(x => x.EmployeeId == id)
.Sum(x => TimeSpan.Parse(x.Duration).TotalMinutes));
var TotalDuration = string.Format("{0}:{1}", Durations.TotalHours, Durations.Minutes);
This one is working absolutely fine. I am getting results in the following format:
H:M
8:5
12:7
19:15
The problem is I need to convert hours into Days and Hours when I divide it by 9. E.g. 19. If I divide 19 by 9 I get 2.111111 Means 2 Days and 1 Hour. How can I get the answer in days and hours format?
I think this should answer your question:
TimeSpan s = new TimeSpan(20,0, 0);
int day = (int)s.TotalHours / 9;
int hour = (int)s.TotalHours % 9;
Console.WriteLine($"the duration in day is {day } hour {hour}");
You can add an extension method to TimeSpan.
public static (int day,int hour) GetDayAndHour(this TimeSpan timeSpan,int dayDuration == 9) {
var number= timeSpan.TotalHours/dayDuration;
int day = (int)Math.Truncate(number);
int hour= (int)Math.Truncate((number-day)*10);
return (day,hour);
}
I use C#7 tuple.If you use previous version, create costume datatype or use Tuple<int, int>.
int totalmins = 5000; // given input
int hourPerDay = 9 // given input
int dayHour = 60 * hourPerDay;
int days = totalmins / dayHour;
int hours = (totalmins % dayHour) / 60;
int mins = tot_mins % 60;

Extract from Timespan Totalhours and Minutes

I get from TimeSpan.TotalHours 24,75 hours.
How can I convert this to get the full and not roundes hours (=24) plus the minutes (0,75hours = 45 minutes)? So the result should be hours = 24 and minutes = 45
I tried to convert it to string and make substring but I would like to know if there is a better way than this.
string test = Reststunden.TotalHours.ToString().Substring(Reststunden.TotalHours.ToString().IndexOf(","),3).Replace(",", "");
double Minuten = Convert.ToInt16(test) * 0.6;
Well just round the total hours appropriately by casting, and then use the Minutes property:
int hours = (int) timeSpan.TotalHours;
int minutes = timeSpan.Minutes;
If you'll ever have a negative TimeSpan, you should think about what you want the results to be and add appropriate tests - you may well find it doesn't do what you want with the simple code above.
How about:
var ts = TimeSpan.FromHours(24.75);
var h = System.Math.Floor(ts.TotalHours);
var m = (ts.TotalHours - h) * 60;
Or even:
var h = (int) (ts.TotalMinutes / 60);
var m = ts.TotalMinutes % 60;
I needed to display the total hours and minutes in the following format HH:mm.
With the help of the other answers I came to the following result:
var end = DateTime.Now;
var duration = end - StartUpTime;
var h = (int)(duration.TotalMinutes / 60);
var m = (int)(duration.TotalMinutes % 60);
var text = $"{h:D2}:{m:D2}";

Get correct time

I am getting the current time and trying to split it into two separate variables.
I want the time to be in 12 hours not 24
When i do this the first and second variable are the same. How can i fix this?
int hour = DateTime.Now.Hour % 12;
if (hour == 0) hour = 12;
then,
FirstDigitHour = hour / 10;
secondDigitHour = hour % 10;
the time here is 6 pm so FirstDigitHour & secondDigitHour both = 6
the first digit should equal 0
If you're trying to format the time for display, I would advise you use the proper format string:
DateTime.Now.ToString("hh tt")
Which is the time in 2-digit 12-hour format (hh) with AM/PM (tt)
See the documentation:
http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
Wouldn't this satisfy your need better
var x = DateTime.Now.ToString("hh");
it returns a string with hours in 12 hour format ( e.g. "01" or "02" ... "11" "12" )
Then you can just get the first and second digit like so
int firstDigit = Convert.ToInt32(x[0].ToString());
int secondDigit = Convert.ToInt32(x[1].ToString());
Seems to work fine for me.
int hr = 18; // 6pm
int hour = hr % 12;
if (hour == 0)
hour = 12;
int fd = hour/10;
int ld = hour%10;
in this case I have fd = 0 and ld = 6.
See it run.
Check if there is a second digit first... if DateTime.Now.Hour > 10. Then you have it.

how to get datetime with +- 10 seconds Buffer?

i have:
jobElement.CreationDate = jobElement.CreationDate + TimeSpan.FromHours(24.0);
i would like to have not strictly 24 hours, but with +- 10 seconds Buffer. like 23.59.10 and 00.00.10
hot to reach that with c#?
This will generate CreationDate + 23:50 and CreationDate + 24:10 with equal probability:
Random random = new Random();
TimeSpan buffer = TimeSpan.FromSeconds(10);
TimeSpan span = TimeSpan.FromHours(24.0);
// 50% of the time do this
if(random.Next() % 2 == 0)
{
span += buffer;
}
// The rest of the time do this
else
{
span -= buffer;
}
jobElement.CreationDate = jobElement.CreationDate + span;
What do you need to do with that?
If you need to any comparison create custom class with overwritten equality operators.
I'm not 100% sure what you want here but I'll give it a shot
DateTime dt1 = DateTime.Now;
DateTime dt2 = DateTime.Now.AddDays(1).AddSeconds(8);
These two are now 24 hours and 8 seconds apart.
Then if you want to see if they are "almost" 24 hour appart, you can do something like this:
if( Math.Abs((dt1-dt2.AddDays(-1))) < 10 ){
//dt2 is 24 after dt1 +- 10 seconds
}else{
//they are not
}
First time (00.00.00) of current date -/+ 10 secs would be:
DateTime dateFrom = jobElement.CreationDate.Date.AddSeconds(-10);
DateTime dateTo = jobElement.CreationDate.Date.AddSeconds(10);
Is that it?
I'll add this variant. It's different from others because it isn't "second based" but "tick" based (the tick is the smallest time that a TimeSpan/DateTime can compute)
const int sec = 10; // +/- seconds of the "buffer"
const int ticksSec = 10000000; // There are 10000000 Ticks in a second
Random r = new Random();
int rng = r.Next(-sec * ticksSec, sec * ticksSec + 1); // r.Next is upper-bound exclusive
var ts = TimeSpan.FromHours(24) + TimeSpan.FromTicks(rng);
jobElement.CreationDate = jobElement.CreationDate + ts;
There are limits in the Random class (it can't generate a long, and generating a "constrained" long (a long with maxValue = x) is non-trivial based only on the Random class, so this will work for up to 3 minutes and something of "buffer" (214 seconds to be more exact).
If you want +/- 10 with all numbers between
Random r = new Random();
int x = r.Next(-10, 11);
var ts = TimeSpan.FromHours(24).Add(TimeSpan.FromSeconds((double)x));
jobElement.CreationDate = jobElement.CreationDate + ts;

How do i convert HH:MM:SS into just seconds using C#.net?

Is there a tidy way of doing this rather than doing a split on the colon's and multipling out each section the relevant number to calculate the seconds?
It looks like a timespan. So simple parse the text and get the seconds.
string time = "00:01:05";
double seconds = TimeSpan.Parse(time).TotalSeconds;
You can use the parse method on aTimeSpan.
http://msdn.microsoft.com/en-us/library/system.timespan.parse.aspx
TimeSpan ts = TimeSpan.Parse( "10:20:30" );
double totalSeconds = ts.TotalSeconds;
The TotalSeconds property returns the total seconds if you just want the seconds then use the seconds property
int seconds = ts.Seconds;
Seconds return '30'.
TotalSeconds return 10 * 3600 + 20 * 60 + 30
TimeSpan.Parse() will parse a formatted string.
So
TimeSpan.Parse("03:33:12").TotalSeconds;
This code allows the hours and minutes components to be optional. For example,
"30" -> 24 seconds
"1:30" -> 90 seconds
"1:1:30" -> 3690 seconds
int[] ssmmhh = {0,0,0};
var hhmmss = time.Split(':');
var reversed = hhmmss.Reverse();
int i = 0;
reversed.ToList().ForEach(x=> ssmmhh[i++] = int.Parse(x));
var seconds = (int)(new TimeSpan(ssmmhh[2], ssmmhh[1], ssmmhh[0])).TotalSeconds;
//Added code to handle invalid strings
string time = null; //"";//"1:31:00";
string rv = "0";
TimeSpan result;
if(TimeSpan.TryParse(time, out result))
{
rv = result.TotalSeconds.ToString();
}
retrun rv;

Categories