web-dev-qa-db-fra.com

Date du jour, moins X jours dans le script Shell

Je dois créer trois variables, chacune pour l'année, le mois et le jour pour la date d'aujourd'hui, moins le nombre X de jours. Pour cette question, je choisirai un nombre de jours aléatoire: 222.

Donc si:

TodayYear=`date +%Y`
TodayMonth=`date +%m`
TodayDay=`date +%d`

Ce que je veux, c'est 222 jours avant.

222days_before_TodayYear=???
222days_before_TodayMonth=???
222days_before_TodayDay=???

Edit: Besoin de 222 travail jours au lieu de 222 jours normaux.

28
gcubed

Pour GNU date:

date_222days_before_TodayYear=$(date --date="222 days ago" +"%Y")
date_222days_before_TodayMonth=$(date --date="222 days ago" +"%m")
date_222days_before_TodayDay=$(date --date="222 days ago" +"%d")

Pour BSD date:

Si vous utilisez OS X ou FreeBSD, utilisez plutôt ce qui suit, car la date BSD est différente de la date GNU:

date_222days_before_TodayYear=$(date -j -v-222d +"%Y")
date_222days_before_TodayMonth=$(date -j -v-222d +"%m")
date_222days_before_TodayDay=$(date -j -v-222d +"%d")

Source: Page de manuel de la date BSD

Remarque:

Dans bash et de nombreuses autres langues, vous ne pouvez pas commencer un nom de variable avec un caractère numérique, je les ai donc préfixés avec date_ pour vous.


Deuxième mise à jour: Nouvelle exigence - En utilisant 222 jours ouvrables au lieu de 222 jours normaux:

(Hypothèse: Sans tenir compte des jours fériés, parce que cela dépasse de loin le cadre de ce que je peux vous aider dans un script Shell :)

Considérez 222 jours ouvrables:

  • 5 jours ouvrables par semaine, c'est-à-dire floor(222/5) == 44 weeks
  • 44 weeks * 7 days per week == 308 days
  • Jours supplémentaires restants: 222 % 5 == 2
  • Donc 222 working days == 310 regular days

Mais il ya un hic! Si le nombre de jours normaux est 308 ou un multiple de 7, cela aurait été bien, car tout multiple de 7 jours d'un jour ouvrable est toujours un jour ouvrable. Nous devons donc nous demander si nous sommes aujourd'hui un lundi ou un mardi:

  • Si aujourd'hui est un lundi, nous aurions samedi où nous voulions jeudi
  • Si aujourd'hui est un mardi, nous aurions dimanche où nous voulions vendredi

Vous voyez donc qu'il nous faut une compensation supplémentaire de 2 jours si nous sommes soit lundi ou mardi; alors découvrons-le d'abord avant de procéder:

#!/bin/bash

# Use 310 days as offset instead of 222
offset=310
# Find locale's abbreviated weekday name (e.g., Sun)
today=$(date -j +"%a")
# Check for Mon/Tue
if [[ "$today" == "Mon" ]] || [[ "$today" == "Tue" ]]; then
     offset=$((offset+2))
fi

date_222_working_days_before_TodayYear=$(date -j -v-${offset}d +"%Y")
date_222_working_days_before_TodayMonth=$(date -j -v-${offset}d +"%m")
date_222_working_days_before_TodayDay=$(date -j -v-${offset}d +"%d")

Et cela devrait le faire =)

55
sampson-chen

Vous pouvez obtenir la date exacte de ce qui suit en bash

Number=222
current_date=$(date +%Y%m%d)
past_date=$(date -d "$current_date - $Number days" +%Y%m%d)
echo "$current_date\t$past_date"

J'espère que cela t'aides !

5
Ashish K
date '+%Y' --date='222 days ago'
3
chrisaycock
Epoch=$(( `date '+%s'` - ( 24 * 60 * 60 * 222 ) ))
year=`date -d "@$Epoch" '+%Y'`
month=`date -d "@$Epoch" '+%m'`
day=`date -d "@$Epoch" '+%d'`

Devrait faire l'affaire.

2
djhaskin987

Je dirais qu'une solution plus facile serait 

222days_before_TodayYear = $(date -v -222d +%Y)
222days_before_TodayMonth = $(date -v -222d +%m)
222days_before_TodayDay = $(date -v -222d +%d)
0
ThatComputerGuy