2

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
riki
  • 1,502
  • 5
  • 17
  • 45

5 Answers5

9

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}"
Sweeper
  • 213,210
  • 22
  • 193
  • 313
6

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
Basin
  • 887
  • 1
  • 14
  • 28
2

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); 
Mat
  • 1,960
  • 5
  • 25
  • 38
1

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

Hans Kesting
  • 38,117
  • 9
  • 79
  • 111
  • This is the correct answer. I don't know why someone has downvoted it. – George Helyar Aug 06 '18 at 08:01
  • 1
    @GeorgeHelyar, I am not downvoter, but 1. Format string `"hh:mm"` will throw `FormatException`, should be `"hh\\:mm"`. 2. `totaleOreMarcaTempo.ToString("hh:mm")` will not return total hours("30:58") but return "06:58". – Basin Aug 06 '18 at 08:15
0

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();
Coskun Ozogul
  • 2,389
  • 1
  • 20
  • 32