Jak długo do tej daty?

11

Chodzi o to: Napisz funkcję, która wydrukuje czas od daty obecnej / dzisiejszej (w momencie wywołania funkcji) do daty podanej jako argument.

Założenia:

  • Data wprowadzenia będzie zawsze jutro lub później, w przyszłości.
  • Data wejścia nigdy nie będzie dłuższa niż 10 lat w przyszłości.

Zasady:

  • Dane wyjściowe muszą być w tym formacie: „[z roku (lat)], [x miesięcy (miesięcy)], y dni (dni) do -Data wejścia-”
  • Wyjściowe ramy czasowe (dzień / miesiąc / rok) muszą być poprawnie pluralizowane. tzn. 1 monthnie1 months
  • Wejście może być w dowolny format daty ty wolisz (3/15/12 - 15 marca 2012 - 2012.03.15).

Przykład: Zakładając, że program zostanie uruchomiony 15 marca 2012 r .:

  • Data wprowadzenia 3/20/12=5 days until 3/20/12
  • NIE Wprowadź datę 4/16/12=1 month, 1 days until 3/20/12
  • Data wprowadzenia 2012.04.20=1 month, 5 days until 2012.04.20
  • NIE Wprowadź datę 2012.04.20=36 days until 2012.04.20
  • Data wprowadzenia 10/31/17=5 years, 7 months, 16 days until 10/31/17
  • Data wprowadzenia 3/15/13=1 year until 3/15/13

To jest kod golfowy, więc wygrywa kod o najkrótszej długości.

Podejrzewam, że ze względu na termin wybiorę odpowiedź na:

23 marca 2012!

(To jest moje pierwsze pytanie CG, więc z przyjemnością poprawię błędy z mojej strony!)

Gaffi
źródło
3
Wolfram | Alpha 10 znaków:: now until <input time> p
Griffin
3
@Griffin 4 znaki:now-<input time>
PhiNotPi
1
@PhiNotPi dobrze grał, dobry panie.
Griffin,
2
Czy można powiedzieć „1 dzień do 16.03.12”?
MrZander
1
Jak pracować z odpowiedziami na temat skoków? Za 10 lat będzie 2 dni błąd. Jak długo trwa miesiąc
Hauleth

Odpowiedzi:

3

R, 99 znaków

Wiem, że to trochę oszustwo, ale R dotyczy wszystkich swoich pakietów, a smarowanie jest tak wygodne dla tego rodzaju zadań!

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

Stosowanie:

f("10/31/2017")
[1] 5 years, 7 months and 16 days 
5 years, 7 months and 16 days  until 10/31/2017
Paolo
źródło
1

PHP, 315 znaków

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;
}

Stosowanie:

p("11/03/2006");

Przyjmuje daty w dd/mm/yyyyformacie. Użyłem kalkulacji długości miesiąca Griffina ( ponownie ), chociaż musiałem wstawić w nim dodatkowe nawiasy, aby pierwszeństwo działało poprawnie. Zostawiłem też kilka przełamań linii, aby ułatwić sobie czytanie.

Gareth
źródło
1

Rubin (213)

przyjmuje daty w dowolnym formacie Date.parseakceptuje. Próbowałem właśnie zyyyy-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

aby uzyskać tygodnie, dodaj:

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

oraz [0,'week'],(między miesiącem a dniem). zawsze będą dni< 7

jsvnm
źródło
jakiej wersji Ruby używasz .... Próbowałem uruchomić Twój kod na Ruby1.9.2p0, ale to daje mi błąd uninitialized constant Object::Date (NameError)... Myślę, że używasz Dateklasy Rails
Rohit
@Rohit 1.9.3, nie używając Railsów. Data rdoc
jsvnm
Widziałem doktora wcześniej ... ale byłem zdezorientowany błędem, który się pojawiał ... Nadal nie jestem w stanie dowiedzieć się, dlaczego otrzymuję ten błąd. Mam Windows 7 64-bit, ruby192p0
Rohit
@rohit spróbuj z 193?
jsvnm
1

VBA: 766 631 znaków

Dzięki mellamokb za pomoc w skróceniu tworzenia łańcucha i 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
If Year(DateAdd("yyyy",-1*y,i))=Year(n) Then Exit For
Next
y=IIf(s=1,y-1,y)
z=s-r
z=IIf(z<0,z+12,z)
For m=0 To z
If Month(DateAdd("m",-1*m,i))=r Then Exit For
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

Wiem, że VBAzdecydowanie nie nadaje się do gry w golfa, jak również w niektórych innych językach, ale w tym jestem dobry (nie jestem ekspertem). :-)

To było dla mnie zabawne ćwiczenie!

Gaffi
źródło
1
To nie do końca wina VBA, istnieje kilka dobrych sposobów na połączenie logiki w kodzie :) Na przykład, If y > 0 Then a = y & " year,":If y > 1 Then a = y & " years,"można je połączyć za = y & " year" & Left("s", y - 1) & ","
mellamokb
@mellamokb Bardzo dobrze. Rzucę na to okiem i repost!
Gaffi,
Miałem problem z niektórych przypadków testowych, a mianowicie 1 year, 1 month, 1 day. Poprawiłem to w odpowiedzi. To rzeczywiście stworzyło krótszy kod!
Gaffi,
I po zaksięgowaniu aktualizację, widzę, że mogę zmienić If v < w Then d = w - v:If v = w Then d = 0, aby If v <= w Then d = w - vdla oszczędności dodatkowego 20 znaków. Zaktualizuję odpowiedź, jeśli mam bardziej znaczącą zmianę w poście.
Gaffi,
Wyobrażam sobie, że mogę to zrobić lepiej z tablicami ...
Spojrzę
1

JavaScript (ES6), 125 bajtów

Ponieważ odpowiedź Paolo wykorzystała bibliotekę zewnętrzną, zrobię to samo. W Node.js chodzi o pakiety NPM, a moment + HumanizeDuration jest tak wygodny dla tego zadania!

Środowiska węzłowe

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

Środowisko przeglądarki

Ponieważ biblioteki deklarują zmienne globalne, w rzeczywistości są nieco krótsze (102 bajty). Nie jest jasne, czy muszę dołączyć tagi skryptowe wymagane do załadowania w JavaScript innej firmy, więc oficjalnie policzę jeden z węzłów.

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

CoffeeScript, również 125 bajtów

f=(d)->console.log require('humanize-duration')((m=require 'moment')(d).diff(m()),{units:['y','mo','d'],round:1})+' until '+d
lodowisko. dozorca 6
źródło
1

PHP, 151 znaków

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));}
Conor
źródło
Brakuje liczby mnogiej i nie liczy się poprawnie, ponieważ format () nie odejmuje dni od miesięcy ... Miałem również podobne rozwiązanie z PHP.
powtac
To jest moje rozwiązanie PHP, ale wciąż nie ma wspomnianego wcześniej błędu: ma echo date_diff(new DateTime(),new DateTime($argv[1]))->format('%yyears, %mmonths, %a days');92 znaki długości, gdy jest wywoływany z wiersza poleceń.
powtac