The Program

You are given two strings, A and B. A is the current position at which your timer is at, and B is the position at which your timer will stop. Both strings are in the format m:ss. You must write a program that determines the amount of time left which should also be formatted as m:ss or mm:ss.

Example

0:00 0:01 -> 0:01
0:55 1:00 -> 0:05
1:45 3:15 -> 1:30

• In dc the input is read incorrectly, since : is a command (data as code philosophy). Am I allowed to use spaces instead or do I need to find other language to answer this? – seshoumara Mar 28 '17 at 21:10
• is 01:30 valid output? (leading zero) – Luis Mendo Mar 28 '17 at 21:18
• Yes, I'll accept that as valid. I'll edit the description. – Josh Mar 28 '17 at 21:35
• @seshoumara The input must contain a colon. – Josh Mar 28 '17 at 21:41
• What is the maximum value expected for m? – Digital Trauma Mar 28 '17 at 22:06

Excel, 6 Bytes

=B1-A1


Assuming A is in cell A1 and B is in cell B1

• No... NO... I WILL NOT LET EXCEL WIN. +1 you devious individual. – Magic Octopus Urn Mar 28 '17 at 20:42
• Cancel that, |vy':¡ bootstrapped in 05AB1E, nothing I can do... I think Excel may honestly win this, nothing else automatically parses that format that I know of. – Magic Octopus Urn Mar 28 '17 at 20:49
• HOW? HOW? How is Excel winning? My brain must now explo... – caird coinheringaahing Mar 28 '17 at 22:07
• If m is greater than 23, then the formatting doesn't seem to work. For example if I type 45:45 in A1 and 22:22 in B1, then the result is 23:23:00 Edit Nevermind - max expected value for m is 9. – Digital Trauma Mar 28 '17 at 22:08
• @EngineerToast Whatever the default formatting is worked for me. I just typed in the input, moved to a different cell, typed the formula and hit enter. – Riley Mar 29 '17 at 13:12

MATL, 17 7 bytes

YOd15XO


Input is a cell array of strings, in the form {'1:45' '3:15'} or {'1:45', '3:15'}.

Try it online!

Explanation

YO     % Input cell array of strings (implicit). Convert to serial date numbers
d      % Difference
15XO   % Convert to format 15, i.e. 'HH:MM'. Display (implicit)

• Oh nice! Carry on! – Suever Mar 28 '17 at 23:56

Bash + coreutils, 44 39 bytes

tr : \ |dc -e?r60*+r-r60*-60~rn58PA~rnn


Try it online!

Explanation: using "1:45 3:15" as test case (last example). I show intermediary steps in quotes.

tr : \ |         # replace colons with spaces: "1 45 3 15"
dc -e?           # start dc script, push input to LIFO stack: "15 3 45 1"
r60*+            # turn time B to total seconds: "195 45 1"
r-r60*-          # turn time A to total seconds and get difference: "90"
60~r             # turn difference (time left) to minutes and seconds: "1 30"
n58P             # pop and print minutes, print colon (ASCII code 58): "30"
A~rnn            # print seconds. Padding with zeroes is done by dividing by
#10 (A), and printing the quotient and the remainder.


Note that I don't check if the minute value needs zero padding, because the OP stated that the maximum value for m is 9.

Below is my original 44 bytes answer, that used the date command to turn the total time left in seconds to the m:ss format.

date -d@tr : \ |dc -e?r60*+r-r60*-p +%M:%S

• @DigitalTrauma Thank you. But in the end, I managed to remove the date command and do the format printing in dc as well. – seshoumara Mar 29 '17 at 0:07
• Crossed out 44 looks like regular 44. – Riley Mar 30 '17 at 22:40
• @Riley I crossed out the spaces surrounding 44 as well, to get the effect that should have been there in the first place. – seshoumara Mar 31 '17 at 2:15
• codegolf.meta.stackexchange.com/a/7427/57100 – Riley Mar 31 '17 at 2:19

Python 2, 908783 80 bytes

Takes input like "2:45","5:01".

a,b=[60*int(s[-5:-3])+int(s[-2:])for s in input()]
print'%d:%02d'%divmod(b-a,60)


Try it online

