14

Im trying to convert a decmial number of hours to days, hours and minutes.

This is what I have so far, its not quite there yet. I need to subtract the number of hours from the days from the hours part if that makes sense?

        /// <summary>
        /// Converts from a decimal value to DD:HH:MM
        /// </summary>
        /// <param name="dHours">The total number of hours</param>
        /// <returns>DD:HH:MM string</returns>
        public static string ConvertFromDecimalToDDHHMM(decimal dHours)
        {
            try
            {
                decimal hours = Math.Floor(dHours); //take integral part
                decimal minutes = (dHours - hours) * 60.0M; //multiply fractional part with 60
                int D = (int)Math.Floor(dHours / 24);
                int H = (int)Math.Floor(hours);
                int M = (int)Math.Floor(minutes);
                //int S = (int)Math.Floor(seconds);   //add if you want seconds
                string timeFormat = String.Format("{0:00}:{1:00}:{2:00}", D, H, M);

                return timeFormat;
            }
            catch (Exception)
            {
                throw;
            }
        }

SOLUTION:

    /// <summary>
    /// Converts from a decimal value to DD:HH:MM
    /// </summary>
    /// <param name="dHours">The total number of hours</param>
    /// <returns>DD:HH:MM string</returns>
    public static string ConvertFromDecimalToDDHHMM(decimal dHours)
    {
        try
        {
            decimal hours = Math.Floor(dHours); //take integral part
            decimal minutes = (dHours - hours) * 60.0M; //multiply fractional part with 60
            int D = (int)Math.Floor(dHours / 24);
            int H = (int)Math.Floor(hours - (D * 24));
            int M = (int)Math.Floor(minutes);
            //int S = (int)Math.Floor(seconds);   //add if you want seconds
            string timeFormat = String.Format("{0:00}:{1:00}:{2:00}", D, H, M);

            return timeFormat;
        }
        catch (Exception)
        {
            throw;
        }
    }
WraithNath
  • 17,658
  • 10
  • 55
  • 82

6 Answers6

38

You could use TimeSpan.FromHours to get the timespan, then you have all you need:

TimeSpan ts = TimeSpan.FromHours(Decimal.ToDouble(dHours));

For example:

int D = ts.Days;
int H = ts.Hours;
int M = ts.Minutes;
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • I wonder whether there are situations where the conversion from decimal to double could cause problems - it feels like there could be (and you might end up with one fewer minute than you expect, for example) but it's certainly a simple approach :) – Jon Skeet Mar 14 '12 at 09:31
  • I saw! Comment deleted :-). Nice answer (we all answered at the same time). You still got my +1. – Tom Chantler Mar 14 '12 at 09:31
  • 1
    You can get the desired string representation by using `ToString` like this: `ts.ToString(@"dd\:hh\:mm")`. – Martin Liversage Mar 14 '12 at 09:33
3

You need to subtract (D * 24) from hours... or you could just use:

int H = ((int) dHours) % 24;

If you're going to cast to int anyway, there's no need to call Math.Floor. So for example, you could actually use:

// I'd rename dHours as well, by the way...
int wholeHours = (int) dHours;
int days = wholeHours / 24;
int hours = wholeHours % 24;
int minutse = (int) ((dHours % 1M) * 60);

On the other hand, you need to be careful if it can be negative - all kinds of things could end up screwy in that case. If you don't believe you have to handle that, I'd explicitly check it and throw an exception if dHours is negative before you do anything else.

(Note that your try/catch block is pointless and distracting at the moment. Just get rid of it.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • thanks, it was the hours - (D*24) I was missing, works perfectly now – WraithNath Mar 14 '12 at 09:27
  • why is the try catch pointless? do you mean just for the code example I'm providing or in general? – WraithNath Mar 14 '12 at 10:17
  • @WraithNath: Any time you've got a single `catch` block whose body is just `throw`, you should remove the try/catch entirely. It serves no purpose (other than *arguably* for debugging) and clutters up your code base. Either way, if an exception is thrown within the body of the method, it will be propagated up the stack. – Jon Skeet Mar 14 '12 at 10:22
  • Thanks for explaining that, I thought without the try catch block and without subscribing to AppDomain.UnhandledException then the program would just crash. Ill not bother in future if its not required! ( catching and throwing generic errors ) – WraithNath Mar 14 '12 at 10:29
  • @WraithNath: Well you'll still get a failure if *nothing* catches the exception - but you were still rethrowing any exception you caught. – Jon Skeet Mar 14 '12 at 10:31
2

Simple.

double counter = 0.25;
TimeSpan span = TimeSpan.FromMinutes(counter);
textbox1.Text = span.ToString(@"hh\:mm\:ss");

result will be 00:00:15 seconds. If counter = 1, then the result will be 00:01:00 and so on.

Pang
  • 9,564
  • 146
  • 81
  • 122
Zia Ur Rahman
  • 1,850
  • 1
  • 21
  • 30
2

Why not do something like this?

double d = 25.23523;
Timespan t = TimeSpan.FromHours(d);

This will give you:

t = 1.01:14:06.8280000

Then you can interrogate the TimeSpan object as you wish: http://msdn.microsoft.com/en-us/library/system.timespan.aspx

NOTE: TimeSpan.FromHours needs a double input, not a decimal.

Tom Chantler
  • 14,753
  • 4
  • 48
  • 53
0
public static string GetTimeString(Decimal dHours)
{
    DateTime dTime = new DateTime().AddHours(dHours);
    return dTime.ToString("HH:mm:ss");    // HH: 24h or hh: 12h
}
0

here is another post which expains it pretty good.

Convert date to string format yyyy-mm-dd HH:MM:SS - C#

MyDateTime.ToString("yyyy-MM-dd hh:mm:ss");

also

http://blog.stevex.net/string-formatting-in-csharp/

Community
  • 1
  • 1
Mayank
  • 8,777
  • 4
  • 35
  • 60
  • sorry i misunderstood your question, TimeSpan.FromHours(hours).ToString("dd:hh:mm"); is the correct solution. – Mayank Mar 14 '12 at 09:33