¿Cuánto tiempo hasta esta fecha?

11

La idea es esta: escriba una función para imprimir el período de tiempo desde ahora / fecha actual (en el momento en que se llama a la función) hasta una fecha proporcionada como argumento.

Suposiciones

  • La fecha de entrada siempre será mañana o más tarde, en el futuro.
  • La fecha de entrada nunca será más de 10 años en el futuro.

Reglas:

  • La salida debe estar en este formato: "[z año (s)], [x mes (es)], y día (s) hasta -Fecha de entrada-"
  • El marco de tiempo de salida (día / mes / año) debe estar pluralizado correctamente. es decir 1 month, no1 months
  • La entrada puede estar en el formato de fecha que prefiera (15/03/12 - 15 marzo 2012 - 2012.03.15).

Ejemplo: suponiendo que el programa se ejecute el 15 de marzo de 2012:

  • Fecha de entrada de 3/20/12=5 days until 3/20/12
  • NO Fecha de entrada de 4/16/12=1 month, 1 days until 3/20/12
  • Fecha de entrada de 2012.04.20=1 month, 5 days until 2012.04.20
  • NO Fecha de entrada de 2012.04.20=36 days until 2012.04.20
  • Fecha de entrada de 10/31/17=5 years, 7 months, 16 days until 10/31/17
  • Fecha de entrada de 3/15/13=1 year until 3/15/13

Este es el código de golf, por lo que gana el código de longitud más corta.

Supongo que por tener una fecha límite, seleccionaré una respuesta sobre:

23 de marzo de 2012!

(Esta es mi primera pregunta de CG, ¡así que estaré encantado de corregir cualquier error de mi parte!)

Gaffi
fuente
3
Wolfram | Alpha 10 chars:: now until <input time> p
Griffin
3
@Griffin 4 caracteres:now-<input time>
PhiNotPi
1
@PhiNotPi bien jugado, buen señor.
Griffin
2
¿Está bien decir "1 días hasta el 16/03/12"?
MrZander
1
¿Cómo trabajar con Leap Yeras en respuesta? En 10 años habrá un error de 2 días. ¿Cuánto dura el mes?
Hauleth

Respuestas:

3

R, 99 caracteres

Sé que es una especie de trampa, pero R se trata de sus paquetes y ¡ lubridate es muy conveniente para este tipo de tareas!

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

Uso:

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

PHP, 315 caracteres

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

Uso:

p("11/03/2006");

Toma fechas en un dd/mm/yyyyformato. He usado el cálculo de la duración del mes de Griffin (de nuevo ), aunque tuve que ponerle corchetes adicionales para que la prioridad funcionara correctamente. También he dejado algunos saltos de línea para que sea un poco más fácil de leer.

Gareth
fuente
1

Rubí (213)

toma fechas en cualquier formato Date.parseacepta. Intenté solo conyyyy-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

para obtener también semanas, agregue:

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

y [0,'week'],(entre mes y día). los días siempre serán< 7

jsvnm
fuente
qué versión de ruby ​​estás usando ... Traté de ejecutar tu código en ruby1.9.2p0, pero me da un error uninitialized constant Object::Date (NameError)... Creo que estás usando la Dateclase Rails
Rohit
@Rohit 1.9.3, sin usar material de Rails. Fecha rdoc
jsvnm
Vi el documento antes ... pero estaba confundido con el error que estaba recibiendo ... Todavía no puedo entender por qué recibo este error. Estoy en Windows 7 de 64 bits, ruby192p0
Rohit
@rohit prueba con 193?
jsvnm
1

VBA: 766 631 Caracteres

Gracias a mellamokb por ayudar a acortar la creación de cadenas y 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

Sé que VBAdefinitivamente no se presta al golf de código tan bien como a otros idiomas, pero es en lo que soy bueno (no experto). :-)

¡Este ha sido un ejercicio divertido para mí!

Gaffi
fuente
1
No es completamente culpa de VBA, hay algunas buenas maneras de combinar la lógica en su código :) Por ejemplo, If y > 0 Then a = y & " year,":If y > 1 Then a = y & " years,"podría combinarse paraa = y & " year" & Left("s", y - 1) & ","
mellamokb
@mellamokb Muy bien. ¡Echaré un vistazo a eso y volveré a publicar!
Gaffi
Tenía un problema con algunos casos de prueba, a saber 1 year, 1 month, 1 day. He corregido esto en la respuesta. ¡Realmente hizo un código más corto!
Gaffi
Y después de publicar la actualización, veo que puedo cambiar If v < w Then d = w - v:If v = w Then d = 0a If v <= w Then d = w - vun ahorro de 20 caracteres adicionales. Actualizaré la respuesta si tengo un cambio más significativo para publicar.
Gaffi
Me imagino que puedo hacerlo mejor con las matrices ... Voy a echar otro vistazo y posiblemente
agregaré
1

JavaScript (ES6), 125 bytes

Como la respuesta de Paolo usó una biblioteca externa, haré lo mismo. Node.js se trata de paquetes NPM y moment + HumanizeDuration es muy conveniente para esta tarea.

Entornos de nodo

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

Entorno del navegador

Como las bibliotecas declaran variables globales, en realidad es un poco más corto (102 bytes). No está claro si necesito incluir las etiquetas de secuencia de comandos necesarias para cargar en el JavaScript de terceros, por lo que contaré oficialmente el Nodo.

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

CoffeeScript, también 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
fuente
1

PHP, 151 caracteres

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
fuente
Le faltan los plurales y no cuenta correctamente, porque format () no resta los días de los meses ... También tuve una solución similar con PHP.
powtac
Esta es mi solución PHP, pero aún carece del error mencionado anteriormente: echo date_diff(new DateTime(),new DateTime($argv[1]))->format('%yyears, %mmonths, %a days');tiene 92 caracteres de largo, cuando se llama en la línea de comando.
powtac