• you can use map on input to save 3 bytes – Rod Mar 28 '17 at 21:27
• you can use list comprehension to save several bytes: a,b=[60*int(s[-5:-3])+int(s[-2:])for s in input()] – Felipe Nardi Batista Mar 31 '17 at 14:01
• If I'm not mistaken, you can save three additional characters replacing the two last lines by print'%d:%02d'%divmod(b-a,60) :) – Morwenn Apr 3 '17 at 18:21

c, 86

f(a,b,c,d){scanf("%d:%d%d:%d",&a,&b,&c,&d);d+=(c-a)*60-b;printf("%d:%02d",d/60,d%60);}


Batch, 74 bytes

@set t=%2-(%1)
@set/as=%t::=*60+1%,m=s/60,t=s/10%%6
@echo %m%:%t%%s:~-1%


Replacing the : in the time with *60+1 converts it into an expression that calculates the number of seconds. Batch interprets leading zeros as octal so I prepend a 1 to the seconds to ensure decimal conversion; fortunately the two 1s cancel out.

C, 112 100 bytes

Thanks to @betseg for saving 11 bytes and thanks to @Johan du Toit for saving one byte!

i,j;f(char*a,char*b){i=atoi(b)-atoi(a);j=atoi(b+2)-atoi(a+2);j<0?i--,j+=60:0;printf("%d:%02d",i,j);}


Try it online!

• You can change %s%d with %02d and remove the ?:. Try it online! – betseg Mar 28 '17 at 22:00
• scanf() is your friend for reading multiple integers. – Digital Trauma Mar 28 '17 at 23:40
• You can also save 1 byte by using: j<0?i++,j+=60:0; – Johan du Toit Mar 29 '17 at 11:01
• @DigitalTrauma Nononono, It's usually shorter to use arguments which he did. – Matthew Roh Mar 29 '17 at 13:05

MySQL, 13 22 bytes

select right(timediff(B,A),5)


expects the times in A and B.

Bash + GNU utilities, 43

date -d@date -f- +%s|dc -e??r-60/p +%M:%S


Explanation

         date -f- +%s                        # read in 2 line-delimited dates and output as number of seconds since the epoch
|dc -e                  # pipe to dc expression:
??                # - read 2 input numbers
r-              # - reverse and subtract
60/           # - divide by 60
p          # - output
                                   # evaluate date|dc command
date -d@                             +%M:%S  # format seconds difference and output


Note the dc expression divides by 60, because date reads the input as H:MM instead of M:SS.

ECMAScript 6, 9991 85 bytes

Single Line:

f=s=>s.split:.reduce((a,e,i)=>a+e*(!i?60:1),0);t=n=>~~(n/60)+":"+n%60;t(f(b)-f(a));


Slightly formatted:

f=s=>s.split:.reduce((a,e,i)=>a+e*(!i?60:1),0);
t=n=>~~(n/60)+":"+n%60;
t(f(b)-f(a));


I feel there could be some some savings in there.. but I am not seeing them at present.

Edit - excellent suggestions in the comments.

• You can remove the parentheses around the s. – Arjun Mar 29 '17 at 1:38
• And instead of s.split(":"), you can use the newer syntax : s.split<backtick>:<backtick>. – Arjun Mar 29 '17 at 1:39

PHP, 55 53 bytes

<?=date('i:s',($s=strtotime)($argv[2])-$s($argv[1]));


takes input from command line arguments

• 53 bytes: <?=date('i:s',($x=strtotime)($argv[2])-$x($argv[1])); – Ismael Miguel Mar 31 '17 at 1:02

Rebol, 5 bytes

b - a


Assuming I didn't miss any rules..

Rebol has arithmetic built-in for a number of literal data types. This also applies to its descendants such as Red

C#, 72 bytes

using System;a=>b=>((DateTime.Parse(b)-DateTime.Parse(a))+"").Remove(5);


Takes input as strings. b="3:15" a="1:45".

Explanation:

Because DateTime.Parse() returns a Date in hh:mm:ss format, I am able to parse the result into a string using +"", then trim the trailing :00.

This works with hh:mm because there are both 60 seconds in a minute and 60 minutes in an hour.

0:01 0:00 returns 0:01

1:00 0:55 returns 0:05

3:15 1:45 returns 1:30

