Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
how can i get the current date, convert to no. of days since Jan 1 1970. & the result is to compare against the "last changed" field in /etc/shadow to ensure the "last changed" occurs in the past.
thanks for any help!

Uribo:
Date arthmetic with classic unix tools (non-GNU tools) is difficult. I'm not much of a Perl programmer, but I did throw this function together that returns the number of seconds from the Epoch:
#!/bin/ksh
# This function takes a date time string of the format:
# YYYY MM DD HH MM SS
# perl autosplits the string and uses timelocal to return
# the number of seconds from the Epoch.
# No error checking!
function seconds_from_epoch {
echo $*| perl -MTime::Local -ane '
my $epochseconds = timelocal($F[5], $F[4], $F[3], $F[2], $F[1] - 1, $F[0]);
print "$epochseconds\n"; '
}s1970=$(seconds_from_epoch "1970 1 1 0 0 0")
echo $s1970end=$(seconds_from_epoch "1971 1 1 0 0 0")
echo $enddiff=$(((end - s1970)/86400))
echo $diff # 365 days for this example
# end scriptThere's 86,400 seconds in a day. the above example is integer arithmetic only, so it doesn't return a decimal part of a day if you choose not to use midnight as the time.
If you don't have Perl, there are other solutions, but they're not very nice.
Regards,
nails

im using bourne shell. what are the functions for converting date into string? or is there any function that will give me the difference in days between two dates? thanks!

hi again!
i have the following output when i run the above script.
-36000
31496400
+ (end - s1970)/86400+
uribo

hi, can i do this?
# Set the current month day and year.
month=`date +%m`
day=`date +%d`
year=`date +%Y`# Subtract Jan 1 1970 from the current day.
day=`expr $day - 1`
month=`expr $month - 1`
year=`expr $year - 1970`# If the day is 0 then determine the last
# day of the previous month.
if [ $day -eq 0 ]; then
# Find the preivous month.
month=`expr $month - 1`# If the month is 0 then it is Dec 31 of
# the previous year.
if [ $month -eq 0 ]; then
month=12
day=31
year=`expr $year - 1`# If the month is not zero we need to find
# the last day of the month.
else
case $month in
1|3|5|7|8|10|12) day=31;;
4|6|9|11) day=30;;
2)
if [ `expr $year % 4` -eq 0 ]; then
if [ `expr $year % 400` -eq 0 ]; then
day=29
elif [ `expr $year % 100` -eq 0 ]; then
day=28
else
day=29
fi
else
day=28
fi ;;
esac
fi
fi# Print the month day and year, ignoring leap year.
echo $month $day $yearcount_month=`expr $month \* 30`
count_year=`expr $year \* 365`
total=`expr $count_month + $count_year + $day`
echo $total
exit 0
how can i refine my script to count days more accurately? the month i used 30 days & years 365.
thanks!

Hi:
In Bourne shell, functions are defined and integer arithmetic is performed differently from ksh. Here is my original submission modified for sh:
#!/bin/sh
# This function takes a date time string of the format:
# YYYY MM DD HH MM SS
# perl autosplits the string and uses timelocal to return
# the number of seconds from the Epoch.
# No error checking!
seconds_from_epoch () {
echo $*| perl -MTime::Local -ane '
my $epochseconds = timelocal($F[5], $F[4], $F[3], $F[2], $F[1] - 1, $F[0]);
print "$epochseconds\n"; '
}s1970=`seconds_from_epoch "1970 1 1 0 0 0"`
echo $s1970end=`seconds_from_epoch "1971 1 1 0 0 0"`
echo $endnosecs=`expr $end - $s1970`
diff=`expr $nosecs / 86400`
echo $diff # 365 days for this exampleRegards,
nails

The following replaces my perl solution. It's based on Scaliger's Julian date algorithm. See the US Naval Observator link below for more information.
Regards,
Nails
#!/bin/sh
# Scaliger's Julian date (JD) is a continuous count of days from 1 January
# 4713 BC. The following algorithm is good from years 1801 to 2099
# See URL:http://aa.usno.navy.mil/faq/docs/JD_Formula.html for
# more information. arguments are
# day, month, year
get_JD () {
# calculation below is all on one line.
# Also the bc calcuator is being called with a unix "here" document, so you need 2 less than arrows between bc and MSG. This forum wipes them out:
bc MSG
scale=0
$1-32075+1461*($3+4800+($2-14)/12)/4+367*($2-2-($2-14)/12*12)/12-3*(($3+4900+($2-14)/12)/100)/4
MSG
}jd1970=`get_JD 1 1 1970`
jd1971=`get_JD 1 1 1971`
diff=`expr $jd1971 - $jd1970`
echo $diff # still 365 days

hi nails,
1 more qn:
is linux using julian day? the code works very well, giving me 12482 days since jan 1 1970 till today (apr 15 2003)
but when im using this: expr `date +%s` / 86400
gives me the result of 12157 daysand when i do these:
date +%D -d "1 January 1970 + 12157 days"
gives me 04/15/03date +%D -d "1 January 1970 + 12482 days"
gives me 03/05/04 (next year date!)

jd1970=`get_JD 1 1 1970`
jd2003=`get_JD 15 4 2003`
diff=`expr $jd2003 - $jd1970`
echo $diff # it's 12157It's DAY MONTH YEAR for the arguments
You get the incorrect 12482 when you transpose the month and day.
Regards,
Nails

hi nails,
yes... i got it!
thanks for analysing my mistake!but if i have the function expr `date +%s` / 86400 which gives me the correct number of days, in which situation would i need to use the rather complex function instead?

Hi:
In my initial response, I said classic, non-GNU tools wasn't good at date arthmetic. 'date +%s' is the GNU date. Use the GNU tools if you have them else you're forced to use something else.
Also, I have a companion function which converts Julian Days to a gregorian date, mm/dd/yyyy.Regards,
nails

is there an equivalent of date +%D -d "1 January 1970 + 12157 days" so that it will work under unix? since unix doesn't accept -d option

![]() |
![]() |
![]() |

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |