私にはかなり基本的な仕事がありますが、それに対する適切な解決策を見つけることができませんでした。 2008年から現在までの日付間隔を繰り返し、ループの繰り返しごとにエポック値が必要です。年、半分、月の両方を繰り返すことに興味があります。
私はそのようなスクリプトを書きました
#!/bin/bash
initial_date=`date -d "2008-02-04 00:00:00 UTC" +%s`
end_date=`date +%s`
n=0
until [ $initial_date -gt $end_date ]; do
echo $initial_date
let n+=1
readable_date=`date +"%Y-%m-%d %T" -d "1970-01-01 $initial_date sec"`
echo $readable_date
readable_date=`date -d "$readable_date + $n year"`
initial_date=`date -d "$readable_date" +%s`
done
しかし、その出力は私にはかなり奇妙です:
1202083200
2008-02-0400:00:00
1233702000
2009-02-0323:00:00
1265230800
2010-02-0321:00:00
1296756000
2011-02-0318:00:00
1328277600
2012-02-0315:00:00
1359885600
2013-02-0311:00:00
1391403600
2014-02-0306:00:00
1422918000
2015-02-0223:00:00
1454425200
2016-02-0215:00:00
年が適切にインクリメントされないのはなぜですか?時間のずれは、unix >> UTC >> unix変換の副作用のように思えます。これを行うための直接的な(再変換なしの)方法はありますか?
PS
はい、 this 、 this 、 this の質問を確認しましたが、明確な方法が見つかりませんでした。それらはすべて、数字を増やし、日付を変換することに基づいていますが、それは私には正確ではないようです。
はい、最初の日付に60*60*24*30*365
を追加することを考えましたが、正しいでしょうか?このアプローチでは、うるう年、31日で構成される月などは考慮されません。
使用日:
$ dateA="2008-02-04 00:00:00 UTC"
時間のずれた日付を取得する最初の理由は、「ローカル」日付を要求することです。
$ date -d "$dateA"
Sun Feb 3 19:00:00 EST 2008
UTC時刻を指定すると、どちらが修正されますか。
$ TZ=UTC0 date -d "$dateA"
Mon Feb 4 00:00:00 UTC 2008
または、日付の-u
オプションを使用する(使用する習慣をつける)ことをお勧めします。
$ date -ud "$dateA"
Mon Feb 4 00:00:00 UTC 2008
2番目の理由は、記号付きの「相対アイテム」を要求することです。
$ date -ud "$(date +"%Y-%m-%d %T" -ud "$dateA") +1 year" ### wrong
Tue Feb 3 23:00:00 UTC 2009
$ date -ud "$(date +"%Y-%m-%d %T" -ud "$dateA") 1 year" ### better
Mon Feb 4 00:00:00 UTC 2008
ただし、「タイムゾーン」(-z)を使用すると、(通常は)すべての時間の問題が解消されます。
$ date -ud "$(date +"%Y-%m-%d %T %z" -ud "$dateA") +1 year" ### Best
Wed Feb 4 00:00:00 UTC 2009
$ date -ud "$(date +"%Y-%m-%d %T %z" -ud "$dateA") 1 year" ### Preferred
Wed Feb 4 00:00:00 UTC 2009
この問題は、日付文字列の解析方法に関連しています。TZ値が欠落している場合、+ 1はタイムゾーン値として解釈される可能性があります。
$ date -ud "2008-02-04 00:00:00 +3 year"
Tue Feb 3 21:00:00 UTC 2009
TZの環境値が設定されている場合でも、次のようになります。
$ TZ=UTC0 date -ud "2008-02-04 00:00:00 +3 year"
Tue Feb 3 21:00:00 UTC 2009
はい、年は増加しました1回(2008ではなく2009)が、+3
は提示された時間の変更に使用されました(意図されたものではありません)。
繰り返しますが、問題は、+3
がタイムゾーン値として解析される可能性があることです。
また、(Epoch)秒を日付に変換するには、GNU dateは "@"を使用できます
$ dateAsec="$( date -ud "$dateA" +"%s" )
$ date -ud @"$dateAsec"
Mon Feb 4 00:00:00 UTC 2008
スクリプト((newdate)関数を使用)は次のように記述できます。
#!/bin/bash
dateI="$(date -ud "2008-02-04 00:00:00 UTC" +%s)"
dateF="$(date -u +%s)"
newdate(){ date -ud "$(date +"%Y-%m-%d %T %z" -ud @"$dateI") $1 year" +"%s"; }
n=0
while
dateN="$( newdate "$n" )"
(( dateN < dateF ));
do
dateNhuman="$(date +"%Y-%m-%d %T %z" -ud @"$dateN")"
echo "dateN=$dateN --- $dateNhuman ---> $dateF $(( $dateF - $dateN )) $n"
(( n++ ))
done
結果:
dateN=1202083200 --- 2008-02-04 00:00:00 +0000 ---> 1470543626 268460426 0
dateN=1233705600 --- 2009-02-04 00:00:00 +0000 ---> 1470543626 236838026 1
dateN=1265241600 --- 2010-02-04 00:00:00 +0000 ---> 1470543626 205302026 2
dateN=1296777600 --- 2011-02-04 00:00:00 +0000 ---> 1470543626 173766026 3
dateN=1328313600 --- 2012-02-04 00:00:00 +0000 ---> 1470543626 142230026 4
dateN=1359936000 --- 2013-02-04 00:00:00 +0000 ---> 1470543626 110607626 5
dateN=1391472000 --- 2014-02-04 00:00:00 +0000 ---> 1470543626 79071626 6
dateN=1423008000 --- 2015-02-04 00:00:00 +0000 ---> 1470543626 47535626 7
dateN=1454544000 --- 2016-02-04 00:00:00 +0000 ---> 1470543626 15999626 8
すべての年が表示され、すべてが正しいようです。
開始点からの 相対日付 のイテレータの方が理にかなっている場合があります。
#!/usr/bin/env bash
START='2008-02-04 00:00:00 UTC'
END=$( date +%s )
for yearnum in $( seq 1 999 ); do
NUDATE=$( date -d "$START + $yearnum year" +%s )
PUNY_HUMAN_DATE=$( date -d "@$NUDATE" "+%Y-%m-%d %T %Z" )
if [[ $NUDATE -gt $END ]]; then
break
fi
echo $NUDATE $PUNY_HUMAN_DATE
done
その結果、次のようになります。
-bash-4.1$ bash iter
1233705600 2009-02-04 00:00:00 UTC
1265241600 2010-02-04 00:00:00 UTC
1296777600 2011-02-04 00:00:00 UTC
1328313600 2012-02-04 00:00:00 UTC
1359936000 2013-02-04 00:00:00 UTC
1391472000 2014-02-04 00:00:00 UTC
1423008000 2015-02-04 00:00:00 UTC
1454544000 2016-02-04 00:00:00 UTC
-bash-4.1$