Отримайте дату останнього дня минулого місяця в сценарії оболонки


11

Як отримати дату закінчення попереднього місяця на основі дати обробки?

Приклади:

  • Дата обробки = 15jan2015
  • Очікувана дата = 31 декабря 2014 року,

  • Дата обробки = 10feb2015
  • Очікувана дата = 31jan2015

Відповіді:


27

З GNU date:

$ date +%d%b%Y
16Aug2015
$ date -d "$(date +%Y-%m-01) -1 day" +%d%b%Y
31Jul2015

Деякі оболонки мають вбудовану підтримку для маніпулювання датою:

З ksh93:

$ printf "%(%d%b%Y)T\n" "1st day, yesterday"
31Jul2015

З zsh:

$ zmodload zsh/datetime
$ strftime -s d %Y-%m-01-12 $EPOCHSECONDS
$ strftime -rs d %Y-%m-%d-%H $d
$ strftime %d%b%Y $((d-86400))
31Jul2015

4

Існує маса способів зробити це; ось найпростіший з них, який я знайшов (тут припускаючи GNU date):

$ date -d "-$(date +%d) days"
Fri Jul 31 16:07:23 EDT 2015

1
Відповідь @stephane зрозуміліша, і ця не спрацює в якісь дивні роки, коли дні пропускаються / додаються в середині місяця. Так, це сталося. дивіться youtube.com/watch?v=-5wpm-gesOY
ctrl-alt-delor

@richard, шлях GNU дати дня Корекція робота (1 день зміщення не так же , як 24 години один), я думаю , що ця відповідь і мої повинен бути еквівалентні і тільки не в часових поясах , які стрибають в останній день місяця ( як правило, якщо це коли-небудь траплялося, можливо, на якомусь тихому острові було б перехід на зміщення до -12: 00 до зміщення до 12:00 (або -13 до 11 ...) ...
Стефан Шазелас

@Stephane дякую за вказівку на інші проблеми, час важкий. Зауважте у своєму рішенні, якщо середина місяця вилучена (це сталося), то день 30 не є 30-м днем, тому віднімання 30 не приведе вас до останнього дня попереднього місяця. Я не можу зрозуміти, чому ця робота не працює, якщо є перший день місяця (не гарантується). Однак це не означає, що це буде.
ctrl-alt-delor

@richard, Див TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '1 day ago'. Ви отримуєте помилку, оскільки там не було 2011-12-30. Тобто зсув дня робився на календарний час. 2011-12-31 мінус 31 день дає вам 2011-11-30, оскільки це займає 31 off. Це не займе 31 * 24 * 60 * 60 * 60 секунд від поточного часу. Порівняйте, з TZ=Pacific/Apia faketime '2011-12-31 12:00' date -d '24 hour ago'якою ви отримуєте 29-ту, тобто цього разу дату, яка була 24 * 60 * 60 * 60 секунд тому.
Стефан Шазелас

2

Ось версія, яка працює на Mac OS, яка використовує dateутиліту BSD :

date -v1d -v-1d +%d%b%Y

Аргументи застосовуються в порядку. Ви можете собі уявити, що дата переходить від одного аргументу до іншого. Наприклад:

  • Почніть з поточної дати ( date) -> 2017-03-06
  • Встановіть цю дату на 1-й день свого місяця ( -v1d) -> 2017-03-01
  • Відніміть один день від цього ( -v-1d)-> 2017-02-28
  • Відформатуйте дату ( +%d%b%Y) -> 28Feb2017

Ви можете дістатися до будь-якої кількості місяців вперед або назад , використовуючи date -v-1m -v1d -v-1d, замінивши -1mз числом місяців тому або вперед ( +1m) ви хочете.

Це загальна відповідь. Це питання конкретно задає дати щодо дати початку. Утиліта дати Mac OS / BSD не дозволяє вам поставити марку дати для початку, але ви можете встановити кожен елемент дати окремо:

date -v2015y -v1m -v15d -v1d -v-1d +%d%b%Y -> 31дек2014


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.