Как долго до этой даты?

11

Идея заключается в следующем: напишите функцию для печати промежутка времени от текущей / сегодняшней даты (во время вызова функции) до даты, представленной в качестве аргумента.

Предположения:

  • Дата ввода всегда будет завтра или позже, в будущем.
  • Дата ввода никогда не будет более 10 лет в будущем.

Правила:

  • Выходные данные должны быть в следующем формате: "[z year (s)], [x month (s)], y дн (s) до -Input Date-"
  • Выходные временные рамки (день / месяц / год) должны быть правильно умножены. то есть 1 monthне1 months
  • Входные данные могут быть в любом формате даты, который вы предпочитаете (15.03.12 - 15 марта 2012 - 2012.03.15).

Пример: предполагается, что программа запущена 15 марта 2012 года:

  • Дата ввода 3/20/12=5 days until 3/20/12
  • НЕ Введите дату 4/16/12=1 month, 1 days until 3/20/12
  • Дата ввода 2012.04.20=1 month, 5 days until 2012.04.20
  • НЕ Введите дату 2012.04.20=36 days until 2012.04.20
  • Дата ввода 10/31/17=5 years, 7 months, 16 days until 10/31/17
  • Дата ввода 3/15/13=1 year until 3/15/13

Это код гольф, поэтому выигрывает самый короткий код.

Я полагаю, ради крайнего срока, я буду выбирать ответ на:

23 марта 2012 года!

(Это мой первый вопрос компьютерной графики, так что я буду рад исправить любые ошибки с моей стороны!)

Gaffi
источник
3
Wolfram | Альфа 10 символов:: now until <input time> p
Гриффин
3
@ Гриффин 4 символа:now-<input time>
PhiNotPi
1
@PhiNotPi хорошо сыграно, хорошо, сэр.
Гриффин
2
Можно ли сказать «1 день до 16.03.12»?
MrZander
1
Как работать с прыжком в ответ? Через 10 лет тогда будет 2 дня ошибка. Как долго длится месяц?
Хаулет

Ответы:

3

R, 99 символов

Я знаю, что это что-то вроде мошенничества, но R - все о его пакетах, и lubridate настолько удобен для такого рода задач!

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

Использование:

f("10/31/2017")
[1] 5 years, 7 months and 16 days 
5 years, 7 months and 16 days  until 10/31/2017
Paolo
источник
1

PHP, 315 символов

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

Использование:

p("11/03/2006");

Принимает даты в dd/mm/yyyyформате. Я использовал расчет продолжительности месяца Гриффина ( опять же ), хотя мне пришлось добавить в него дополнительные скобки, чтобы приоритет работал правильно. Я также оставил несколько разрывов строк, чтобы их было легче читать.

Gareth
источник
1

Рубин (213)

принимает даты в любом формате Date.parseпринимает. Пробовал только с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}}

и [0,'week'],(между месяцем и днем). дни будут всегда< 7

jsvnm
источник
какую версию ruby ​​вы используете .... Я пытался запустить ваш код на ruby1.9.2p0, но он выдает ошибку uninitialized constant Object::Date (NameError)... Я думаю, вы используете Dateкласс Rails
Rohit
@Rohit 1.9.3, без использования Rails. Дата rdoc
jsvnm
Я видел документ раньше ... но был смущен ошибкой, которую я получаю ... Я все еще не могу понять, почему я получаю эту ошибку. Я на Windows 7 64-разрядной, ruby192p0
Rohit
@ Рохит попробовать с 193?
jsvnm
1

VBA: 766 631 символов

Спасибо mellamokb за помощь в сокращении сроков создания и 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

Я знаю VBA определенно не поддается кодированию в гольф, а также некоторым другим языкам, но это то, в чем я хорош (не эксперт). :-)

Это было забавное упражнение для меня!

Gaffi
источник
1
Это не совсем вина VBA, есть несколько хороших способов объединить логику в вашем коде :) Например, If y > 0 Then a = y & " year,":If y > 1 Then a = y & " years,"можно объединить вместе сa = y & " year" & Left("s", y - 1) & ","
mellamokb
@mellamokb Очень хорошо. Я посмотрю на это и сделаю репост!
Gaffi
У меня была проблема с некоторыми тестовыми, а именно 1 year, 1 month, 1 day. Я исправил это в ответе. Это на самом деле сделано для более короткого кода!
Gaffi
И после публикации обновления я вижу, что могу перейти If v < w Then d = w - v:If v = w Then d = 0на If v <= w Then d = w - vдополнительные 20 символов. Я обновлю ответ, если у меня появятся более существенные изменения в публикации.
Gaffi
Я полагаю, что могу сделать это лучше с массивами ... Я еще раз посмотрю и, возможно, добавлю еще один ответ ...
Gaffi
1

JavaScript (ES6), 125 байт

Поскольку в ответе Паоло использовалась внешняя библиотека, я сделаю то же самое. Node.js - это все о пакетах NPM и момент + HumanizeDuration так удобен для этой задачи!

Узел среды

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

Среда браузера

Поскольку библиотеки объявляют глобальные переменные, на самом деле они немного короче (102 байта). Не ясно, нужно ли мне включать теги скрипта, необходимые для загрузки в сторонний JavaScript, поэтому я буду считать Node one официально.

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

CoffeeScript, также 125 байтов

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

PHP, 151 символ

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));}
Конор
источник
Он пропускает множественное число и не считается правильно, потому что format () не вычитает дни из месяцев ... У меня было похожее решение и с PHP.
Powtac
Это моё PHP-решение, но все еще не хватает ранее упомянутой ошибки: echo date_diff(new DateTime(),new DateTime($argv[1]))->format('%yyears, %mmonths, %a days');его длина 92 символа при вызове из командной строки.
Powtac