riki
riki

Reputation: 1725

Sum of multiple TimeSpan

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

Upvotes: 2

Views: 3142

Answers (5)

Hans Kesting
Hans Kesting

Reputation: 39283

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

Upvotes: 1

Basin
Basin

Reputation: 1017

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

Upvotes: 6

Coskun Ozogul
Coskun Ozogul

Reputation: 2469

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();

Upvotes: 0

Sweeper
Sweeper

Reputation: 271625

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}"

Upvotes: 9

Mat
Mat

Reputation: 2072

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); 

Upvotes: 2

Related Questions