×

Loading...
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务

Here is an algorithm.

本文发表在 rolia.net 枫下论坛Here is a C function showing an algorithm to convert Gregorian calendar date to Julian day number Jday.

unsigned long
Jday(unsigned month, unsigned day, unsigned year)
{
/*
* The following two autos are just for clearity
*/
unsigned long century;
unsigned long years;

/*
* The code for argument validation is ignored here.
*/

if (month > 2)
month -= 3;
else {
month += 9;
year--;
}

century = (unsigned long) year / 100;
years = (unsigned long) year % 100;

return ((146097UL * century) >> 2) + ((1461UL * years) >> 2)
+ (unsigned long) ((153 * month + 2) / 5 + day) + 1721119UL;
}

Porting this function to Shell Script we can get days between almost any two given dates. For exampple:
Jday(6, 4, 2002) - Jday(6, 4, 1989)

It is said that the algorithm is from Communications of the ACM, Volume 6, No. 8, (Aug. 1963), p. 444. I never read it.

I am not sure the exact range of the valid date. Because Gregorian calendar started on September 14, 1752, I think the range of valid date in this algorithm should be at least from September 14, 1752 to the date which is limited by the maximum value of the number used in the Shell Script.更多精彩文章及讨论,请光临枫下论坛 rolia.net
Report

Replies, comments and Discussions:

  • 工作学习 / IT技术讨论 / I came across this post in chinasmile. Nobody has answered his question yet. I couldn't figure out a way to do it with shell scripts, although
    I know it's pretty easy to write a simple C program by using mktime() function and a simple parser to parse the argument into tm structure. But the guy obviously was asking for solutions in script languages, does anybody have any idea? I am really interested.
    ####################but here############################
    Thanks.
    I need a working shell scripts to calculate the days between two calendar dates, the input should be in the format of "YYYYMMDD" for the date string, and I need to know how many days between a given date and the current day's date, OR any two given dates.

    I know it may sound easy, just don't have time to code and test it my own. Does anybody know if there are already some successfully tested running scripts for this somewhere, OR can you kindly help me on this? Any shell (B,K,C) is okay.

    Thanks in advance.
    • I can do it easily with FSF's date, but I can't figure out how to do it using *BSD's date
      Something like:

      #!/bin/sh

      s1=`date -d $1 +%s`
      s2=`date -d $2 +%s`
      day=$((($s2 - $s1)/3600/24))
      echo "Days: " $day
      • Oops! Only works from 1902 to 2038 (with some modification)! So using date is not a good idea...But how to parse string using shell script? Perl would be a lot easier but usually it is not considered a shell...
        • Thanks, actually you can use awk to parser the date. Where can you get FSF's date utility? I never heard of it. And should you use expr in the second last line when you try to evaluate ($s1-s2)/3600/24?
          • It came with every Linux distro (I think). I mean date(1) in Linux (which is from FSF) is different from date(1) in *BSD. And I think $(( ... )) will do the same thing with expr? I'm using bash anyway.
            Actually my script has problems, it overflows much earlier than it should be. Here's an updated one:

            #!/bin/sh

            s1=`date -d $1 +%s`
            s2=`date -d $2 +%s`
            day1=$(($s1/3600/24))
            day2=$(($s2/3600/24))
            echo "Days: " $(($day2 - $day1))

            But like I said it can only calculate from 1902 - 2038. I'll try to come up one with awk (why I didn't think of that? stupid me) if I have time. But I have to deal with leap year myself I guess.
            • Okay, I got it. the $(()) works much better than expr. it looks I am outdated. bash is a gnu thing, FSF date is a gnu thing too.
              I work on Solaris platform mostly. It looks like GNU stuffs are always better than conventional Unix stuffs. BTW, I'am very happy to meet a guy like you, hope we can keep on. Although I am not doing script programming anymore, the script languages are always my favorite, they are concise and fun.
    • Here is an algorithm.
      本文发表在 rolia.net 枫下论坛Here is a C function showing an algorithm to convert Gregorian calendar date to Julian day number Jday.

      unsigned long
      Jday(unsigned month, unsigned day, unsigned year)
      {
      /*
      * The following two autos are just for clearity
      */
      unsigned long century;
      unsigned long years;

      /*
      * The code for argument validation is ignored here.
      */

      if (month > 2)
      month -= 3;
      else {
      month += 9;
      year--;
      }

      century = (unsigned long) year / 100;
      years = (unsigned long) year % 100;

      return ((146097UL * century) >> 2) + ((1461UL * years) >> 2)
      + (unsigned long) ((153 * month + 2) / 5 + day) + 1721119UL;
      }

      Porting this function to Shell Script we can get days between almost any two given dates. For exampple:
      Jday(6, 4, 2002) - Jday(6, 4, 1989)

      It is said that the algorithm is from Communications of the ACM, Volume 6, No. 8, (Aug. 1963), p. 444. I never read it.

      I am not sure the exact range of the valid date. Because Gregorian calendar started on September 14, 1752, I think the range of valid date in this algorithm should be at least from September 14, 1752 to the date which is limited by the maximum value of the number used in the Shell Script.更多精彩文章及讨论,请光临枫下论坛 rolia.net