16

I am new to linux. How can I print and store date in given date range.

For example I have startdate=2013-03-01 and enddate = 2013-03-25 ; I want to print all date in that range.

Thanks in advance

0

7 Answers 7

20

As long as the dates are in YYYY-MM-DD format, you can compare them lexicographically, and let date do the calendar arithmetic without converting to seconds first:

startdate=2013-03-15 enddate=2013-04-14 curr="$startdate" while true; do echo "$curr" [ "$curr" \< "$enddate" ] || break curr=$( date +%Y-%m-%d --date "$curr +1 day" ) done 

With [ ... ], you need to escape the < to avoid confusion with the input redirection operator.

This does have the wart of printing the start date if it is greater than the end date.

Sign up to request clarification or add additional context in comments.

2 Comments

So, just do the echo "$curr" after the test ;). date --date "$curr +1 day" is nicer than the let cur=..
It's probably better to put this in a for loop rather than a while loop to be safe. If you parameterize your startdate and enddate within a script, with the loop running max of say 366 times or 1000 times. This will keep it from infinitely looping.
11

An alternate if you want 'recent' dates is:

echo {100..1} | xargs -I{} -d ' ' date --date={}' days ago' +"%Y-%m-%d" 

Obviously won't work for arbitrary date ranges.

1 Comment

this is close of the best answer I think, I made a change with it: $ startdate='2016-03-01'; echo {0..10} | xargs -I{} -d ' ' date --date="$startdate +"{}" days" +"%Y-%m-%d" 2016-03-01 2016-03-02 2016-03-03 ....
9

Another option is to use dateseq from dateutils (http://www.fresse.org/dateutils/#dateseq):

$ dateseq 2013-03-01 2013-03-25 2013-03-01 2013-03-02 2013-03-03 2013-03-04 2013-03-05 2013-03-06 2013-03-07 2013-03-08 2013-03-09 2013-03-10 2013-03-11 2013-03-12 2013-03-13 2013-03-14 2013-03-15 2013-03-16 2013-03-17 2013-03-18 2013-03-19 2013-03-20 2013-03-21 2013-03-22 2013-03-23 2013-03-24 2013-03-25 

1 Comment

Nice! In Vim: :read ! dateseq 2018-12-04 2019-12-31. :read appends output to current buffer (file); ! executes the external (BASH) command (dateseq ...).
3

Use date to convert your dates to seconds, do a little maths and convert back:

#/bin/bash dstart=2013-03-01 dend=2013-03-25 # convert in seconds sinch the epoch: start=$(date -d$dstart +%s) end=$(date -d$dend +%s) cur=$start while [ $cur -le $end ]; do # convert seconds to date: date -d@$cur +%Y-%m-%d let cur+=24*60*60 done 

See man date for more info on date parameters..

Comments

1

Slightly improved version

#!/bin/bash startdate=2013-03-15 enddate=2013-04-14 curr="$startdate" while true; do [ "$curr" \< "$enddate" ] || { echo "$curr"; break; } echo "$curr" curr=$( date +%Y-%m-%d --date "$curr +1 day" ) done 

Comments

1

one line version:

seq 0 24 | xargs -I {} date +"%Y-%m-%d" -d '20130301 {}day' # this version is ok if the dates not cross next month seq -f'%.f' 20130301 20130325 

1 Comment

Please add further details to expand on your answer, such as working code or documentation citations.
0

A simple demo

start_date="20191021" end_date="20191025" dates=() while [[ "${start_date}" != "${end_date}" ]];do formatted_date=$(date -d "${start_date}" +"%Y%m%d") dates+=( "${formatted_date}" ) start_date=$(date -d "$start_date +1 day" +"%Y%m%d") done 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.