Display dates within a given date range


 
Thread Tools Search this Thread
# 1  
Display dates within a given date range

Hi All,

I have a requirement to display all the dates within the provided (through user input) date range.

For eg: If I enter 28012009 (as From date in the format 'DDMMYYYY') and 02022009(as To date in the format 'DDMMYYYY'), the output should be all dates occuring between the from and to dates:

28012009
29012009
30012009
31012009
01022009
02022009

I have devised the logic to ensure that:

1. the from and to dates are numerals only and not characters (thanks to this forum for that!).
2. the to date is always greater than the from date.
3. the format of the from and to dates are 'DDMMYYYY'.

However, I am stuck at this point. I am not sure how to devise the logic for getting the list of dates.

Any suggestions/tips?

TIA,

Regards,

Praveen
# 2  
If you rearrange the order to YYYYMMDD you can use the date as a long integer.
One way to do this.
Code:
# compar reaanage and compare dates
# returns 0 if in the range 
#         -1 if below the lower bound, 
#         1 if above the upper bound
compar()
{
    echo "$1 $2 $3" |\
	awk 'function rearrange( mySTRING ){
	       return  substr(mySTRING,5) substr(mySTRING,3,2) substr(mySTRING, 1,2)
	     }
	     { one=rearrange($1)
	       two=rearrange($2)
	       three=rearrange($3)
	       if(three > one) {print 1; exit}
	       if(three < two) { print -1; exit}
	       print 0
	     } '
}

a=01312009
b=12012008
c=01012009

if [[  $(compar "$a" "$b" "$c") -eq 0 ]] ; then 
    echo "$c is in the range between $a and $b"
else
    echo "not in date range"
fi

# 3  
Well, your date format is a problem...

In ksh, you can use this case statement to verify (somewhat) the correct date format:

Code:
#----------------------------------------------------------------------#
# Check user input for dates in DDMMCCYY format.                       #
#----------------------------------------------------------------------#
check_ddmmccyy()
{
ddmmccyy=$1

case $ddmmccyy in

#----------------------------------------------------------------------#
# Does some really basic date checking...                              #
#----------------------------------------------------------------------#
  [0-3][0-9][0-9][0-2][12][0-9][0-9][0-9]) return 0 ;;
  *) return 1 ;;

esac
}


But to do a comparision of the 2 values, you need to reformat them into:
CCYYMMDD format...

So why not just ask for the data in that format to begin with?
Or ask for the input data in this format:

CCYY/MM/DD

So it's easier to parse, and verify and all that?

At any rate, what SHELL are you using?
# 4  
Quote:
Originally Posted by jim mcnamara
If you rearrange the order to YYYYMMDD you can use the date as a long integer.
One way to do this.
Code:
# compar reaanage and compare dates
# returns 0 if in the range 
#         -1 if below the lower bound, 
#         1 if above the upper bound
compar()
{
    echo "$1 $2 $3" |\
    awk 'function rearrange( mySTRING ){
           return  substr(mySTRING,5) substr(mySTRING,3,2) substr(mySTRING, 1,2)
         }
         { one=rearrange($1)
           two=rearrange($2)
           three=rearrange($3)
           if(three > one) {print 1; exit}
           if(three < two) { print -1; exit}
           print 0
         } '
}
 
a=01312009
b=12012008
c=01012009
 
if [[  $(compar "$a" "$b" "$c") -eq 0 ]] ; then 
    echo "$c is in the range between $a and $b"
else
    echo "not in date range"
fi

Jim, you seem to have misunderstood my requirement. My requirement is to accept From and To dates from the user and DISPLAY all the dates that fall within that range.

For eg., if the user inputs

From date: 01012009 (Format - 'DDMMYYYY')
To Date: 05012009 (Format - 'DDMMYYYY')

then I have to display all the dates between the 1st of Jan 2009 to the 5th of Jan 2009 (as shown below):

