2016-04-21 85 views
0

問:如何獲取最新日期爲given_day_of_the_week如何獲取Bash中某個特定日期的最新日期

例子:例如,如果今天是2016年4月21日,我只想得到一個given_day_of_the_week例如Monday這將是2016-04-18的日期。如果代碼明天運行,直到下一個given_day_of_the_week前一天,此日期仍將返回。

說明:代碼應返回最新given_day_of_the_week的(Monday)日起至週日2016年4月24日,然後代碼運行的同位將在2016-04-25下週返回。

+0

擊不包括日期操作功能。你可以使用系統的'date'命令來做你想做的事情,但是這個命令的使用因操作系統而異,而且你沒有提到你使用的是什麼操作系統。另外...你有什麼嘗試?我們大多數人都很樂意幫助你改進自己的技藝,但不願意擔任短期無償編程人員。在[MCVE](http://stackoverflow.com/help/mcve)中向我們展示您的工作,您期待的結果以及您獲得的結果,我們將幫助您弄清楚。 – ghoti

回答

1

需要GNU日期:

today_dow=$(date +%w) 
days=(Sunday Monday Tuesday Wednesday Thursday Friday Saturday) 
for ((dow=0; dow<7; dow++)); do 
    if ((dow < today_dow)); then 
     date -d "last ${days[dow]}" 
    else 
     date -d "${days[dow]}" 
    fi 
done 
Sun Apr 17 00:00:00 EDT 2016 
Mon Apr 18 00:00:00 EDT 2016 
Tue Apr 19 00:00:00 EDT 2016 
Wed Apr 20 00:00:00 EDT 2016 
Thu Apr 21 00:00:00 EDT 2016 
Fri Apr 22 00:00:00 EDT 2016 
Sat Apr 23 00:00:00 EDT 2016 

因此,我們可以這樣做:

given_day_of_the_week() { 
    local days=(Sunday Monday Tuesday Wednesday Thursday Friday Saturday) 
    local today_dow=$(date +%w) 
    local dow datestr 
    for ((dow=0; dow<7; dow++)); do 
     if [[ "${days[dow],,}" == "${1,,}" ]]; then 
      if ((dow < today_dow)); then 
       datestr="last ${days[dow]}" 
      else 
       datestr="${days[dow]}" 
      fi 
      date -d "$datestr" "+%F" 
     fi 
    done 
} 

結果造成:

$ given_day_of_the_week tuesday 
2016-04-19 
$ given_day_of_the_week friday 
2016-04-22 

硬編碼在工作日的名稱一樣,會給你的問題如果你在不同的場所


迴應@ ryenus的評論:

$ given_day_of_the_week() { 
    local -A days=([sunday]=0 [monday]=1 [tuesday]=2 [wednesday]=3 [thursday]=4 [friday]=5 [saturday]=6) 
    local today_dow=$(date +%w) 
    local datestr=${1,,} 
    local dow=${days[$datestr]} 
    [[ -z "$dow" ]] && { echo "error: unknown day: '$1'" >&2; return 1; } 
    ((dow < today_dow)) && datestr="last $datestr" 
    date -d "$datestr" "+%F" 
} 
$ given_day_of_the_week friday 
2016-04-22 
$ given_day_of_the_week monday 
2016-04-18 
$ given_day_of_the_week FOO 
error: unknown day: 'FOO' 
+0

Upvoted!因爲你聰明地使用了'date -d'和'date -d last ...'。 – ryenus

+0

您可能會考慮直接比較day_of_week,而不循環,以決定是否添加最後一個前綴:'[$(date -d monday +%w)-lt $(date +%w)] && date_str_prefix =「last」 ' – ryenus

0

通過@格倫 - 傑克曼的回答啓發,但更簡單:

given_day_of_the_week=$1 
f='%A %Y-%m-%d' 
tomorrow=`date -d 'tomorrow' +"$f"` 
today=`date -d 'today' +"$f"` 
last5=`seq 1 5 | xargs -I{} date -d '{} day ago' +"$f"` 
echo -e "$tomorrow\n$today\n$last5" | 
    grep -i $given_day_of_the_week | 
    cut -d' ' -f2 

注:這個答案確實能給如果用明天的週一日期在星期天。如果在星期一使用,它還會顯示星期二的明天日期。不是100%確定,如果這是你的想法。

相反,如果這個想法是要始終與當前星期天去 - 週六,這將做到這一點:

given_day_of_the_week=$1 
f='%A %Y-%m-%d' 

[ `date +%A` = 'Sunday' ] && first=`date -d 'today' +"$f"` || 
    first=`date -d 'last Sunday' +"$f"` 

rest=`seq 1 6 | xargs -I{} date -d "$first +{} day" +"$f"` 

echo -e "$first\n$rest" | 
    grep -i $given_day_of_the_week | 
    cut -d' ' -f2 
0
# requires bash 4.x and GNU date 
last_kday() { 
    local kday=$1 
    local -A numbers=([sunday]=0 [monday]=1 [tuesday]=2 [wednesday]=3 
        [thursday]=4 [friday]=5 [saturday]=6) 
    if [[ $kday == *day ]]; then 
    kday=${numbers[${kday,,}]} 
    elif [[ $kday != [0-6] ]]; then 
    echo >&2 "Usage: last_kday weekday" 
    return 1 
    fi 

    local today=$(date +%w) 
    local days_ago=$((today - kday)) 
    if ((days_ago < 0)); then let days_ago+=7; fi 
    date -d "$days_ago days ago" +%F 
}