Wie lange bis zu diesem Datum?

11

Die Idee ist folgende: Schreiben Sie eine Funktion, um die Zeitspanne vom aktuellen Datum (zum Zeitpunkt des Aufrufs der Funktion) bis zu einem als Argument angegebenen Datum zu drucken.

Annahmen:

  • Das Eingabedatum wird in Zukunft immer morgen oder später sein.
  • Das Eingabedatum wird in Zukunft niemals mehr als 10 Jahre betragen.

Regeln:

  • Die Ausgabe muss in diesem Format erfolgen: "[z Jahr (e)], [x Monat (e)], y Tag (e) bis -Input Date-"
  • Der Ausgabezeitrahmen (Tag / Monat / Jahr) muss korrekt pluralisiert werden. dh 1 monthnicht1 months
  • Die Eingabe kann in welch auch immer sein Datumsformat Sie bevorzugen (3/15/12 - 15. März 2012 - 2012.03.15).

Beispiel: Angenommen, das Programm wird am 15. März 2012 ausgeführt:

  • Eingabedatum von 3/20/12=5 days until 3/20/12
  • NICHT Eingabedatum von 4/16/12=1 month, 1 days until 3/20/12
  • Eingabedatum von 2012.04.20=1 month, 5 days until 2012.04.20
  • NICHT Eingabedatum von 2012.04.20=36 days until 2012.04.20
  • Eingabedatum von 10/31/17=5 years, 7 months, 16 days until 10/31/17
  • Eingabedatum von 3/15/13=1 year until 3/15/13

Dies ist Code Golf, also gewinnt der Code mit der kürzesten Länge.

Ich nehme an, um eine Frist zu haben, werde ich eine Antwort auswählen auf:

23. März 2012!

(Dies ist meine erste CG-Frage, daher werde ich gerne alle Fragenfehler meinerseits korrigieren!)

Gaffi
quelle
3
Wolfram | Alpha 10 Zeichen :: now until <input time> p
Griffin
3
@ Griffin 4 Zeichen:now-<input time>
PhiNotPi
1
@PhiNotPi gut gespielt, guter Herr.
Griffin
2
Ist es in Ordnung, "1 Tage bis 16.03.12" zu sagen?
MrZander
1
Wie arbeite ich mit Sprung-Yeras als Antwort? In 10 Jahren wird dann 2 Tage Fehler sein. Wie lang ist der Monat?
Hauleth

Antworten:

3

R, 99 Zeichen

Ich weiß, es ist eine Art Betrug, aber bei R dreht sich alles um seine Pakete und Lubridate ist für diese Art von Aufgaben so praktisch!

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

Verwendung:

f("10/31/2017")
[1] 5 years, 7 months and 16 days 
5 years, 7 months and 16 days  until 10/31/2017
Paolo
quelle
1

PHP, 315 Zeichen

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

Verwendung:

p("11/03/2006");

Nimmt Daten in einem dd/mm/yyyyFormat. Ich habe Griffins Monatslängenberechnung ( wieder ) verwendet, obwohl ich zusätzliche Klammern einfügen musste, damit die Priorität ordnungsgemäß funktioniert. Ich habe auch einige Zeilenumbrüche hinterlassen, um das Lesen zu erleichtern.

Gareth
quelle
1

Rubin (213)

nimmt Daten in jedem Format Date.parseakzeptiert. Versuchte nur mityyyy-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

Um auch Wochen zu bekommen, füge hinzu:

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

und [0,'week'],(zwischen Monat und Tag). Tage werden dann immer sein< 7

jsvnm
quelle
Welche Ruby-Version verwenden Sie? Ich habe versucht, Ihren Code auf ruby1.9.2p0 auszuführen, aber es gibt mir einen Fehler uninitialized constant Object::Date (NameError). Ich denke, Sie verwenden die Rails- DateKlasse
Rohit
@Rohit 1.9.3, ohne Rails-Zeug. Datum rdoc
jsvnm
Ich habe das Dokument früher gesehen. Ich war jedoch verwirrt über den Fehler, den ich erhalten habe. Ich kann immer noch nicht herausfinden, warum ich diesen Fehler erhalte. Ich bin auf Windows 7 64-Bit, Ruby192P0
Rohit
@rohit versuchen mit 193?
jsvnm
1

VBA: 766 631 Zeichen

Vielen Dank an mellamokb für die Verkürzung der String-Erstellung und 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

Ich weiß, dass es sich VBAdefinitiv nicht für das Code-Golfen sowie für einige andere Sprachen eignet, aber ich bin gut darin (kein Experte). :-)

Das war eine lustige Übung für mich!

Gaffi
quelle
1
Es ist nicht ganz VBAs Schuld, es gibt einige gute Möglichkeiten, Logik in Ihrem Code If y > 0 Then a = y & " year,":If y > 1 Then a = y & " years,"zu kombinieren :) Zum Beispiel könnte zusammen kombiniert werdena = y & " year" & Left("s", y - 1) & ","
mellamokb
@ Mellamokb Sehr gut. Ich werde mir das ansehen und neu posten!
Gaffi
Ich hatte ein Problem mit einigen Testfällen, nämlich 1 year, 1 month, 1 day. Ich habe dies in der Antwort korrigiert. Es machte tatsächlich für kürzeren Code!
Gaffi
Und nachdem ich das Update veröffentlicht habe, sehe ich, dass ich zu wechseln kann If v < w Then d = w - v:If v = w Then d = 0, If v <= w Then d = w - vum weitere 20 Zeichen zu sparen. Ich werde die Antwort aktualisieren, wenn ich eine größere Änderung zu posten habe.
Gaffi
Ich kann mir vorstellen, dass ich das mit Arrays besser machen kann ... Ich werde einen weiteren Blick darauf werfen und möglicherweise eine weitere Antwort hinzufügen ...
Gaffi
1

JavaScript (ES6), 125 Byte

Da die Antwort von Paolo eine externe Bibliothek verwendet hat, werde ich dasselbe tun. Bei Node.js dreht sich alles um NPM-Pakete und moment + HumanizeDuration ist für diese Aufgabe so praktisch!

Knotenumgebungen

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

Browser-Umgebung

Da die Bibliotheken globale Variablen deklarieren, ist sie tatsächlich etwas kürzer (102 Byte). Es ist nicht klar, ob ich die zum Laden von JavaScript von Drittanbietern erforderlichen Skript-Tags einfügen muss, daher werde ich den Knoten offiziell zählen.

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

CoffeeScript, auch 125 Bytes

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

PHP, 151 Zeichen

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
quelle
Es fehlen die Pluralformen und es wird nicht richtig gezählt, da format () die Tage nicht von den Monaten subtrahiert ... Ich hatte eine ähnliche Lösung auch mit PHP.
Powtac
Dies ist meine PHP-Lösung, aber es fehlt immer noch der zuvor erwähnte Fehler: echo date_diff(new DateTime(),new DateTime($argv[1]))->format('%yyears, %mmonths, %a days');Es ist 92 Zeichen lang, wenn es über die Befehlszeile aufgerufen wird.
Powtac