01012009 (from date)
02012009
03012009
04012009
05012009 (to date)

@quirkasaurus, I am using bash but I can also use ksh.

To reiterate, I have devised the logic to ensure that:

1. the from and to dates are numerals only and not characters (thanks to this forum for that!).
2. the to date is always greater than the from date.
3. the format of the from and to dates are 'DDMMYYYY'.

However, I am unable to devise the logic to get the list of dates that fall within the given range.


TIA,

Regards,

Praveen

Last edited by sunpraveen; 01-29-2009 at 02:26 AM..
# 5  
My 2 cents:

Quote:
1. the from and to dates are numerals only and not characters (thanks to this forum for that!).
2. the to date is always greater than the from date.
Is that so?
Look what you wrote:
Quote:
I enter 28012009 (as From date in the format 'DDMMYYYY') and 02022009...
Since when 02022009 greater than 28012009 ?

So if left in numeric it should be YYYYMMDD...
# 6  
Solution for generating dates between given dates

I believe this shell script will solve the problem. I was hoping for any UNIX built in functions to do the job. Because there is no point in reinventing the wheel. Please feel free to cut short my algorithm for a better code. And if there is any built in functions please inform me.

Currently the output is in DDMMYY format. if you want it in DDMMYYYY format just edit the below line in the code & remove the 'cut' section.

year=`echo $3 | cut -c3-4`

Thanks for all the support from the UNIX forum members
1. The script cecho will echo the output in color so if you dont have cecho replace it by echo. I believe i got cecho from someone in UNIX Forum.
2. The anflg is my script to check whether the date contains alphabetic or alphanumeric characters. You can comment the calls to validation functions to bypass calls to external scripts, but make sure the input is in correct format.
3. The real algorithm lies in the last for loop, Generate Dates . This for loop will take the dates from unix cal function and generates the date

The name for the source code in gendt and run them as

gendt <From date> <To date>

Bye. SmilieSmilie

HTML Code:
# gendt - DATE GENERATOR WITHIN THE GIVEN RANGE
#
# USAGE
#
# gendt <From> <To>
#
# Note: 1. The date must be in DDMMYYYY format
#    2. The <From> date must be smaller than <To> date
#        Ex: dt 30012009 28022009
#    3. The output is in DDMMYY format
#     4. Invalid month days like 300209 (feb has 28 days) & 310408 
#       are corrected automatically by the script
#
# MAINTENANCE HISTORY 
# DATE        AUTHOR AND DETAILS
# 30-01-09    BAS     TR - ORIGINAL 
#
#----------------------------------------------------------------------------79 

frmDate=$1
toDate=$2

# Basic data check
dateChk1() {
    
    len=`echo $1 | wc -c`
    len=`expr $len - 1`

    if [ $len -ne 8 ]; then
        cecho green "Invalid date length (DDMMYYYY)."
        exit
    fi
    
    alpNumFlg=`anflg "$1" "AN"`
    alpFlg=`anflg "$1" "AT"`
    
    finFlg=`expr $alpNumFlg + $alpFlg`
    if [ "$finFlg" != "0" ]; then
        cecho green "$1 is not a number"
        exit
    fi
        
}


dateChk1 "$frmDate"
dateChk1 "$toDate"

# Basic date validation
dateChk2 () {

    case $2 in
        "M")                    
            if [ $1 -le  12 ]; then                        
                if [ $1 -le 0 ]; then                                    
                    cecho green "$1 is an invalid month (1-12)"
                    exit
                fi
            else
                cecho green "$1 is an invalid month (1-12)"
                exit
            fi
            ;;
        "D")
            if [ $1 -le 31 ]; then
                if [ $1 -le 0 ]; then
                    cecho green "Day value $1 must be within (1-31)"
                    exit
                fi
            else
                cecho green "Day value $1 must be within (1-31)"
                exit
                
            fi
            ;;

        "Y")
            if [ $1 -le 0 ]; then
                cecho green "$1 is an invalid year."
                exit
            fi
            ;;
    esac
}

