Computing.Net > Forums > Unix > count days since jan 1 1970

Computer Problems? Computing.Net has over 1,000,000 posts about all things technology related! Click here to start participating now! Also, check out the New User Guide.

count days since jan 1 1970

Reply to Message Icon

Name: uribo
Date: April 10, 2003 at 23:58:53 Pacific
OS: Solaris
CPU/Ram: n.a.
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!





Response Number 1
Name: nails
Date: April 11, 2003 at 12:56:43 Pacific
+1
Reply:

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 $s1970

end=$(seconds_from_epoch "1971 1 1 0 0 0")
echo $end

diff=$(((end - s1970)/86400))
echo $diff # 365 days for this example
# end script

There'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



Response Number 2
Name: uribo
Date: April 11, 2003 at 22:08:33 Pacific
+1
Reply:

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!



Response Number 3
Name: uribo
Date: April 11, 2003 at 23:09:02 Pacific
+1
Reply:

hi again!

i have the following output when i run the above script.

-36000
31496400
+ (end - s1970)/86400+


uribo




Response Number 4
Name: uribo
Date: April 12, 2003 at 08:11:08 Pacific
+1
Reply:

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 $year

count_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!



Response Number 5
Name: nails
Date: April 12, 2003 at 09:34:52 Pacific
+1
Reply:

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 $s1970

end=`seconds_from_epoch "1971 1 1 0 0 0"`
echo $end

nosecs=`expr $end - $s1970`
diff=`expr $nosecs / 86400`
echo $diff # 365 days for this example

Regards,

nails



Related Posts

See More



Response Number 6
Name: uribo
Date: April 13, 2003 at 20:22:06 Pacific
+1
Reply:

i must use only bourne shell. any advice on the above code? thanks.



Response Number 7
Name: nails
Date: April 14, 2003 at 07:57:43 Pacific
+1
Reply:

The above is only Bourne shell. Are you saying you don't have Perl?

Nails



Response Number 8
Name: uribo
Date: April 14, 2003 at 19:40:12 Pacific
+1
Reply:

that's right. i don't have perl :(



Response Number 9
Name: nails
Date: April 14, 2003 at 21:40:10 Pacific
+1
Reply:

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



Response Number 10
Name: uribo
Date: April 14, 2003 at 22:11:39 Pacific
+1
Reply:

thanks very much for yur help, nails!



Response Number 11
Name: uribo
Date: April 14, 2003 at 22:38:50 Pacific
+1
Reply:

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 days

and when i do these:
date +%D -d "1 January 1970 + 12157 days"
gives me 04/15/03

date +%D -d "1 January 1970 + 12482 days"
gives me 03/05/04 (next year date!)



Response Number 12
Name: nails
Date: April 15, 2003 at 15:15:27 Pacific
+1
Reply:


jd1970=`get_JD 1 1 1970`
jd2003=`get_JD 15 4 2003`
diff=`expr $jd2003 - $jd1970`
echo $diff # it's 12157

It's DAY MONTH YEAR for the arguments

You get the incorrect 12482 when you transpose the month and day.

Regards,


Nails



Response Number 13
Name: uribo
Date: April 15, 2003 at 22:23:39 Pacific
+1
Reply:

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?



Response Number 14
Name: nails
Date: April 16, 2003 at 06:29:01 Pacific
+1
Reply:

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



Response Number 15
Name: uribo
Date: April 16, 2003 at 06:39:41 Pacific
+1
Reply:

thanks very much for all yur help, nails!
the learning process is sure interesting! :)



Response Number 16
Name: vartmp
Date: May 1, 2003 at 06:46:12 Pacific
+1
Reply:

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



Reply to Message Icon

grab any two files! xargs for a ONE line comm...



Post Locked

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


Go to Unix Forum Home


Google Ads



Results for: count days since jan 1 1970

Getting old date into variable www.computing.net/answers/unix/getting-old-date-into-variable/5223.html

/etc/passwd & /etc/shadow file www.computing.net/answers/unix/etcpasswd-amp-etcshadow-file/4895.html

December 31, 1969 www.computing.net/answers/unix/december-31-1969-/6650.html