Tom's Guide | Tom's Hardware | Tom's Games | PC Safety Suite
![]() |
![]() |
![]() |
Comment:
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!
+1 | ![]() |
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
+1 | ![]() |
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!
+1 | ![]() |
hi again!
i have the following output when i run the above script.
-36000
31496400
+ (end - s1970)/86400+
uribo
+1 | ![]() |
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!
+1 | ![]() |
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
+1 | ![]() |
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
+1 | ![]() |
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!)
+1 | ![]() |
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
+1 | ![]() |
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?
+1 | ![]() |
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
+1 | ![]() |
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
![]() |
grab any two files!
|
xargs for a ONE line comm...
|

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