none
Convert Timespan to HH:MM:SS RRS feed

  • Question

  • Hallo

    Hope all are well.

    We are converting int which is minutes to Timespan, but we want to be able to only display it as HH:MM:SS and no days, meaning the Hours must be able to go over 24HR. Can somebody please assist.

    Currently is shows 1:10:34:33 trying to get rid of the days to only display 34:34:33. (Even if we can only show HH:MM it will be exactly what we are looking for..

     private void UpdateCalculationTotals()
            {
                TimeTotalBO TotalsTimes = new TimeTotalBO();
                DataTable dt = new DataTable();
                dt = ClockRecords.GetMonthWorkingHoursPerID(TimeRecords);
                
                    
    
                TotalsTimes.NormalHR = Convert.ToDouble(dt.Compute("SUM([Normal HR])", string.Empty));
                txtNormalHr.Text = TimeSpan.FromMinutes(TotalsTimes.NormalHR).Hours.ToString();
                TotalsTimes.NotApprovedHR = Convert.ToDouble(dt.Compute("SUM([Not Approved])", string.Empty));
                txtNotAppr.Text = TimeSpan.FromMinutes(TotalsTimes.NotApprovedHR).Hours.ToString();
                TotalsTimes.ApprovedHR = Convert.ToDouble(dt.Compute("SUM([Approved])", string.Empty));
                txtApprov.Text = TimeSpan.FromMinutes(TotalsTimes.ApprovedHR).Hours.ToString();
                TotalsTimes.SpecialHR = Convert.ToDouble(dt.Compute("SUM([Special])", string.Empty));
                txtSpecial.Text = TimeSpan.FromMinutes(TotalsTimes.SpecialHR).Hours.ToString();
                TotalsTimes.PublicHolidayHR = Convert.ToDouble(dt.Compute("SUM([Holiday])", string.Empty));
                txtHoliday.Text = TimeSpan.FromMinutes(TotalsTimes.PublicHolidayHR).Hours.ToString();
                                                             
            }


    labjac

    Monday, October 29, 2018 6:41 PM

Answers

  •     public static class TimeSpanExtensions
        {
            public static string ToStringNoDays(this TimeSpan source)
                      => $"{(int)source.TotalHours}:{source.ToString(@"mm\:ss")}";
        }

    or

        public static class TimeSpanExtensions
        {
            public static string ToStringNoDays(this TimeSpan source)
                      => (int)source.TotalHours + source.ToString(@"\.mm");
        }


    • Edited by DerChris88 Wednesday, October 31, 2018 7:28 PM
    • Marked as answer by labjac Friday, November 2, 2018 5:47 AM
    Wednesday, October 31, 2018 7:27 PM

All replies

  • Unfortunately you cannot format a TimeSpan out of the box as just the hours but you can do it using a little extra code.

    //Extension class so you can reuse it
    public static class TimeSpanExtensions
    {
      public static string ToStringNoDays ( this TimeSpan source )
                => $"{source.TotalHours}:{source.ToString(@"mm\:ss")}";
    }

    You could do it some other ways as well if you wanted. Here's the usage.

    var time = TimeSpan.FromHours(40);
    
    var str = time.ToStringNoDays();


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, October 29, 2018 7:18 PM
    Moderator
  • Check this example too:

    TimeSpan ts = TimeSpan.FromMinutes( 10_000 );
    
    int total_seconds = (int)ts.TotalSeconds;
    int hours = total_seconds / ( 60 * 60 );
    int remaining_seconds = total_seconds - hours * ( 60 * 60 );
    int minutes = remaining_seconds / 60;
    int seconds = remaining_seconds % 60;
    
    string s = string.Format( "{0:#00}:{1:#00}:{2:#00}", hours, minutes, seconds );
    Console.WriteLine( s ); // prints "166:40:00"
    

    Monday, October 29, 2018 7:35 PM
  • Try this.

    int seconds = minutes * 60;
                string.Format("{0:00}:{1:00}:{2:00}", seconds / 3600, (seconds / 60) % 60, seconds % 60);


    Thanks, AT

    Monday, October 29, 2018 8:07 PM
  • string str = ts.ToString(@"hh\:mm\:ss");

    Ah ok, you want to see the day as hours+24h? Try this:

    TimeSpan ts = TimeSpan.FromMinutes(12323);
    string str = (ts.Days*24+ts.Hours) + ts.ToString(@"\:mm\:ss");




    • Edited by DerChris88 Monday, October 29, 2018 8:40 PM
    Monday, October 29, 2018 8:30 PM
  • @Michael Taylor TotalHours is a double, so here is an improvement proposal:

        public static class TimeSpanExtensions
        {
            public static string ToStringNoDays(this TimeSpan source)
                      => source.TotalHours.ToString("00") + source.ToString(@"\:mm\:ss");
        }
    or
        public static class TimeSpanExtensions
        {
            public static string ToStringNoDays(this TimeSpan source)
                      => $"{source.TotalHours.ToString("00")}:{source.ToString(@"mm\:ss")}";
        }



    Monday, October 29, 2018 9:00 PM
  • Thanks All.

    We used the Top answer from Michael and it works perfect...

    Thank you..


    labjac

    Tuesday, October 30, 2018 7:36 PM
    • Unmarked as answer bylabjac  12 minutes ago

    What happened? Is it not working anymore?



    • Edited by DerChris88 Wednesday, October 31, 2018 7:18 PM
    Wednesday, October 31, 2018 7:17 PM
  • Hallo All

    We've used the solution from Michael and all seemed to work until we started doing some calculation and realized that we are either missing something or we not understanding something correctly.

    The total minutes is 1050. which should be 17Hr and 30Min.

    The result we are getting is 18:30 

    If we monitor the source value we are passing to the method it's  17:30:00 

    But when passing more then 24Hr it seems to be OK.. (Is there a way to modify below to suit our application?

     private void UpdateCalculationTotals()
    {
    txtNormalHr.Text = TimeSpanExtensions.ToStringNoDays(TimeSpan.FromMinutes(TotalsTimes.NormalHR)); 
    
    } 
    public static class TimeSpanExtensions
        {
            public static string ToStringNoDays(this TimeSpan source)
                      => source.TotalHours.ToString("00") + source.ToString(@"\.mm");
        }



    labjac

    Wednesday, October 31, 2018 7:19 PM
  • Hallo

    Seems like over 24Hr is also not working correct. 

    Total minutes: 2130

    We tested 1d:11hr:30min

    Expect 35hr : 30 min, result is 36Hr and 30 min.

    As I mentioned we might be missing something, but it works when there is no Minutes involved. eg.

    Total minutes: 9540

    Result is 159Hr: 0 min which is correct.


    labjac

    Wednesday, October 31, 2018 7:26 PM
  •     public static class TimeSpanExtensions
        {
            public static string ToStringNoDays(this TimeSpan source)
                      => $"{(int)source.TotalHours}:{source.ToString(@"mm\:ss")}";
        }

    or

        public static class TimeSpanExtensions
        {
            public static string ToStringNoDays(this TimeSpan source)
                      => (int)source.TotalHours + source.ToString(@"\.mm");
        }


    • Edited by DerChris88 Wednesday, October 31, 2018 7:28 PM
    • Marked as answer by labjac Friday, November 2, 2018 5:47 AM
    Wednesday, October 31, 2018 7:27 PM
  • You should do a unit test for it with some test cases, before you use it somewhere...
    Wednesday, October 31, 2018 7:30 PM
  • As Chris mentioned, TotalHours is a double so truncate to int and you'll get the expected result I believe.

    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, October 31, 2018 7:32 PM
    Moderator
  • Yes, using .ToString("00") was not a good idea because of the rounding, but casting it to int should work.

    I apologize, I should have test it a bit more...

    Wednesday, October 31, 2018 7:35 PM
  • Hallo

    We are running some tests already with a couple of user to find bug that needs to be resolved, so one of the clever users decided to use a calculator because they don't trust computers.. :-)

    The is a simple time sheet monitoring application for managing Overtime, Holiday and no Approved overtime. 

    People are very reluctant to move from excel sheets and hand written paper to any new application, which is good for our testing, every little instruction and every input box is always under a huge magnifying glass.. :-)

    Thanks all for always be willing to assist..

    Regards,


    labjac

    Friday, November 2, 2018 5:51 AM
  • Hi labjac,

    with unit tests I mean something like this:

    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace UnitTestProject
    {
        [TestClass]
        public class TimeSpanExtensionsTests
        {
            [TestMethod]
            public void TestRows()
            {
                for (int i = 0; i < 10000; i+=15)
                {
                    ToStringNoDays(i);
                }
            }
    
            public void ToStringNoDays(int timeIn)
            {
                // Arrange
                int minutes = timeIn % 60;
                int hours = timeIn / 60;
    
                // Act
                var result = TimeSpan.FromMinutes(timeIn).ToStringNoDays();
                var results = result.Split('.');
                var h = Int32.Parse(results[0]);
                var m = Int32.Parse(results[1]);
    
                // Assert
                Assert.AreEqual(hours, h);
                Assert.AreEqual(minutes, m);
            }
    
            [TestMethod]
            public void TestRowsBroken()
            {
                for (int i = 0; i < 10000; i += 15)
                {
                    ToStringNoDaysBroken(i);
                }
            }
    
            public void ToStringNoDaysBroken(int timeIn)
            {
                // Arrange
                int minutes = timeIn % 60;
                int hours = timeIn / 60;
    
                // Act
                var result = TimeSpan.FromMinutes(timeIn).ToStringNoDaysBroken();
                var results = result.Split('.');
                var h = Int32.Parse(results[0]);
                var m = Int32.Parse(results[1]);
    
                // Assert
                Assert.AreEqual(hours, h);
                Assert.AreEqual(minutes, m);
            }
        }
    }
        public static class TimeSpanExtensions
        {
            public static string ToStringNoDays(this TimeSpan source)
                      => (int)source.TotalHours + source.ToString(@"\.mm");
    
            public static string ToStringNoDaysBroken(this TimeSpan source)
                      => source.TotalHours.ToString("00") + source.ToString(@"\.mm");
        }

    Greetings, Chris


    • Edited by DerChris88 Sunday, November 4, 2018 1:43 AM
    Sunday, November 4, 2018 1:42 AM
  • Hallo Chris

    Tx, I don't have a lot of experience with C#, of and on been working with it when there is a requirement, this information is very helpful going forward, I will start looking at unit testing, never done it before.

    Regards,



    labjac

    Sunday, November 4, 2018 12:00 PM