Today's date, minus X days in shell script

后端 未结 5 2002
小鲜肉
小鲜肉 2020-12-08 09:25

I need to create three variables, each for Year, Month, and Day for Today\'s date, minus X number of days. For this question I\'ll choose a random amount of days: 222.

相关标签:
5条回答
  • 2020-12-08 10:03

    For 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")
    

    For BSD date::

    If you are using OS X or FreeBSD, use the following instead because BSD date is different from GNU date:

    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: BSD date manual page

    Note:

    In bash and many other languages, you cannot start a variable name with a numerical character, so I prefixed them with date_ for you.


    Second Update: New requirement - Using 222 Working days instead of 222 Regular days:

    (Assumption: Not considering statutory holidays, because that just gets far beyond the scope of what I can help you with in a shell script:)

    Consider 222 working days:

    • 5 working days per week, that is floor(222/5) == 44 weeks
    • 44 weeks * 7 days per week == 308 days
    • Extra days leftover: 222 % 5 == 2
    • Therefore 222 working days == 310 regular days

    But, there is a catch! If the number of regular days is 308 or some multiple of 7, then we would have been fine, because any multiple of 7-days ago from a working day is still a working day. So we need to consider whether today is a Monday or a Tuesday:

    • If today is a Monday, we'd get Saturday where we wanted Thursday
    • If today is a Tuesday, we'd get Sunday where we wanted Friday

    So you see we need an additional offset of 2 more days if today is either Monday or Tuesday; so let's find that out first before we proceed:

    #!/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")
    

    And that should do it =)

    0 讨论(0)
  • 2020-12-08 10:07

    I would say easier solution would be

    222days_before_TodayYear = $(date -v -222d +%Y)
    222days_before_TodayMonth = $(date -v -222d +%m)
    222days_before_TodayDay = $(date -v -222d +%d)
    
    0 讨论(0)
  • 2020-12-08 10:08
    epoch=$(( `date '+%s'` - ( 24 * 60 * 60 * 222 ) ))
    year=`date -d "@$epoch" '+%Y'`
    month=`date -d "@$epoch" '+%m'`
    day=`date -d "@$epoch" '+%d'`
    

    Should do the trick.

    0 讨论(0)
  • 2020-12-08 10:13

    You can get exact past date from the following in 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"
    

    Hope this helps !

    0 讨论(0)
  • 2020-12-08 10:20
    date '+%Y' --date='222 days ago'
    
    0 讨论(0)
提交回复
热议问题