# Convert hours (as decimals) to fractions for billable-time invoice

I'm creating an invoice in LaTeX and I've entered the hours I've worked as decimals (for example, 1, 1.5, 0.75, 2.25), but I want to display those decimals as fractions (1, 1½, ¾, 2¼).

(The reason I've entered the hours worked as a decimal is so I can perform simple invoice math with the fp package along the lines of this answer)

For a little context, here's the synopsis of the macro I created that includes the number of hours worked:

\lineitem{DATE}{HOURS}{RATE}{PROJECT}{DESCRIPTION}


The conversions I have in mind are pretty simple:

\documentclass{article}
\usepackage{xfrac}
\begin{document}
\begin{tabular}{r @{} l | r @{\hspace{0.1em}} l}
\multicolumn{2}{c}{Given...} & \multicolumn{2}{c}{Output} \\
\hline
1 & & 1 & \\
1 & .5 & 1 & \sfrac{1}{2} \\
0 & .75 & \sfrac{3}{4} & \\
2 & .25 & 2 & \sfrac{1}{4} \\
\end{tabular}
\end{document}


(I'm not married to \sfrac for displaying fractions, it's just the first package I reached for)

Is there an off-the-shelf package that will do what I want? If not, can anyone give me a few pointers how I might go about implementing my own conversion/display logic?

-
possible duplicate of Automatically add fractions and reduce the result (if neccessary) –  Peter Grill May 12 '14 at 19:31
@PeterGrill That helps, but my problem is not so much reducing the fraction, as it is splitting a decimal into a fraction. I know 2.25 = 2 + 25/100, I get that — I just don't know how to express that in TeX. Yes, my TeX knowledge is very bad. –  Michael Kropat May 12 '14 at 19:38

Adapting the solution from Automatically add fractions and reduce the result (if neccessary) yields:

## Notes:

• The \hphantom line should be commented out in your actual use case. It was added to produce a nicer output for posting on TeX.SE.
• This may not yield ideal results for all possible decimals but does work for the ones requested.
• For the HH:MM format, I used the xstring package for string comparison as I prefer its format, but probably can be done without this package if desired.

## Code:

\documentclass{article}
\usepackage{tikz}
\usepackage{xfrac}
\usepackage{xstring}

\makeatletter
\newcommand*{\@PositionOfColon}{}%
\newcommand{\IfStrContains}[4]{%
\StrPosition{#1}{#2}[\@PositionOfColon]% Record position in \@PositionOfColon
\IfEq{\@PositionOfColon}{0}%
{#4}% StrPosition=0 => Did not find the target string
{#3}% StrPosition>0 => Found the target string
}%

% Use Euclid's Algorithm to find the greatest
% common divisor of two integers.
\def\gcd#1#2{{% #1 = a, #2 = b
\ifnum#2=0 \edef\next{#1}\else
\@tempcnta=#1 \@tempcntb=#2 \divide\@tempcnta by\@tempcntb
\multiply\@tempcnta by\@tempcntb  % q*b
\@tempcntb=#1
\advance\@tempcntb by-\@tempcnta % remainder in \@tempcntb
\ifnum\@tempcntb=0
\@tempcnta=#2
\ifnum\@tempcnta < 0 \@tempcnta=-\@tempcnta\fi
\xdef\gcd@next{\noexpand%
\def\noexpand\thegcd{\the\@tempcnta}}%
\else
\xdef\gcd@next{\noexpand\gcd{#2}{\the\@tempcntb}}%
\fi
\fi}\gcd@next
}

\newcommand*{\rfNumer}{}%
\newcommand*{\rfDenom}{}%
\newcommand\reduceFrac[2]{%
\gcd{#1}{#2}{\@tempcnta=#1 \divide\@tempcnta by\thegcd
\@tempcntb=#2 \divide\@tempcntb by\thegcd
\ifnum\@tempcntb<0\relax
\@tempcntb=-\@tempcntb
\@tempcnta=-\@tempcnta
\fi
\xdef\rfNumer{\the\@tempcnta}
\xdef\rfDenom{\the\@tempcntb}}%
}
\makeatother

\newcommand*{\fracReduced}[2]{\reduceFrac{#1}{#2}\ensuremath{\sfrac{\rfNumer}{\rfDenom}}}%

\newcommand*{\TempNumerator}{}%
\newcommand*{\TempDenominator}{}%
\newcommand*{\DecimalToFrac}[1]{%
\IfStrContains{#1}{:}{%
\StrBefore{#1}{:}[\WholePortion]%
\StrBehind{#1}{:}[\TempNumerator]%
\def\TempDenominator{60}%
}{%
\pgfmathtruncatemacro{\WholePortion}{int(#1)}%
\pgfmathtruncatemacro{\TempNumerator}{100*(#1-\WholePortion)}%
\def\TempDenominator{100}%
}%
#1 =
\ifnum\WholePortion > 0\relax%
\WholePortion%
\else
\hphantom{0}% Just for nicer output of MWE. Should be deleted in actual use
\fi
\fracReduced{\TempNumerator}{\TempDenominator}%
}%

\begin{document}
Using decimals:

\DecimalToFrac{0.75},
\DecimalToFrac{0.50},
\DecimalToFrac{0.25}.

\DecimalToFrac{2.75},
\DecimalToFrac{1.50},
\DecimalToFrac{3.25}.

\bigskip
Using \texttt{HH:MM} format:

\DecimalToFrac{0:45},
\DecimalToFrac{0:30},
\DecimalToFrac{0:15},

\DecimalToFrac{0:20},
\DecimalToFrac{0:10},
\DecimalToFrac{0:05}.

\medskip
\DecimalToFrac{2:45},
\DecimalToFrac{1:15},
\DecimalToFrac{3:10}.

\DecimalToFrac{2:20},
\DecimalToFrac{1:10},
\DecimalToFrac{3:05}.
\end{document}

-
That helps a lot. Now I just need to figure out how to turn it into a mixed fraction. –  Michael Kropat May 12 '14 at 20:17
@MichaelKropat: Update to handle whole numbers. –  Peter Grill May 12 '14 at 20:29
That works beautifully. The code is about what I expected, except that it would have taken me forever to figure out how to express that on my own, so thanks a bunch. That was the last piece of my invoice, so now I can finally get paid, hopefully :) –  Michael Kropat May 12 '14 at 20:41

tikz provides this type of formatting:

\documentclass{article}
\usepackage{tikz,xfrac}
\usetikzlibrary{fpu}
\newcommand{\dectofrac}[1]{\begingroup%
\pgfkeys{/pgf/number format/frac}% Format as fraction
\let\frac\sfrac% Let \frac act like \sfrac
\pgfmathprintnumber{#1}\endgroup}
\pagestyle{empty}
\begin{document}

\begin{tabular}{r @{} l | r @{\hspace{0.1em}} l}
\multicolumn{2}{c}{Given...} & \multicolumn{2}{c}{Output} \\
\hline
1&    & 1& \\
1&.5  & 1&\dectofrac{0.5} \\
0&.75 &  &\dectofrac{0.75} \\
2&.25 & 2&\dectofrac{0.25}
\end{tabular}
\end{document}​

-
You can also use \dectofrac{2.25} which will be formatted to 2 1/4, but it depends on how you want the alignment to be. –  Werner May 12 '14 at 20:49
Very nice. I kinda expected something like this to be included in some package somewhere. –  Michael Kropat May 12 '14 at 20:51