I have rather basic task but wasn't able to find proper solution to it.I want to iterate date interval since 2008 to current and need epoch values for each iteration of the loop. I am interested in iterating both years, halves and months as well.I wrote such script #!/bin/bashinitial_date=`date -d 2008-02-04 00:00:00 UTC +%s`end_date=`date +%s`n=0until [ $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`donebut its output is rather weird to me:1202083200 2008-02-04 00:00:00 1233702000 2009-02-03 23:00:00  1265230800 2010-02-03 21:00:00 1296756000 2011-02-03 18:00:00  1328277600 2012-02-03 15:00:00 1359885600 2013-02-03 11:00:00  1391403600 2014-02-03 06:00:00 1422918000 2015-02-02 23:00:00  1454425200 2016-02-02 15:00:00Why the year is not incremented properly? Shifted hours seems to me a side-effect of unix>>UTC>>unix conversion.Is there any direct (without reconversion) method for doing this?P.S.And yes, I checked this, this and this question and found no clear way of doing this. All they are based on incrementing number and converting date with the help of it which doesn't seem precise to me.And yes, I thought about adding 60*60*24*30*365 to initial date but would it be correct? This approach doesn't consider leap years, months comprised of 31 days and so on.   
Looping through unix dates
bash;shell script;shell;scripting;timestamps
Date used:$ dateA=2008-02-04 00:00:00 UTCThe first reason to get dates with shifted times is to request local dates:$ date -d $dateASun Feb  3 19:00:00 EST 2008Which will be corrected if you specify a UTC time:$ TZ=UTC0 date -d $dateAMon Feb  4 00:00:00 UTC 2008Or better (make an habit of using it) use the -u option of date:$ date -ud $dateAMon Feb  4 00:00:00 UTC 2008A second reason is to request relative items with a sign:$ date -ud $(date +%Y-%m-%d %T -ud $dateA) +1 year  ### wrongTue Feb  3 23:00:00 UTC 2009$ date -ud $(date +%Y-%m-%d %T -ud $dateA) 1 year  ### betterMon Feb  4 00:00:00 UTC 2008But all the time problems (usually) go away when a time zone (-z) is used:$ date -ud $(date +%Y-%m-%d %T %z -ud $dateA) +1 year  ### BestWed Feb  4 00:00:00 UTC 2009$ date -ud $(date +%Y-%m-%d %T %z -ud $dateA) 1 year  ### PreferredWed Feb  4 00:00:00 UTC 2009The issue is related to the way a date string is parsed, if the TZ value is missing, the +1 may be interpreted as a Time Zone value:$ date -ud 2008-02-04 00:00:00 +3 yearTue Feb  3 21:00:00 UTC 2009Even if an environment value for TZ has been set:$ TZ=UTC0 date -ud 2008-02-04 00:00:00 +3 yearTue Feb  3 21:00:00 UTC 2009Yes, the year was incresed once (2009 instead of 2008) but the +3 was used for a change of the time presented (not what was intended).I repeat: the problem is that the +3 may be parsed as a Time Zone value.Also, to convert (epoch) seconds to dates, GNU date may use @$ dateAsec=$( date -ud $dateA +%s )$ date -ud @$dateAsecMon Feb  4 00:00:00 UTC 2008The script (using a (newdate) function) could be written like this:#!/bin/bashdateI=$(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=0while     dateN=$( newdate $n )    (( dateN < dateF ));do    dateNhuman=$(date +%Y-%m-%d %T %z -ud @$dateN)    echo dateN=$dateN --- $dateNhuman ---> $dateF $(( $dateF - $dateN )) $n    (( n++ ))doneResults:dateN=1202083200 --- 2008-02-04 00:00:00 +0000 ---> 1470543626 268460426 0dateN=1233705600 --- 2009-02-04 00:00:00 +0000 ---> 1470543626 236838026 1dateN=1265241600 --- 2010-02-04 00:00:00 +0000 ---> 1470543626 205302026 2dateN=1296777600 --- 2011-02-04 00:00:00 +0000 ---> 1470543626 173766026 3dateN=1328313600 --- 2012-02-04 00:00:00 +0000 ---> 1470543626 142230026 4dateN=1359936000 --- 2013-02-04 00:00:00 +0000 ---> 1470543626 110607626 5dateN=1391472000 --- 2014-02-04 00:00:00 +0000 ---> 1470543626 79071626 6dateN=1423008000 --- 2015-02-04 00:00:00 +0000 ---> 1470543626 47535626 7dateN=1454544000 --- 2016-02-04 00:00:00 +0000 ---> 1470543626 15999626 8All years appear and all seems correct.