• Status: Solved
• Priority: Medium
• Security: Public
• Views: 1234

# date string - calculate difference

I'm in a real crunch and need some quick help!

I need a Unix script that will read three arguments - the MONTH (3 letters ONLY) the day (number) and year and then calculate the display the number of days between that date and a set date (i.e. Feb 9 1952). I've tried everything I can think of and I keep getting numbers like 124100 days (340 years). Please help!!
0
nrstahl
• 4
• 3
• 2
• +2
1 Solution

Commented:
below script subtracts 15 days from the current date. This logic should really help your problem. I don't have time to modify and send it to u, otherwise I would have done it. Pl. try to modify it. let me know if u still need any help...

Add this below loop to store your month what u have already set:

month_set=\$1
day_set=\$2
year_set=\$3

case \$month_set in
Jan)month_set_no=1;;
Feb)month_set_no=2;;
Mar) ...
Apr) ...
May)
Jun)
Jul)
Aug)
Sep)
Oct)
Nov)
Dec)
esac

#!/bin/sh

# Program to check backup of 15 days old and remove them.

let n=15

# Set the current month day and year.
month=`date +%m`
day=`date +%d`
year=`date +%Y`

# Add 0 to month. This is a
# trick to make month an unpadded integer.
#month=`expr \$month + 0`

# Subtract n from the current day.
day=`expr \$day - \$n`

# While the day is less than or equal to
# 0, decrement the month.
while [ \$day -le 0 ]
do
month=`expr \$month - 1`

# If month is 0 then it is Dec of last year.
if [ \$month -eq 0 ]; then
year=`expr \$year - 1`
month=12
fi

# Add the number of days appropriate to the
# month.
case \$month in
1|3|5|7|8|10|12) day=`expr \$day + 31`;;
4|6|9|11) day=`expr \$day + 30`;;
2)
if [ `expr \$year % 4` -eq 0 ]; then
if [ `expr \$year % 400` -eq 0 ]; then
day=`expr \$day + 29`
elif [ `expr \$year % 100` -eq 0 ]; then
day=`expr \$day + 28`
else
day=`expr \$day + 29`
fi
else
day=`expr \$day + 28`
fi
;;
esac
done

# Print the month day and year.
Date=\$day.\$month.\$year

Regards,
Kusuma
0

Commented:
which calender are you using?
which years (of that calender) are allowed?
how many days do you expect when the other date is the same day?
etc. etc.

anyway I highly recommend that you use perl and its Date::Manip module. Anything else most likely results in cumbersome, not maintaniable solution, or might not work for a lot of examples.
0

Author Commented:
I am still not able to display the correct information. Here's exactly what I need to do:

I need to read in a 3-letter month string (eg. May), a day number (eg. 24), and a 4-digit year (eg. 2004).

Calculate and display the number of days from Sep 9, 1992 to that date (accounting for leap year).

Assumed: No date < Sep 9, 1992 | No date > CurrentYear

\$ ./test Sep 13 1992
4 days

0

Commented:
something like:
perl -MDate::Manip -le 'print &Delta_Format(&DateCalc(&ParseDate("Sep 9 1992"),"-today",\\$e,1),0,"%dh");'
0

Commented:
Simple shell script using date - no error checking or anything...
Input is as decribed (year must be 4 letters)

#!/bin/bash

# converts date to secs from epoch so it's always 100% leap year safe
secs_day=86400     # 60*60*24
ref=\$(date +%s -d "Sep 13 0:00 1992")  # this is the reference date...
new=\$(date +%s -d "\$1 \$2 0:00 \$3")      # input date...

echo \$[ (\$new-\$ref)/\$secs_day] days
0

Commented:
hmm, requires GNU's date
0

Commented:
Me again
A bit safer version of the same - correct date and defaulting to current year
exits if input isn't right

#!/bin/bash

[ \$# -ne 2 -a \$# -ne 3 ] && (echo "usage: \$0 mon dd [yyyy]" && exit 1 )

y=\${3:-""}  # date is "smart" so an empty year equals the current year

# converts date to secs from epoch so it's always 100% leap year safe
secs_day=86400     # 60*60*24
ref=\$(date +%s -d "Sep 9 0:00 1992")  # this is the reference date...
new=\$(date +%s -d "\$1 \$2 0:00 \$y")     # input date...
[ -z "\$old" -o -z "\$new" ] && exit 1          # date conversion failed
echo \$[ (\$new-\$ref)/\$secs_day] days
0

Author Commented:
bytta,

Your script works great! I did need to remove the line if date conversion failed, but after I  did that, it works perfectly. Thank you, Thank you!
0

Commented:
Thanks. One of the first things I learned when programming dates is using secs from epoch.

The error checking may be an overkill, but I prefer them. The test I used works on my debian linux setup (which expands unset variables to "") so I didn't give it much thought.

I don't remember the recommended way to test if a variable is good, but this one here should work in any bash shell:
[ -z \${new:-""} -o -z \${ref:-""} ] && echo exit 1 # error in date

But as I say - it's an overkill.
0

Commented:
[ -z \${new:-""} -o -z \${ref:-""} ] && exit 1
0

## Featured Post

• 4
• 3
• 2
• +2
Tackle projects and never again get stuck behind a technical roadblock.