LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (https://www.linuxquestions.org/questions/slackware-14/)
-   -   A program to compute number of days between two dates? (https://www.linuxquestions.org/questions/slackware-14/a-program-to-compute-number-of-days-between-two-dates-4175454050/)

stf92 03-14-2013 08:31 AM

A program to compute number of days between two dates?
 
Hi:

I mean, does slackware include one in his distributions? In the affirmative case I would like to know its name.

colucix 03-14-2013 08:37 AM

You don't really need a program. In bash you can try something like:
Code:

echo $(( ($(date -ud 20130331 +%s) - $(date -ud 20130314 +%s))/86400 ))
The code might be transformed to a shell function that accepts the two dates as arguments. Just my :twocents:.

stf92 03-14-2013 09:32 AM

I'll try it, thanks. Though I do not think, if I want to compute difference between April 7, 1784 and today it will work.

Habitual 03-14-2013 10:13 AM

Just another example. :)
Code:

echo $((($(date +%s)-$(date +%s -d "April 7, 1784"))/86400)) days
83616 days.

but ("it's always something"))...
Code:

echo $((($(date +%s -d "March 14, 2013")-$(date +%s -d "April 7, 1784"))/86400)) days.
83615 days.

1 day can make a difference!

stf92 03-14-2013 10:19 AM

Oh I see. It's all built into the date command. It has to give date in days, starting from some predetermined date! 2000 was a weird year. As it is divisible by 100, it should not have been leap year. However, it is divisible by 400 too. So an exception is made and the year is not a lear year! But I did not see this commented on the newspapers.

Habitual 03-14-2013 11:00 AM

I love date math and the awe inspiring feeling I get when it works. Giddy.

Anyway, anything significant about April 7, 1784, if I may ask?

subscribed with interest...

Code:

xmas ()
{
    Christmas=$(date --date="2013-12-25" +%j);
    dayofyear=$(date +%j);
    echo "There are $(($Christmas-$dayofyear)) days until Christmas."
}

but there's a bug. ;)

stf92 03-14-2013 11:30 AM

Yes, the satisfaction one gets when one sees the program working is unrivaled. The first job they gave me when I began working at a certain software firm was to write a program to compute number of days between dates. It was the epoch of minicomputers, PDP-11 for instance.

I chose 1784 not to go before 1600, because I was not sure about the year the Gregorian reform began and did not want to give a pre-Gregorian date as an example. I guess the bug is in the date command?

T3slider 03-14-2013 11:53 AM

I don't believe it is a bug -- it is a rounding error. If you explicitly pass two dates then you will get the correct difference since it will assume 00:00, whereas if you just get the difference from the current time it might be half a day or more off, which would round improperly. I think though that bash rounds by cutting off the decimal point so it isn't the most accurate.
Code:

echo "($(date +%s)-($(date -d "April 7 1784" +%s)))/86400" | bc -l
would give you an unrounded value from the current day/time, though
Code:

echo "($(date -d "March 14" +%s)-($(date -d "April 7 1784" +%s)))/86400" | bc -l
is probably still better.

saulgoode 03-14-2013 01:02 PM

Quote:

Originally Posted by stf92 (Post 4911562)
I chose 1784 not to go before 1600, because I was not sure about the year the Gregorian reform began and did not want to give a pre-Gregorian date as an example. I guess the bug is in the date command?

For Britain (and the U.S.), the switch took place in September of 1752. The 'cal' command gets this right:
Code:

$ cal 9 1752
  September 1752 
Su Mo Tu We Th Fr Sa
      1  2 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

The 'date' command doesn't seem to account for this:
Code:

$ echo $(($(date --date="1752-9-14" +%s)/-86400)) days ago
79365 days ago
$ echo $(($(date --date="1752-9-2" +%s)/-86400)) days ago
79377 days ago


GazL 03-14-2013 01:11 PM

I like playing with this sort of stuff too.

Instead of use date, I rolled my own.
Code:

gazl@ws1:/var/tmp$ cat days.sh
#/bin/bash

YEAR=$1
MONTH=$2
DAY=$3

function leapyear()
{
  local leapyear
  local year="$1"

  if ! ((year % 400)); then
    leapyear=0
  elif ! ((year % 100)); then
    leapyear=1
  elif ! ((year % 4)); then
    leapyear=0
  else
    leapyear=1
  fi 
 
  return $leapyear
}


if leapyear $YEAR ; then
  MONTHDAYS=( 0 31 60 91 121 152 182 213 244 274 305 335 )
else
  MONTHDAYS=( 0 31 59 90 120 151 181 212 243 273 304 334 )
fi


DAYS=$(( ((YEAR-1)*365) + (YEAR-1)/4 - (YEAR-1)/100 + (YEAR-1)/400 ))
DAYS=$(( DAYS + MONTHDAYS[MONTH-1] ))
DAYS=$(( DAYS + DAY - 1))


echo "$DAYS complete since the beginning (start of 1AD)"

Note: it's zero not one based (i.e. Jan 1st 1AD is day 0).

Code:

gazl@ws1:/var/tmp$ ./days.sh 2013 3 14
734940 complete since the beginning (start of 1AD)
gazl@ws1:/var/tmp$ ./days.sh 1784 4 7
651324 complete since the beginning (start of 1AD)
gazl@ws1:/var/tmp$ echo $(( 734940 - 651324 ))
83616

Glad to see I got the same number of days. :)

Didier Spaier 03-14-2013 01:27 PM

Still waiting for solution working since year 1 (Julian then Gregorian calendars).

I've done that as an exercise in Cobol long ago (circa 1977, IIRC :-)

Batch processing of Hollerith punched cards, I was allowed to test only once a day :^)

rg3 03-14-2013 01:27 PM

Python's datetime module can also be used if you're sure both date are after the Gregorian reform.

Code:

$ python
Python 2.7.3 (default, Jul  3 2012, 19:58:39)
[GCC 4.7.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import *
>>> a = date(2013, 3, 14)
>>> b = date(1784, 4, 7)
>>> print a -b
83616 days, 0:00:00


rg3 03-14-2013 01:32 PM

Quote:

Originally Posted by Didier Spaier (Post 4911626)
Still waiting for solution working since year 1 (Julian then Gregorian calendars).

I've done that as an exercise in Cobol long ago (circa 1977, IIRC :-)

Before the BSD ncal command accepted a flag allowing you to select the Gregorian reform date, I wrote a small Python script to print calendars assuming October 1582. Much of that code can be used to calculate the difference.

https://github.com/rg3/cal_1582

Also, the source of the ncal BSD command is interesting as it has an algorithm to count days too and calculate the day of the week for any date. It's pretty simple, actually.

http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/ncal/

imitis 03-14-2013 01:36 PM

I'm using this one :

http://kde-apps.org/content/show.php...?content=37238

Mark Pettit 03-14-2013 01:45 PM

Go with the Python method @rg3 suggests. If you're dipping your toes into what's really a programming problem, then you might as well go the whole hog and learn a decent programming language. And I cannot recommend anything better than Python. The simple example (s)he gave shows just how easy it is.


All times are GMT -5. The time now is 07:03 PM.