• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 7768
  • Last Modified:

Bash check if a string is a date

Hello

Does anyone have an easy way to check if a string is formatted like YYYY-MM-DD?

Thanks for any helps
jculkincys
0
jculkincys
Asked:
jculkincys
  • 5
  • 5
  • 4
  • +1
3 Solutions
 
mightyoneCommented:
$ echo  string  | grep -E 20[0-9][0-9]-0[0-9]\|11\|12-[0-3][0-9]
0
 
mightyoneCommented:
oh little mistake as even days higher 31 will match.

bett5er use this regex

 grep -E 20[0-9][0-9]-0[0-9]\|11\|12-[0-2][0-9]\|30\|31
0
 
xDamoxCommented:
Hi,

you can use the following:

echo 2006-10-10  | grep -c '^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$'

The example was provided by a friend :) znx replace 2006-10-10 with your string
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
jculkincysAuthor Commented:
I think I need to write a fuction to be sure the the month is not above 12 and the day is not above 31
 
I know thats not a perfect solution but it may be the best.

thoughts?
0
 
xDamoxCommented:
Hi,

you could try use:

expr `expr substr 2006-12-12 6 2` \<= 12

the 6 2 means six characters accross and copy 2 that will extract the month and then
compares it to see if its less than or equal to 12 you can do this for month too
0
 
jculkincysAuthor Commented:
That sounds a little promising.

I am a little new to bash - wouldyou mind showing me how that would look if I wanted to test the month and day?

expr `expr substr 2006-12-12 6 2` \<= 12 9 2`\<=31 ???

I guess if that works then I will just find out how to verify that the string is in the format '####-##-##'
0
 
xDamoxCommented:
Hi,

you could do:

#!/bin/bash

echo "Please enter the date"
read -n 10 Date

Month=`expr substr $Date 6 2` && Day=`expr substr $Date 9 2`

export Month Day

if [ `echo $Date  | grep -c '^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$'` -eq 1 ]; then
        if [ $Month -gt 12 ]; then
                echo "Error month over 12"
        fi

        if [ $Day -gt 31 ]; then
                echo "Error day over 31"
        fi
else
        echo "Error invalid date, please enter YYYY-MM-DD"
fi
0
 
Duncan RoeSoftware DeveloperCommented:
You might simply be able to use the date command to verify the syntax. Here's a little test session to show what I mean:

$ cat try
#!/bin/sh
if date -d "$@" >/dev/null 2>&1;then
  echo good date
else
  echo bad date
fi

$ ./try "2004/09/13 13:33:34"
good date

$ ./try "Sat Apr  8 20:04:01 EST 2006"
good date

$ ./try "Sat Foo  33 20:04:01 EST 2006"
bad date

$ ./try "Sat Apr  33 20:04:01 EST 2006"
good date

This validates a variety of date strings that you'd have a lot of trouble doing with regular expressions. Note that date rejects Foo as a month name but allows Apr 33 - it interprets the latter as May 3rd.

0
 
Duncan RoeSoftware DeveloperCommented:
P.S. You can use date's +<format> option to convert the input date to any format you'd like
0
 
mightyoneCommented:
aehm

why didn't you try my second one witch fits all requirements?
0
 
jculkincysAuthor Commented:
Duncan Roe
- What I don't just need to make sure that the input is a date - I need to make sure its in the format 'YYYY-mm-dd'

mightyone
 - sorry for not replying to your posts faster.
- I am still a little new to bash - could you explain in a little more detail what your second one is doing. Would it handle febuary correctly (ex. 28 days) - this is not mandatory but it would be nice.
0
 
xDamoxCommented:
Whats wrong with the one i provided
0
 
mightyoneCommented:
it simply checks.


20[0-9][0-9]           a year between 2000 and 2099
-                            your delimiter
0[0-9]\|11\|12        00 up to twelve for month
-                            your delimiter
[0-2][0-9]\|30\|31  00 up to 31

to match futher
 grep -E 20[0-9][0-9]-[0[1-9]\|10\|11\|12-[0-2][1-9]\|10\|20\|30\|31] will fit the 00 failure
0
 
jculkincysAuthor Commented:
Duncan  

your is nice because it validates all actual dates formats (ie it checks to see if the month is over 12 and the day number is appropriate for the month) However - I only want it to accept dates in the form of YYYY-mm-dd

mightyone
yours is good at validating the YYYY-mm-dd format but it does not deal with Febuary 29th

It looks like I can use a combination

0
 
xDamoxCommented:
Hmmm, I guess your just ignorant. the script I provided carried out your requirements. this is the last reply I am
doing in this post.
0
 
Duncan RoeSoftware DeveloperCommented:
Actually my solution will accept Feb 29th and treat it as Mar 1st on a non-leap year. From your point of view that might be good or it might not.
Others have already given you solutions to validate that input is in the form of ####-##-##.
You could combine the above 2 to get a date which is always legal (use earlier regular expression to validate input format then use date to e.g. convert 2006-02-29 to 2006-03-01)
0
 
jculkincysAuthor Commented:
Wow I guess I rubbed xDamox the wrong way.
I apoligize to him and others for not being a master of bash.

It seems a good way might be to do a grep and then something similar to

#!/bin/sh
if date -d "$@" >/dev/null 2>&1;then
  echo good date
else
  echo bad date
fi

I will test and return with results
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 5
  • 5
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now