• Unfortunately, the DateTime.Parse() is taking the input -- for example, 1:45 -- as hh:mm and not mm:ss, resulting in the follow output -- for A 1:45 and B 3:15 -- [01:30:00] ( hh:mm:ss ) ( even with CultureInfo.InvariantCulture specified ). You might have to add a "0:" + a/b when parsing. – auhmaan Mar 29 '17 at 10:37
• @auhmaan Ah, nice catch. I ended up trimming the trailing :00. – Oliver Mar 29 '17 at 14:05
• I believe you need a ; on the end, you can use currying i.e. a=>b=>, you need to fully qualify DateTime or include using System;. – TheLethalCoder Mar 30 '17 at 16:24

Pyth, 474544 40 Bytes

J.U-Zbm+*60hdedmmvkcd\:.z%"%d:%02d".DJ60


Takes the input separated by newlines.

Pyth had no time built-ins useful for this. I tried some fancy eval() stuff but apparantly Pyth can't eval stuff with * or any leading zeroes whatsoever. This got much longer than i hoped. Quite some bytes are spent on adding a leading zero to the output. At least I'm shorter than bash. Will add explanation if asked.

Try this!

alternative solution, 48 Bytes

J.U-Zbm+*60hdh_dmmvkcd\:.z
K%J60
s[/J60\:*<KT\0K


r(m:_:s)=60*read[m]+read s
a#b|(d,m)<-divMod(r b-r a)60=show d++':':['0'|m<=9]++show m


Try it online!

But I wonder if there are some library functions for this

EDIT: Removed import, also fixed an error where it showed m:s instead of m:ss

Also, well-formatted version:

convert :: String -> Integer

diffTime :: String -> String -> String
diffTime s1 s2 = let (d,m) = divMod (c b-c a) 60 in show d ++ ":" ++ pad2d m



EDIT2: Golfed off (30?) bytes thanks to Laikoni! Also golfed some other misc. bytes.

• You should tell us what language this is and how many bytes it uses. – Josh Mar 28 '17 at 21:38
• Yeah, I didn't mean to press post (who knew tab+enter from the text box posts your answer?) – Generic Display Name Mar 28 '17 at 21:48
• Same approach, 86 bytes: Try it online! – Laikoni Mar 28 '17 at 22:30
• I didn't think of using a list comprehension. Thanks :) – Generic Display Name Mar 28 '17 at 22:32

T-SQL, 238 bytes

CREATE PROCEDURE d @a time,@b time AS BEGIN DECLARE @d int DECLARE @s varchar(2) SET @d=datediff(s,@a,@b);SET @s=CAST(@d%3600/60 AS VARCHAR(3)) SELECT CAST(@d/3600 AS VARCHAR(3))+':'+(SELECT CASE WHEN LEN(@s)=1 THEN '0'+@s ELSE @s END)END


Usage:

EXEC d '00:55','01:00'


Seeing the PostGres example earlier I realised I hadn't seen many golfing attempts in SQL so I had a go at it in T-SQL. Now I know why you don't see much golfing in SQL :D

CJam, 3433 25 bytes

Saved 8 bytes thanks to Martin Ender!

{r':/60b}2*\m60mds2Te[':\


Try it online!

Explanation

{             e# Start of block
r            e#  Read one time from input
':/          e#  Split on colons, gives [minutes seconds]
60b          e#  Convert from base 60
}2*           e# Run this block 2 times
e# At this point, we have the two times in seconds on the stack
\             e# Swap top elements
m             e# Subtract
60md          e# Divmod the result by 60, to convert back to minutes and seconds
s             e# Convert the seconds to a string
2Te[          e# Pad it to 2 characters by adding 0s to the left (T = 0)
':            e# Push a colon character
\             e# Swap top elements, bringing seconds back to the top


T-SQL, 82 Bytes

select left(cast(dateadd(minute, datediff(S,'0:00','0:01')/60,114) as time(0)), 5)


Python, 160 bytes

I am still new to code golf so if anyone has any suggestions, I would appreciate it.

a, b = input()
def z(x):
x = x.split(":")
return int(x[0])*60+int(x[1])
a, b = z(a),z(b)
s, m = b-a,0
while s >= 60:
s -= 60
m += 1
print(str(m)+":"+str(s))

• Hello and welcome to our site. It seems that you are taking input for your program from preinitialized variables. However this is not permitted under out defaults for IO. I would recommend for this specific case to take input via raw_input(). – Wheat Wizard Mar 30 '17 at 0:07

REXX, 79 bytes

arg t q
say right(time(,f(q)-f(t),s),5)
f:return time(s,'00:'right(arg(1),5,0))


Pyth, 28

%"%d:%02d".Dh.+misMcd\:60Q60


Explanation

                   cd\:      # lambda to split c on ":"
sM          # map to convert string to int
mi      60Q   # convert from base-60 list to give seconds
.+              # delta of the two seconds values
h                # single-item list to int
.D              60 # divmod by 60
%"%d:%02d"                   # format output


Java 7, 164 bytes

String c(String a,String b){long s=x(b,1)-x(a,1)+(x(b,0)-x(a,0))*60,m=s%60;return(s/60)+":"+(m>9?m:"0"+m);}long x(String s,int i){return new Long(s.split(":")[i]);}


Explanation:

String c(String a, String b){       // Method with two String parameters and String return-type
long s = x(b,1) - x(a,1)          //  Get difference in seconds from input times
+ (x(b,0) - x(a,0)*60,   //   plus the difference in minutes times 60 to get the seconds
m = s%60;                       //  Temp variable of seconds after we've subtracted the minutes (used multiple times)
return (s/60)                     //  Return minutes
+":"                            //   plus ":"
+(m>9?m:"0"+m);                 //   plus seconds (with a leading 0 if necessary)
}                                   // End of method

long x(String s,int i){             // Separate ethod with String and Integer parameters and long return-type
return new Long(s.split(":")[i];  //  Return either minutes or seconds of String parameter based on the index
}                                   // End of method


Test code:

Try it here.

class M{
String c(String a,String b){long s=x(b,1)-x(a,1)+(x(b,0)-x(a,0))*60,m=s%60;return(s/60)+":"+(m>9?m:"0"+m);}long x(String s,int i){return new Long(s.split(":")[i]);}

public static void main(String[] a){
M m = new M();
System.out.println(m.c("0:00", "0:01"));
System.out.println(m.c("0:55", "1:00"));
System.out.println(m.c("1:45", "3:15"));
}
}


Output:

0:01
0:05
1:30


TXR Lisp, 101 bytes

$txr -e '(awk (:let (s "%M:%S")) ((mf (time-parse s)) (prn (time-string-local (- [f 1].(time-utc) [f 0].(time-utc)) s))))' 13:49 14:49 01:00 0:13 1:47 01:34 5:01 5:59 00:58 6:00 6:00 00:00 6:00 5:00 59:00  Condensed: (awk(:let(s"%M:%S"))((mf(time-parse s))(prn(time-string-local(-[f 1].(time-utc)[f 0].(time-utc))s)))) • You need a bytecount, and I don't think this is fully golfed. – Rɪᴋᴇʀ Mar 30 '17 at 1:58 Ruby, 91 bytes require'time';t=Time;d=t.parse($*[1])-t.parse($*[0]);puts t.at(d.to_i).utc.strftime '%H:%M'  Try it online! Takes input from command line arguments. Invocation: ruby outatime.rb$A $B  Example: ruby outatime.rb 1:45 3:15  Output: 01:30 • Welcome to the site! – James Mar 30 '17 at 20:08 PowerShell 47 Bytes param($s,[timespan]$f)($f-\$s).ToString("h\:mm")


Simple timespan math and coverting to hour and seconds string.

JavaScript, 88 bytes

a=>b=>{c=a.split:,d=b.split:;return +c[0]-d[0]-d[1]>c[1]?1:0+":"+(+c[1]+60-d[1])%60}


Try it online!

Explanation:

Splits the inputs on the colon

c=a.split:,d=b.split:;


Converts string to int

+c[0]


Gets the minute value

+c[0]-d[0]-d[1]>c[1]?1:0


Gets the second value

(+c[1]+60-d[1])%60


Returns the string minutes:seconds

return +c[0]-d[0]-d[1]>c[1]?1:0+":"+(+c[1]+60-d[1])%60