# How long until this date?

The idea is this: Write a function to print the length of time from now/today's date (at the time the function is called) until a date supplied as an argument.

Assumptions:

• Input date will always be tomorrow or later, in the future.
• Input date will never be more than 10 years in the future.

Rules:

• Output must be in this format: "[z year(s)], [x month(s)], y day(s) until -Input Date-"
• Output time frame (day/month/year) must be pluralized correctly. i.e. 1 month, not 1 months
• Input can be in whichever date format you prefer (3/15/12 - March 15, 2012 - 2012.03.15).

Example: Assuming program is run on March 15, 2012:

• Input date of 3/20/12 = 5 days until 3/20/12
• NOT Input date of 4/16/12 = 1 month, 1 days until 3/20/12
• Input date of 2012.04.20 = 1 month, 5 days until 2012.04.20
• NOT Input date of 2012.04.20 = 36 days until 2012.04.20
• Input date of 10/31/17 = 5 years, 7 months, 16 days until 10/31/17
• Input date of 3/15/13 = 1 year until 3/15/13

This is code golf, so shortest length code wins.

I suppose for the sake of having a deadline, I will be selecting an answer on:

## March 23, 2012!

(This is my first CG question, so I'll be happy to correct any question errors on my part!)

• Wolfram|Alpha 10 chars: now until <input time> :p – Griffin Mar 15 '12 at 22:16
• @Griffin 4 chars: now-<input time> – PhiNotPi Mar 15 '12 at 22:23
• @PhiNotPi well played, good sir. – Griffin Mar 15 '12 at 22:24
• Is it okay to say "1 days until 3/16/12"? – MrZander Mar 15 '12 at 23:32
• How to work with leap yeras in answer? In 10 years then will be 2 days error. How long is month? – Hauleth Mar 16 '12 at 7:18

## R, 99 characters

I know it is sort of cheating, but R is all about its packages and lubridate is so convenient for this kind of tasks!

f=function(x){library(lubridate);cat(show(as.period(interval(mdy("3/15/2012"),mdy(x)))),"until",x)}


# Usage:

f("10/31/2017")
 5 years, 7 months and 16 days
5 years, 7 months and 16 days  until 10/31/2017


## PHP, 315 characters

function p($z) { list($d,$m,$y)=explode("/",$z);$d=$d-date("d");$n=$m-1;$m=$m-date("m")-($d<0);
$d=$d+($d<0)*($n>7^$n&1)+27+($n-2?3:($y%4?1:($y%100?2:($y%400?1:2))));$y=$y-date("Y")-($m<0);
$s="s "; echo ($y?$y." year".$s[$y<2]:"")." ".($m?$m." month".$s[$m<2]:"")." ".($d?$d." day".$s[$d<2]:"")." until ".$z;
}


Usage:

p("11/03/2006");


Takes dates in a dd/mm/yyyy format. I've used Griffin's month length calculation(again), though I had to stick extra brackets in it to make the precedence work properly. I've also left some line-breaks in to make it a little easier to read.

# Ruby (213)

takes dates in any format Date.parse accepts. Tried just with yyyy-mm-dd

def u s
t=Date.today
f=Date.parse s
[[0,'year'],[0,'month'],[0,'day']].map{|c,n| while t<f
c+=1
t=t.send"next_#{n}"
end
c,t=c-1,t.send("prev_#{n}")if t>f
[c,n+(c>1??s:'')]*' 'if c>0}.compact*', '+' until '+s
end


['prev_','next_'].each{|n|Date.send(:define_method,n+'week'){send n+'day',7}}


and [0,'week'], (between month and day). days will then always be < 7

• which ruby version are you using.... I tried to run your code on ruby1.9.2p0, but it gives me error uninitialized constant Object::Date (NameError)... I think you are using the Rails Date class – Rohit Mar 22 '12 at 12:09
• @Rohit 1.9.3, not using Rails stuff. Date rdoc – jsvnm Mar 23 '12 at 8:16
• I saw the doc earlier.. but was confused on the error I was getting... I am still unable to figure out why I am getting this error. I am on windows 7 64-bit, ruby192p0 – Rohit Mar 23 '12 at 21:57
• @rohit try with 193? – jsvnm Mar 24 '12 at 10:15

## VBA: 766 631 Chars

Thanks to mellamokb for helping shorten up the string creation and IIf.

Function k(i)
e=" month"
g="s"
n=Now()
r=Month(n)
s=Month(i)
t=DateSerial(Year(i),s,1)
u=DateSerial(Year(i),s-1,1)
v=Day(n)
w=Day(i)
x=DateSerial(Year(n),r,1)
d=t-u-v+w
For y=0 To 10
Next
y=IIf(s=1,y-1,y)
z=s-r
z=IIf(z<0,z+12,z)
For m=0 To z
Next
d=IIf(v<=w,w-v,d)
m=IIf(v>w,m-1,m)
If y Then a=y & " year" & Left(g,y-1)
a=IIf((m Or d) And y,a & ",",a)
If m Then b=IIf(d,m & e & Left(g,m-1) & ",",m & e & Left(g,m-1))
If d Then c=IIf(d>1,d & " days",d & " day")
k=Trim(Trim(a & " " & b) & " " & c) & " until " & i & "."
End Function


I know VBA definitely does not lend itself to code golfing as well as some other languages, but it's what I'm good (not expert) at. :-)

