Я часто хочу сделать некоторые быстрые вычисления даты, такие как:
- В чем разница между этими двумя датами?
- Какая дата n недель после этой другой даты?
Я обычно открываю календарь и считаю дни, но я думаю, что должна быть программа / скрипт, который я мог бы использовать для таких вычислений. Какие-либо предложения?
Ответы:
«N недель после даты» легко с датой GNU (1):
Я не знаю простого способа вычисления разницы между двумя датами, но вы можете немного обдумать дату (1) с помощью функции оболочки.
Поменяйте местами
d1
и,d2
если вы хотите, чтобы вычисление даты происходило иначе, или сделайте немного интереснее, чтобы это не имело значения. Кроме того, в случае перехода не-DST к DST в этом интервале один из дней будет длиться всего 23 часа; Вы можете компенсировать, добавив ½ дня к сумме.источник
Для набора портативных инструментов попробуйте мой собственный dateutils . Ваши два примера будут сводиться к одной строке:
или в неделях и днях:
а также
источник
dateadd -i '%m%d%Y' 01012015 +1d
, кажется, не работает, он просто висит там неопределенно долго ... он работает, если спецификации даты разделены символом, любым символом ... есть идеи, что случилось?)Пример Python для расчета количества дней, которые я прошел по планете:
источник
ychaouche@ychaouche-PC ~ $ python -c "from datetime import date as d; print (d.today() - d(1980, 6, 14)).days"
12813
ychaouche@ychaouche-PC ~ $
Я обычно предпочитаю иметь время / дату в формате unix utime (количество секунд с начала эпохи семидесятых до UTC). Таким образом, это всегда сводится к простому вычитанию или сложению секунд.
Обычно проблема заключается в преобразовании даты / времени в этот формат.
В оболочке / скрипте вы можете получить его с помощью
date '+%s'
На момент написания, текущее время1321358027
.Сравнивать с 2011-11-04 (мой день рождения)
date '+%s' -d 2011-11-04
, уступая1320361200
. Вычесть:expr 1321358027 - 1320361200
дает996827
секунды, чтоexpr 996827 / 86400
= 11 дней назад.Преобразование из utime (формат 1320361200) в дату очень просто сделать, например, в C, PHP или perl, используя стандартные библиотеки. В GNU
date
к-d
аргументу можно добавить префикс@
«секунды с начала эпохи».источник
date -d @1234567890
конвертирует из секунд с начала эпохи в любой формат даты, который вы укажете.info date
, В частности, секунды, прошедшие с узла « Эпоха» : «Если перед числом стоит` @ ', он представляетЕсли вам подходит графический инструмент, я искренне рекомендую
qalculate
(калькулятор с акцентом на преобразование единиц, он поставляется с интерфейсом GTK и KDE, IIRC). Там вы можете сказать, например,чтобы получить количество дней (140, с 1900 года не было високосным годом) между датами, но, конечно, вы можете сделать то же самое для времен:
дают
8.4591667
часы или, если вы установите выход на время форматирования8:27:33
.источник
qalc
тогдаhelp days
.qcalc
пример:qalc -t 'days(1900-05-21, 1900-01-01)'
-> 140Это возникло при использовании,
date -d "$death_date - $y years - $m months - $d days"
чтобы получить дату рождения (для генеалогии). Эта команда НЕПРАВИЛЬНА. Месяцы не имеют одинаковую длину, поэтому(date + offset) - offset != date
. Возраст в году / месяце / дне - это показатели, идущие вперед от даты рождения.Дата дает правильный вывод в обоих случаях, но во втором случае вы задавали неправильный вопрос. Это имеет значение, КОТОРЫЕ 11 месяцев в году охватывают +/- 11, прежде чем добавлять / вычитать дни. Например:
Чтобы вычитание было обратной операцией сложения, порядок операций должен быть обратным. Добавление добавляет лет, ТОГДА месяцев, ТОГДА дней. Если вычитание использовало противоположный порядок, то вы вернетесь к исходной точке. Это не так, так что нет, если смещение дней пересекает границу месяца в другом месяце длины.
Если вам нужно работать в обратном направлении с конечной даты и возраста, вы можете сделать это с помощью нескольких вызовов
date
. Сначала вычтите дни, затем месяцы, а затем годы. (Я не думаю, что безопасно объединять годы и месяцы в одномdate
вызове, потому что високосные годы меняют продолжительность февраля.)источник
Другой способ рассчитать разницу между двумя датами одного и того же календарного года, вы можете использовать это:
date
переменной DATEfirstnum.-d
Флаг отображает строку в формате времени в этом случае 14 мая 2014 года и+"%j"
говоритdate
форматировать вывод только на день года (1-365).DAYSdif
разности двух дней.DAYSdif
.Это работает с версией GNU
date
, но не с версией PC-BSD / FreeBSD. Я установилcoreutils
из дерева портов и использовал команду/usr/local/bin/gdate
вместо этого.источник
DATEfirstnum=$(date -d "$1" +%s)
DATElastnum=$(date -d "$2" +%s)
Кроме того, этот скрипт не сможет рассчитать разницу между двумя разными годами.+%j
относится к дню года (001..366), поэтому./date_difference.sh 12/31/2001 12/30/2014
выводит -1. Как уже отмечалось в других ответах, вам нужно конвертировать обе даты в секунды с 1970-01-01 00:00:00 UTC.$
внутри арифметического выражения:$((DATElastnum - DATEfirstnum))
также будет работать.Я часто использую SQL для вычисления даты. Например, MySQL , PostgreSQL или SQLite :
В других случаях я просто в настроении для JavaScript. Например, SpiderMonkey , WebKit , Seed или Node.js :
(Будьте осторожны при передаче месяца в
Date
конструктор объекта JavaScript . Начинается с 0.)источник
С помощью решений dannas это можно сделать в одну строку с помощью следующего кода:
(Работает как в Python 2.x, так и в Python 3.)
источник
date
и bash может делать различия даты (показаны параметры OS X). Поместите последнюю дату первой.источник
Также есть расчеты времени блока GNU в сочетании с датой GNU:
(gunits это единицы в Linux, gdate это дата)
источник
datediff.sh на github: gist
источник
Ответ camh заботится о большей части этого, но мы можем улучшить работу с округлением, часовыми поясами и т. д., плюс мы получаем дополнительную точность и возможность выбирать наши юниты:
-d
говорит,date
что мы предоставляем дату-время для конвертации.+%s.%N
изменяет дату и время на seconds.nanoseconds с 1970-01-01 00:00:00 UTC.bc
вычисляет разницу между двумя числами, а коэффициент деления дает нам различные единицы.printf
добавляет 0 перед десятичной запятой, если необходимо (bc
не делает), и обеспечивает округление до ближайшего (bc
только усекает). Вы также можете использоватьawk
.Теперь давайте запустим это с помощью классного теста,
Обратите внимание, что, поскольку длина месяца или года не всегда одинакова, здесь нет ни одного «правильного» ответа, хотя в настоящее время можно использовать 365,24 дня в качестве разумного приближения.
источник
Вы можете использовать библиотеку awk Velor :
Или же:
Результат:
источник