frmDtDay=`echo $frmDate | cut -c1-2`
frmDtMon=`echo $frmDate | cut -c3-4 | tr -d 0`
frmDtYer=`echo $frmDate | cut -c5-8`

toDtDay=`echo $toDate | cut -c1-2`
toDtMon=`echo $toDate | cut -c3-4 | tr -d 0`
toDtYer=`echo $toDate | cut -c5-8`

dateChk2 "$frmDtDay" "D"
dateChk2 "$frmDtMon" "M"
dateChk2 "$frmDtYer" "Y"
dateChk2 "$toDtDay" "D"
dateChk2 "$toDtMon" "M"
dateChk2 "$toDtYer" "Y"

# Make any D & M day,month formats to DD,MM respectively
dateFill() {

    val="$1"    
    dtLen=`echo "$val" | wc -c`
    dtLen=`expr $dtLen - 1`
    if [ $dtLen -lt 2 ]; then
        val="0$1"    
    fi
    return $val
}

yerDiff=`expr $toDtYer - $frmDtYer`
if [ $yerDiff -lt 0 ]; then
    cecho green "Date $frmDate must be less than date $toDate."
    exit
fi

# Display the date in DDMMYY format
datDisp () {

    dateFill $1
    dayTmp=$val
    dateFill $2
    monTmp=$val
    year=`echo $3 | cut -c3-4`    
    echo "$dayTmp$monTmp$year"
}

# Generate dates
for y in $(seq $frmDtYer $toDtYer); do
    for m in $(seq 1 12); do        
        dtGenIni=`cal $m $y | grep -v [A-z] | tr -s ' ' '\n'`
        for d in $dtGenIni; do
                                
            day=$d
            # same year
            if [ $y -eq $toDtYer ]; then
                # same month
                if [ $m -eq $toDtMon ]; then
                    # same day
                    if [ $day -eq $toDtDay ]; then
                        # if all the above, print the same BAS-BAS-BAS day
                        datDisp $day $m $y
                    # different days
                    else                    
                        # print days between From & To Days
                        if [ $day -ge $frmDtDay ]; then
                            if [ $day -le $toDtDay ]; then
                                datDisp $day $m $y                                
                            fi
                        fi                    
                    fi
                # different months
                else
                    # print days between From & To Months                    
                    if [ $m -ge $frmDtMon ]; then                                
                        if [ $m -le $toDtMon ]; then
                            # if curent month is From or To, 
                            # remove dates outside the range                            
                            if [ $m -eq $frmDtMon ]; then
                                if [ $day -ge $frmDtDay ]; then                                    
                                    datDisp $day $m $y
                                fi
                            else
                                    datDisp $day $m $y
                            fi
                        fi
                    fi
                fi    
    
            # different year    
            else
                # print the days between the From & To Years
                if [ $y -ge $frmDtYer ]; then
                    if [ $y -le $toDtYer ]; then
                        # check for same From year
                        if [ $y -eq $frmDtYer ]; then
                            # check for same month
                            if [ $m -eq $frmDtMon ]; then
                                if [ $day -ge $frmDtDay ]; then
                                    datDisp $day $m $y
                                        
                                fi                                
                            fi
                        fi
                        # check for same To Year
                        if [ $y -eq $toDtYer ]; then
                            # check for same month
                            if [ $m -eq $toDtMon ]; then
                                datDisp $day $m $y
                            fi                    
                        else
                            # simply print other dates within the range
                            datDisp $day $m $y
                        fi                    
                    fi    
                fi
            fi                                    
        
        done
    done
done
# 7  
@forzensmilz,

Thanks for providing the logic and the script! Smilie

What is "seq"? Is it a function that you have written? Smilie

Thanks once again.

Regards,

