Bash

如何將日期從a增加到b?

  • October 5, 2021

我有 2 個日期,start=20190903並且end=20210912 想要增加直到開始接近結束,增量是 13 天。

有以下程式碼,但它超出了結尾。

#! /usr/bin/env bash

start="20190903"
end="20210912"

startdate="$(date -d ${start} +'%Y-%m-%d')"
enddate="$(date -d ${end} +'%Y-%m-%d')"
echo ${startdate}
echo ${enddate}

while [ "${startdate}" < "${enddate}" ]; do
   echo ${startdate}
   startdate="$( date -d "${startdate} + 13 days" +'%Y-%m-%d')"
done

擴展比利叔叔的評論,[是一個正常命令,所以你使用的<是標準輸入重定向。如果您沒有收到bash: line 9: 2021-09-12: No such file or directory錯誤,很可能是您之前使用>. 如果是這樣的話,那麼

[ "${startdate}" < "${enddate}" ]

評估與

[ "${startdate}" ]

只要$startdate不是未設置或為空,它就是真實的。所以,你有一個無限循環。

更改為[[使用

while [[ "${startdate}" < "${enddate}" ]]; do

解決了這個問題,因為這是一種特殊的形式,它有自己的語法而不是正常命令,並且</>不會被解析為重定向。

編輯:[[是一種 bash 主義。如果您希望[它與 POSIX 兼容,您可以使用-lt. 但是,由於這樣做是進行數字比較而不是像字典那樣進行比較<,因此您必須-從日期格式中刪除 s :

#!/bin/sh

startdate="20190903"
enddate="20210912"

echo ${startdate}
echo ${enddate}

while [ "${startdate}" -lt "${enddate}" ]; do
   echo ${startdate}
   startdate="$( date -d "${startdate} + 13 days" +'%Y%m%d')"
done

在您的情況下,通過這樣的更改,您最終得到的程式碼更少,因為您不再需要start變成startdate和相同的end/ enddate

編輯 2:另一種選擇似乎是<像 in 一樣轉義[ "${startdate}" \< "${enddate}" ],但這似乎只適用於 bash。它不是 POSIX,至少在 zsh 上失敗了。

通過startdate+interval與 end 進行比較,您可以防止執行它。

#!/bin/bash

start="20190903"
end="20210912"
interval=1123200
   # 13 days = 13 * 24 * 60 *60

startdate=$( date --utc -d ${start} +%s )
enddate=$( date --utc -d ${end} +%s )

echo "$( date --utc -d @${startdate} +"%Y-%m-%d" ) (start)"
next=${startdate}
while [[ "$(( next+interval ))" -lt "${enddate}" ]] ; do
   next=$(( next+interval ))
   nextdate=$( date --utc -d @${next} +"%Y-%m-%d" )
   echo "${nextdate}"
done
echo "$( date --utc -d @${enddate} +"%Y-%m-%d" ) (end)"

我不確定你添加 13 天的方式,所以我從 1970 年 1 月 1 日起將其更改為秒。至少現在你知道了另一種方法。

引用自:https://unix.stackexchange.com/questions/671628