Quanto tempo até essa data?

11

A idéia é a seguinte: Escreva uma função para imprimir o período de tempo a partir de agora / data de hoje (no momento em que a função é chamada) até uma data fornecida como argumento.

Premissas:

  • A data de entrada será sempre amanhã ou mais tarde, no futuro.
  • A data de entrada nunca será superior a 10 anos no futuro.

Regras:

  • A saída deve estar neste formato: "[z ano (s)], [x mês (s)], y dia (s) até -Data de entrada-"
  • O período de saída (dia / mês / ano) deve ser pluralizado corretamente. ou seja 1 month, não1 months
  • A entrada pode estar no formato de data que você preferir (15/3/12 - 15 de março de 2012 - 2012.03.15).

Exemplo: Supondo que o programa seja executado em 15 de março de 2012:

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

Isso é código de golfe, então o código de menor comprimento vence.

Suponho que, por ter um prazo, selecionarei uma resposta em:

23 de março de 2012!

(Esta é a minha primeira pergunta de CG, por isso, ficarei feliz em corrigir quaisquer erros de pergunta da minha parte!)

Gaffi
fonte
3
Wolfram | Alpha 10 caracteres:: now until <input time> p
Griffin
3
@Griffin 4 caracteres:now-<input time>
PhiNotPi
1
@PhiNotPi bem jogado, bom senhor.
Griffin
2
Tudo bem dizer "1 dia até 16/03/12"?
MrZander
1
Como trabalhar com pulos em resposta? Em 10 anos, haverá 2 dias de erro. Quanto tempo dura o mês?
Hauleth 16/03/12

Respostas:

3

R, 99 caracteres

Eu sei que é meio trapaceiro, mas o R é tudo sobre suas embalagens e o lubrificado é tão conveniente para esse tipo de tarefa!

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
fonte
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");

Tira datas em um dd/mm/yyyyformato. Usei o cálculo da duração do mês de Griffin ( novamente ), mas tive que colocar colchetes extras para fazer a precedência funcionar corretamente. Também deixei algumas quebras de linha para facilitar a leitura.

Gareth
fonte
1

Rubi (213)

aceita datas em qualquer formato Date.parseaceita. Tentei apenas comyyyy-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 também receber semanas, adicione:

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

e [0,'week'],(entre mês e dia). dias serão sempre sempre< 7

jsvnm
fonte
qual versão rubi você está usando .... Eu tentei executar o seu código em ruby1.9.2p0, mas dá-me erro uninitialized constant Object::Date (NameError)... Eu acho que você está usando o Rails Dateclasse
Rohit
@Rohit 1.9.3, não usando coisas do Rails. Data rdoc
jsvnm 23/03
Eu vi o documento anteriormente .. mas estava confuso com o erro que estava recebendo ... Ainda não consigo descobrir por que estou recebendo esse erro. Estou no Windows 7 64-bit, ruby192p0
Rohit
@rohit tentar com 193?
Jsvnm
1

VBA: 766 631 caracteres

Obrigado a mellamokb por ajudar a diminuir a criação de strings e 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

Sei que VBAdefinitivamente não se presta ao código do golfe, bem como a alguns outros idiomas, mas é nisso que sou bom (não especialista). :-)

Este foi um exercício divertido para mim!

Gaffi
fonte
1
Não é inteiramente culpa da VBA, existem algumas boas maneiras de combinar a lógica em seu código :) Por exemplo, If y > 0 Then a = y & " year,":If y > 1 Then a = y & " years,"poderiam ser combinados em conjunto paraa = y & " year" & Left("s", y - 1) & ","
mellamokb
@mellamokb Muito bom. Vou dar uma olhada nisso e repassar!
Gaffi
Eu tive um problema com alguns casos de teste, ou seja 1 year, 1 month, 1 day. Eu corrigi isso na resposta. Na verdade, ele criou um código mais curto!
Gaffi
E depois de postar a atualização, eu vejo que eu posso mudar If v < w Then d = w - v:If v = w Then d = 0para If v <= w Then d = w - vpara uma economia de mais 20 caracteres. Atualizarei a resposta se tiver uma alteração mais significativa para postar.
Gaffi
Eu imagino que eu posso fazer isso melhor com matrizes ... Vou dar mais uma olhada e, possivelmente, adicionar outra resposta ...
Gaffi
1

JavaScript (ES6), 125 bytes

Como a resposta de Paolo usou uma biblioteca externa, farei o mesmo. O Node.js tem tudo a ver com pacotes NPM e o momento + HumanizeDuration é tão conveniente para esta tarefa!

Ambientes de nó

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

Ambiente do navegador

Como as bibliotecas declaram variáveis ​​globais, na verdade é um pouco menor (102 bytes). Não está claro se preciso incluir as tags de script necessárias para carregar no JavaScript de terceiros; portanto, contarei o Node oficialmente.

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

CoffeeScript, também 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
fonte
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
fonte
Está faltando o plural e não conta corretamente, porque format () não subtrai os dias dos meses ... Eu também tinha uma solução semelhante com PHP.
Powtac
Esta é a minha solução PHP, mas ainda falta o erro mencionado anteriormente: echo date_diff(new DateTime(),new DateTime($argv[1]))->format('%yyears, %mmonths, %a days');tem 92 caracteres, quando chamado na linha de comando.
Powtac