Praveen
 

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

Test Your Knowledge in Computers #198
Difficulty: Easy
Bash ranked in the top 20 programming languages according to the TIOBE Index for October 2019.
True or False?

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Display dates between two dates

Hi All, I have 2 dates in mm/dd format. sdate=10/01 (October 01) edate=10/10 (October 10) I need the dates in between these 2 dates like below. 10/01 10/02 10/03 10/04 10/05 10/06 10/07 10/08 (1 Reply)
Discussion started by: jayadanabalan
1 Replies

2. Shell Programming and Scripting

Display lines of two date range from syslog file

Hi Guys, I want to display lines from Solaris syslog file but with 2 dates range. I have some similar solution (https://www.unix.com/shell-programming-scripting/39293-grep-log-file-between-2-dates-4.html) which works fine but as you know syslog has different date format (Jan 22) so this is not... (1 Reply)
Discussion started by: prashant2507198
1 Replies

3. Shell Programming and Scripting

Display data from a range of dates

I have a data in a file called SCHED which has 5 columns: sched no, date, time, place and remarks. The image is shown below. http://dl.dropbox.com/u/54949888/Screenshot%20from%202013-01-02%2002%3A42%3A25.png Now, I want to display only the schedules which fall under a certain date range which... (2 Replies)
Discussion started by: angilulu
2 Replies

4. Shell Programming and Scripting

display Range of date depend on user input php

Hi, i am very new to php Is it possible to display Range of date depend on user input day example: user input 2 day start from 28/4/12 it will add 2 day from date of input so display should look like this 28/4/12 to 30/4/12 then from 30/412 user add another 4 date so will... (0 Replies)
Discussion started by: guidely
0 Replies

5. Emergency UNIX and Linux Support

show div on select - range of dates

Hi, I am sure this is simple, but I am breaking my head. I need 1 page with at the top a range of dates, 2002, 2003, 2004 etc If you select 2002 it will show the content of 1 div, if you select 2002 the content of another div. this is for showing announcements on a site, right now there... (1 Reply)
Discussion started by: lawstudent
1 Replies

6. Shell Programming and Scripting

Using 'date' to list a range of dates

Hi guys, I have been trying to create a list of dates from a certain range, ie. range from 01011950 to 31122000 But when my below code reaches certain dates, it comes up with a; 'date: invalid date 'yyyy-mm-dd -d 1day' Sofar I have come up with the following, slow and ugly; ... (4 Replies)
Discussion started by: TAPE
4 Replies

7. Shell Programming and Scripting

pull range of dates/times and put into new file

Need to pull from a range of dates/times (ex. 6:00 AM March 3 through 6:00 AM March 4) from a folder and put those file names in a new file to process later. Dates would not be hard dates but dates from the folder directory, how would I do that? (9 Replies)
Discussion started by: freddie999
9 Replies

8. Shell Programming and Scripting

Display the last five dates from the given date

Hi all, In Oracle we have got sysdate -1 to find the previous date. Is there any similar way to display date in unix shell scripting? Kindly help me to display the last five dates from the given date Thanks, Geetha (11 Replies)
Discussion started by: iamgeethuj
11 Replies

9. Shell Programming and Scripting

display the file with in the date range

Hi All, I want a shell script which can display the file with in the date range. For Example I have 15 files with the following format abc_01-01-2009.txt to abc_15-01-2009.txt. Now I want to have the files between 4th of jan to 12th files. How can I acheive this. Advance... (1 Reply)
Discussion started by: fareed_do
1 Replies

10. UNIX for Dummies Questions & Answers

How to display files that have been modifed between a given date range

Hi, I am new to Unix and was trying different ways of how to display the list of file names modified between a given date range in sorting order.I will get the fromdate and Todate from the browser, I need to display the list of all the file names that are modified between the given date... (1 Reply)
Discussion started by: prathima
1 Replies

Featured Tech Videos