This has been a fun exercise for me!

• It's not entirely VBA's fault, there are some good ways to combine logic in your code :) For example, If y > 0 Then a = y & " year,":If y > 1 Then a = y & " years," could be combined together to a = y & " year" & Left("s", y - 1) & "," – mellamokb Mar 16 '12 at 14:23
• @mellamokb Very good. I'll take a look at that and repost! – Gaffi Mar 16 '12 at 14:27
• I had an issue with some test cases, namely 1 year, 1 month, 1 day. I have corrected this in the answer. It actually made for shorter code! – Gaffi Mar 16 '12 at 17:39
• And after posting the update, I see that I can change If v < w Then d = w - v:If v = w Then d = 0 to If v <= w Then d = w - v for a savings of an additional 20 characters. I'll update the answer if I have a more significant change to post. – Gaffi Mar 16 '12 at 17:59
• I imagine I can do this better with arrays... I will take another look and possibly add another answer... – Gaffi Mar 18 '12 at 7:09

## JavaScript (ES6), 125 bytes

Since the answer by Paolo used an external library, I shall do the same. Node.js is all about NPM packages and moment + HumanizeDuration is so convenient for this task!

### Node environments

m=require('moment'),f=d=>console.log(require('humanize-duration')(m(d).diff(m()),{units:['y','mo','d'],round:1})+' until '+d)


### Browser environment

Since the libraries declare global variables, it's actually a bit shorter (102 bytes). It's not clear whether I need to include the script tags required to load in the third-party JavaScript, so I will count the Node one officially.

f=d=>console.log(humanizeDuration((m=moment)(d).diff(m()),{units:['y','mo','d'],round:1})+' until '+d)


## CoffeeScript, also 125 bytes

f=(d)->console.log require('humanize-duration')((m=require 'moment')(d).diff(m()),{units:['y','mo','d'],round:1})+' until '+d


# PHP, 151 chars

function p($z){$n=date_create(date('Y-m-d'));$d=date_create($z);$i=date_diff($n,$d);print($i->format('%R%y years, %m months, and %a days until '.$z));}  • It is missing the plurals and does not count correctly, because format() does not subtract the days from the months... I had a similar solution with PHP as well. – powtac May 15 '12 at 22:18 • This is my PHP solution, but still lacks of the previously mentioned error: echo date_diff(new DateTime(),new DateTime($argv))->format('%yyears, %mmonths, %a days'); Its 92 chars long, when called on the command line. – powtac May 15 '12 at 22:23