Solved

Julian Day calculation

Posted on 2004-04-21
36
1,535 Views
Last Modified: 2007-12-19
I want to know how to use year, month, day, hour, minute, second as input and calculate the corresponding julian day?
0
Comment
Question by:hauto
  • 13
  • 10
  • 6
  • +2
36 Comments
 
LVL 46

Expert Comment

by:Sjef Bosman
ID: 10877819
For 20 points? Read ctime, gmtime, localtime and mktime.
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10877959
Hi hauto,
Good one.

Try this:

#define UNIX_EPOCH 2440588


time_t unix_to_jd(time_t unix_d) {
          return ( UNIX_EPOCH + unix_d);
     }



Cheers,
Stefan
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10878003
It is easy (with your calculator) to calculate the Julian Day Number of any date given on the Gregorian Calendar. The Julian Day Number so calculated will be for 0 hours, GMT, on that date. Here's how to do it:

1) Express the date as Y M D, where Y is the year, M is the month number (Jan = 1, Feb = 2, etc.), and D is the day in the month.

2) If the month is January or February, subtract 1 from the year to get a new Y, and add 12 to the month to get a new M. (Thus, we are thinking of January and February as being the 13th and 14th month of the previous year).

3) Dropping the fractional part of all results of all multiplications and divisions, let

  A = Y/100
  B = A/4
  C = 2-A+B
  E = 365.25x(Y+4716)
  F = 30.6001x(M+1)
  JD= C+D+E+F-1524.5
This is the Julian Day Number for the beginning of the date in question at 0 hours, Greenwich time. Note that this always gives you a half day extra. That is because the Julian Day begins at noon, Greenwich time.
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10878022
hauto,
Since Julian calender is mainly used for calculating religious holidays in the Orthodox world, here is a PHP script for the whole lot - Christian, Islamic and Jewish holidays.

Enjoy.

The author is John Hamilton <treeless at adelphia dot net>

<?PHP
     /***********************
     Calendar1.php module

     the primary objective of this module is to present the holiday_class
     which determines U.S., christian, hebrew, and islamic holidays occuring
     during a specific gregorian year.  gregorian, hebrew, and islamic date handling
     and conversion functions are provided for use in the class, and any other uses
     you need.  note the julian day is used for all conversions.

     to use the module:
          delete html code at the beginning and end of this module,
          delete the test functions at the end of the module
          comment out undesired holidays
          add desired holidays
          declare a holiday_class variable for the desired year,
               e.g., $cal = new holiday_class($yr)
          use one of the output methods:
               $cal->ListHolidays([$yr]) to print the list of holidays to html output
               $cal->GetHolidays($jd) to return a string of any holidays
                    corresponding to a julian day (use to list holidays on calendars)
               $cal->GetHoliday($s) to return a julian day of the holiday corresponding
                    to the parameter $s (e.g. "Christmas")

     ************************************/

     //julian day corresponding to the start of various functions
     define("GREGORIAN_EPOCH", 1721425.5, TRUE);
     define("HEBREW_EPOCH", 347995.5, TRUE);
     define("ISLAMIC_EPOCH", 1948439.5, TRUE);
     define("UNIX_EPOCH", 2440587.5, TRUE);
          //caution--php's mktime uses universal time
          //adjustments are made corresponding to the server's time zone

     define("SECS_IN_DAY", 86400.0, TRUE);

     //constants for day of week interpretation
     define("dSUNDAY", 0, TRUE);
     define("dMONDAY", 1, TRUE);
     define("dTUESDAY", 2, TRUE);
     define("dWEDNESDAY",3, TRUE);
     define("dTHURSDAY", 4, TRUE);
     define("dFRIDAY", 5, TRUE);
     define("dSATURDAY", 6, TRUE);

     $GREGORIAN_DAY = Array("Sunday", "Monday", "Tuesday", "Wednesday",
                    "Thursday", "Friday", "Saturday");

     $HEBREW_DAY = Array("yom rishon", "yom sheni", "yom sh'lishi",
                    "yom revi'i", "yom chamishi", "yom shishi", "shabbat kodesh");

     $ISLAMIC_DAY = Array("al-'ahad", "al-'ithnayn", "ath-thalatha'", "al-'arb`a'",
                    "al-khamis", "al-jum`a", "as-sabt");

     //gregorian month constants
     define("mJANUARY", 1, TRUE);
     define("mFEBRUARY", 2, TRUE);
     define("mMARCH", 3, TRUE);
     define("mAPRIL", 4, TRUE);
     define("mMAY", 5, TRUE);
     define("mJUNE", 6, TRUE);
     define("mJULY", 7, TRUE);
     define("mAUGUST", 8, TRUE);
     define("mSEPTEMBER", 9, TRUE);
     define("mOCTOBER", 10, TRUE);
     define("mNOVEMBER", 11, TRUE);
     define("mDECEMBER", 12, TRUE);

     $GREGORIAN_MONTH = Array(1 => "January", "February", "March",
                    "April", "May", "June", "July", "August", "September",
                    "October", "November", "December");

     //HEBREW month constants
     define("mNISAN", 1, TRUE);
     define("mIYYAR", 2, TRUE);
     define("mSIVAN", 3, TRUE);
     define("mTAMMUZ", 4, TRUE);
     define("mAV", 5, TRUE);
     define("mELUL", 6, TRUE);
     define("mTISHRI", 7, TRUE);
     define("mCHESHVAN", 8, TRUE);
     define("mKISLEV", 9, TRUE);
     define("mTEVET", 10, TRUE);
     define("mSHVAT", 11, TRUE);
     define("mADAR", 12, TRUE);
     define("mADARI", 12, TRUE);  //leap month
     define("mADARII", 13, TRUE); //Adar in leap year
     define("mVEDAR", 13, TRUE);  //alternative ADAR in leap year

     $HEBREW_MONTH = Array(1=>"Nisan", "Iyyar", "Sivan", "Tammuz", "Av",
                    "Elul", "Tishri", "Cheshvan", "Kislev", "Teveth", "Sh'vat", "Adar", "Vedar");

     $HEBREW_LEAP_MONTH = Array(1=>"Nisan", "Iyyar", "Sivan", "Tammuz", "Av",
                    "Elul", "Tishri", "Cheshvan", "Kislev", "Teveth", "Sh'vat", "Adar I", "Adar II");

     //ISLAMIC MONTH constants
     define("mMuharram", 1, TRUE);
     define("mSafar", 2, TRUE);
     define("mRabiI", 3, TRUE);
     define("mRabiII", 4, TRUE);
     define("mJumadlaI", 5, TRUE);
     define("mJumadaII", 6, TRUE);
     define("mRajab", 7, TRUE);
     define("mShaban", 8, TRUE);
     define("mRamadan", 9, TRUE);
     define("mShawwal", 10, TRUE);
     define("mDhualQada", 11, TRUE);
     define("mDhualHijja", 12, TRUE);

     $ISLAMIC_MONTH = Array(1=>"Muharram", "Safar", "Rabi`al-Awwal", "Rabi`ath-Thani",
                    "Jumad l-Ula", "Jumada t-Tania", "Rajab", "Sha`ban", "Ramadan",
                    "Shawwal", "Dhu l-Qa`da", "Dhu l-Hijja");

/*************************
     HOLIDAY_CLASS -- class provides methods to determine and output holidays in any given gregorian year
          the primary objective is list any holidays associate with a given julian day
************************************************/
class holiday_class {

     var $holidays;
     var $bjd; //beginning julian day of the year
     var $ejd; //ending julian day of the year

     //initialization method
     function holiday_class ($yr=0)
     {
          if ($yr==0) $yr = (int)date("Y");
          $this->bjd = gregorian_to_jd(1,1,$yr);
          $this->ejd = gregorian_to_jd(12,31,$yr);

          //add holidays easily define in the gregorian calendar
          $this->holidays = Array(
               "New Year's Day" => $this->bjd,

               "Candlemas" => gregorian_to_jd(1,2, $yr),
               "Epiphany" => gregorian_to_jd(1,6,$yr),

               "Martin Luther King Day" => nth_weekday_jd(3,dMONDAY,1,$yr),

               "Abraham Lincoln's Birthday" => gregorian_to_jd(2,12,$yr),
               "St. Valentine's Day"=> gregorian_to_jd(2,14,$yr),
               "Presidents' Day" => nth_weekday_jd(3,dMONDAY,2,$yr),

               "George Washington's Birthday" => gregorian_to_jd(2,22,$yr),
               "St. Patrick's Day" => gregorian_to_jd(3,17,$yr),

               "April Fools' Day" => gregorian_to_jd(4,1,$yr),

               "May Day" => gregorian_to_jd(5,1,$yr),

               "Cinco De Mayo" => gregorian_to_jd(5,5,$yr),
               "Mothers' Day" => nth_weekday_jd(2,dSUNDAY,5,$yr),
               "Memorial Day" => $this->MemorialDay($yr),
               "Flag Day" => gregorian_to_jd(6,14,$yr),
               "Fathers' Day" => nth_weekday_jd(3,dSUNDAY,6,$yr),
               "Independence Day" => gregorian_to_jd(7,4,$yr),
               "Labor Day" => nth_weekday_jd(1,dMONDAY,9,$yr),
               "Columbus Day" => nth_weekday_jd(2,dMONDAY,10,$yr),

               "Holloween" => gregorian_to_jd(10,31,$yr),
               "All Saints' Day" => gregorian_to_jd(11,1,$yr),
               "All Souls' Day" => gregorian_to_jd(11,2,$yr),
               "Veterans' Day" => gregorian_to_jd(11,11,$yr),
               "Thanksgiving Day" => nth_weekday_jd(4, dTHURSDAY, 11,$yr),
               "Advent Begins" => $this->NthSundayOfAdvent(1,$yr),

               "1st Sunday of Advent" => $this->NthSundayOfAdvent(1,$yr),

               "2nd Sunday of Advent" => $this->NthSundayOfAdvent(2,$yr),

               "3rd Sunday of Advent" => $this->NthSundayOfAdvent(3,$yr),

               "4th Sunday of Advent" => $this->NthSundayOfAdvent(4,$yr),
               "Christmas Eve" => gregorian_to_jd(12,24,$yr),
               "Christmas Day" => gregorian_to_jd(12,25,$yr),


               "Mardi Gras/Fat Tuesday" => easter_jd($yr,-47),
               "Ash Wednesday" => easter_jd($yr,-46),
               "1st Sunday of Lent" => easter_jd($yr,-42),

               "2nd Sunday of Lent" => easter_jd($yr,-35),

               "3rd Sunday of Lent" => easter_jd($yr,-28),

               "4th Sunday of Lent" => easter_jd($yr,-21),

               "5th Sunday of Lent" => easter_jd($yr,-14),
               "Palm Sunday" => easter_jd($yr,-7),
               "Maundy Thursday" => easter_jd($yr,-3),
               "Good Friday" => easter_jd($yr,-2),
               "Easter" =>     easter_jd($yr),
               "Ascension" => easter_jd($yr,39),
               "Pentecost" => easter_jd($yr,49) );

               //add jewish holidays to holidays array
               $this->hebrew_holidays();

               //add islamic holidays
               $this->islamic_holidays();

               asort($this->holidays);
     }

     //method to add a hebrew holiday in month, day, year form
     // use $shabbat_test = TRUE when the holiday CAN'T fall on shabbat
     // and set $shabbat_jda to the month day used when the holiday normally
     // falls on shabbat (saturday)
     function add_hebrew_holiday($name, $jmo, $jda, $jyr,
          $shabbat_test = FALSE, $shabbat_jda = 0) {
          //adar holidays fall in Vedar in leap years
          if ( $jmo == mADAR && hebrew_leap($jyr) ) $jmo = mVEDAR;

          $jd = hebrew_to_jd($jmo, $jda, $jyr);
          //perform the shabbat_test
          if ($shabbat_test && jd_to_weekday($jd) == dSATURDAY)
               $jd = hebrew_to_jd($jmo, $shabbat_jda, $jyr);

          $this->add_holiday_jd($name, $jd, $jyr);

     }

     //method actually adds the holiday to the array, if it falls within
     //the current gregorian year
     //used for both hebrew and islamic holidays
     //yr is appended if holiday name is repeated during the greorian year
     function add_holiday_jd($name, $jd, $yr) {

          //does date fall within the current gregorian calendar year?
          if($jd >= $this->bjd && $jd <= $this->ejd) {
               //append yr if the holiday is already in the list
               if(array_key_exists($name,$this->holidays)) $name .= (" " . $yr);
               $this->holidays[$name] = $jd;
          }
     }

     //method adds n holidays named name starting on hebrew date $jmo/$jda/$jyr
     //used primarily to list festival days
     function add_n_hebrew_holidays($n, $name, $jmo, $jda, $jyr) {

          //$jd and $n adjusted for use in loop
          $jd = hebrew_to_jd($jmo, $jda, $jyr) - 1;
          $n = $n + 1;

          for ($i=1; $i < $n; $i++) {
               $ex = ($i==1 ? "st" : ($i==2 ? "nd" : ($i==3 ? "rd" : "th" )));
               $this->add_holiday_jd($i . $ex . " Day of " . $name, $jd+$i, $jyr);
          }
     }

     //method adds a series of hebrew holidays (using above methods)
     function hebrew_holidays() {

          jd_to_hebrew($this->bjd, $jmo, $jda, $bjyr); //for beg jewish yr
          jd_to_hebrew($this->ejd, $jmo,$jda, $ejyr); //for end jewish yr

          //there usually are more than 1 jewish year in a gregorian year
          //for loop cycles through the hebrew years in the gregorian year
          //to assure they are all considered (note won't be added to list
          //if they don't fall within the current gregorian year
          for($jyr = $bjyr; $jyr <= $ejyr; $jyr++ ) {
               //Major Festivals
               $this->add_n_hebrew_holidays(2, "Rosh Hashana", mTISHRI, 1, $jyr); //Jewish New Year
               $this->add_hebrew_holiday("Yom Kippur", mTISHRI, 10, $jyr); //Day of Atonement

               $this->add_n_hebrew_holidays(2, "Sukkot", mTISHRI, 15, $jyr); //Tabernacles
               $this->add_n_hebrew_holidays(7, "Sukkot Chol Hamoed", mTISHRI, 17, $jyr);

               $this->add_hebrew_holiday("Sh'mini Atzeret", mTISHRI, 22, $jyr);

               $this->add_hebrew_holiday("Simchat Tora", mTISHRI, 23, $jyr);

               $this->add_n_hebrew_holidays(2, "Pesach (Passover)", mNISAN, 15, $jyr); //Pesach
               $this->add_n_hebrew_holidays(4, "Pesach Chol Hamoed", mNISAN, 17, $jyr);

               $this->add_n_hebrew_holidays(2, "Pesach (Final Holiday)", mNISAN, 21, $jyr);

               $this->add_n_hebrew_holidays(2, "Shavuot", mSIVAN, 6, $jyr);

               //Minor Festivals
               $this->add_n_hebrew_holidays(8, "Chanukka", mKISLEV, 25, $jyr);

               $this->add_hebrew_holiday("Purim", mADAR, 14, $jyr);

               //Fast Days
               $this->add_hebrew_holiday("Tzom Gedalya", mTISHRI, 3, $jyr, TRUE, 4);
               $this->add_hebrew_holiday("Asara b'Tevet", mTEVET, 10, $jyr);
               $this->add_hebrew_holiday("Tan'anit Ester", mADAR, 13, $jyr, TRUE, 11);
               $this->add_hebrew_holiday("Shiv'a Asar b'Tammuz", mTAMMUZ, 17, $jyr, TRUE, 18);
               $this->add_hebrew_holiday("Tish'a b'Av", mAV, 9, $jyr, TRUE, 10);


          }

     }

     //utility method to add an islamic holiday
     function add_islamic_holiday($name, $imo, $ida, $iyr) {

          $this->add_holiday_jd($name, islamic_to_jd($imo, $ida, $iyr), $iyr);
     }

     //method adds a series of islamic holidays
     function islamic_holidays() {
          jd_to_islamic($this->bjd, $imo, $ida, $biyr); //for biyr
          jd_to_islamic($this->ejd, $imo, $ida, $eiyr); //for eiyr

          //as for the jewish, more than one islamic year is covered
          //in any gregorian year--for loop used to ensure they are all covered
          for($iyr = $biyr; $iyr <= $eiyr; $iyr++) {
               $this->add_islamic_holiday("Islamic New Year", mMuharram, 1, $iyr);
               $this->add_islamic_holiday("Ashura'", mMuharram, 10, $iyr);
               $this->add_islamic_holiday("Mawlid an Nabi", mRabiI, 12, $iyr);
               $this->add_islamic_holiday("Lailat al Miraj", mRajab, 27, $iyr);
               $this->add_islamic_holiday("Lailat al Bara'a", mShaban, 15, $iyr);
               $this->add_islamic_holiday("Ramadan begins", mRamadan, 1, $iyr);
               $this->add_islamic_holiday("Lailat al Qadr", mRamadan, 27, $iyr);
               $this->add_islamic_holiday("'Id al Fitr", mShawwal, 1, $iyr);
               $this->add_islamic_holiday("eve of Adha", mDhualHijja, 9, $iyr);
               $this->add_islamic_holiday("'Id al Adha", mDhualHijja, 10, $iyr);

          }
     }

     //method determines the Nth Sunday of Advent
     function NthSundayOfAdvent($n,$yr)
     {     //(4-n)th sunday before christmas
          $jd = gregorian_to_jd(12,25,$yr);

          $temp=jd_to_weekday($jd);
          if ($temp == dSUNDAY) $temp = 7;

          return ( $jd - $temp - (4-$n) * 7 );
     }

     //method determines Memorial Day
     function MemorialDay ($yr)
     {     //last mon in may
          $jd = gregorian_to_jd(5,31,$yr);

          $w = jd_to_weekday($jd);
          //if $w is sunday, it's the sunday FOLLOWING memorial day
          if ($w==dSUNDAY) $w = 7;

          return ( $jd - ($w - dMONDAY) );
     }

     //method prints/lists ALL holidays to the html output
     //modify for the html output you want, or to return a string
     //containing all output
     function ListHolidays($y=0)
     {
          global $GREGORIAN_MONTH, $GREGORIAN_DAY;
          //call with year $y for other than current year
          if ($y!=0) $this->holiday_class($y);
          //reset($this->holidays);

          //print ("<pre>");
          //print_r ($this->holidays);
          //print ("</pre>");
          //return;

          foreach($this->holidays as $k => $f)
          {
               jd_to_gregorian($f, $m, $d, $y);
               $d = ": " . $GREGORIAN_DAY[jd_to_weekday($f)] . ", " .
                    $GREGORIAN_MONTH[$m] . " $d, $y";

               //print("<pre>" . $f . "--" . $k . $d . "</pre>");
               print($k . $d . "<br />");

          }
     }


     //method returns a string listing all current holidays
     //falling on the input julian day parameter ($jd)
     //the string is empty is no holidays fall on that date
     function GetHolidays($jd)
     {
          $s="";
          reset($this->holidays);

          //test each holiday for matching given date
          foreach($this->holidays as $k => $d)
          {
               if ($jd==$d) $s.=$k."<br/>\n\r\n";
          }

          //return string listing any holidays for given date
          return ($s);
     }

     //method returns the julian day of the holiday corresponding to
     //the input parameter $s (e.g.: "Christmas")
     //zero (0) is returned if no holidays correspond to $s
     function GetHoliday($s)
     {
          if (array_key_exists($s, $this->holidays)) return ($this->holidays[$s]);

          //the key doesn't exist, return 0
          return (0);
     }

} //end class

     /*************************
     JD_TO_WEEKDAY -- determine the weekday from julian day
     ***************************/
     function jd_to_weekday($jd) {
          return ( floor( ($jd+8.5) % 7 )  );
     }

     /***************************
     NTH_WEEKDAY_JD -- determine julian day of Nth ($n) weekday ($m) for given
          Gregorian month ($m) and year ($yr)
     *******************************************/
     function nth_weekday_jd($n, $w, $m, $yr)
     {
          $jd = gregorian_to_jd($m,1,$yr);
          //calculate days to first weekday (w) in month (m)
          $days = $w - jd_to_weekday($jd);
          //negative days points to previous month, increment by 7 for
          if ($days < 0) $days += 7;

          return ( $jd + $days + ($n-1) * 7 );
     }

     /************************
      function returns Easter Date as a julian date for any given $year 1583 to 4099
      based on Visual Basic code in Easter Dating Method by Ronald W. Mallen
      see http://www.assa.org.au/edm.html

      the optional $offset parameter allows calculations of other dates, e.g. the sundays of lent,
      which are based on the easter date

      problems with php's easter_date([year])
     **********************************************/
     function easter_jd ( $year, $offset=0 ) {

          $FirstDig = (int)($year/100);     //first 2 digits of year
          $Remain19 = $year % 19;               //remainder of year / 19

          //calculate PFM date

          $temp = ( (int)(($FirstDig - 15) /2) + 202 - 11 * $Remain19);

          switch ($FirstDig) {
               case 21:
               case 24:
               case 25:
               case 27:
               case 28:
               case 29:
               case 30:
               case 31:
               case 32:
               case 34:
               case 35:
               case 38:
                    $temp = $temp - 1;
                    break;

               case 33:
               case 36:
               case 37:
               case 39:
               case 40:
                    $temp = $temp - 2;
                    break;
          }     //end switch

          $temp = $temp % 30;

          $tA = $temp + 21;
          if ($temp == 29 ) $tA = $tA -1;
          if($temp == 28 And $Remain19 > 10) $tA = $tA - 1;

          //find the next Sunday
          $tB = ($tA - 19) % 7;

          $tC = (40 - $FirstDig) % 4;
          if ($tC == 3) $tC = $tC +1;
          if ($tC > 1) $tC = $tC +1;

          $temp = $year % 100;
          $tD = ($temp + ((int)($temp / 4)) ) % 7;

          $tE = ((20 -$tB - $tC - $tD) % 7 ) + 1;
          $da = $tA + $tE;

          //return the date
          if ( $da > 31 ) {
               $da = $da - 31;
               $mo = 4;
          } else {
               $mo = 3;
          }

          return( gregorian_to_jd($mo, $da, $year) + $offset );

     } //end EasterDate()

/************************************************
     the following functions are taken from the java script at
     http://www.fourmilab.com/documents/calendar/
**************************************************/

     /**********************
     LEAP_GREGORIAN -- Is a given Gregorian year a leap year?
     ************************/
     function leap_gregorian($year) {

          return ( (($year % 4)==0) && (!( (($year % 100)==0) && (($year % 400) != 0) )));
     }

     /*************************
     GREGORIAN_TO_JD -- Determine Julian day number from Gregorian calendar date
     ************************/
     function gregorian_to_jd($mo, $da, $yr) {

          return (     GREGORIAN_EPOCH - 1 +
                         365 * ($yr-1) +
                         floor(($yr-1)/4) -
                         floor(($yr-1)/100) +
                         floor(($yr-1)/400) +
                         floor((367 * $mo - 362) / 12 ) +
                         (($mo <= 2) ? 0 : (leap_gregorian($yr) ? -1 : -2 )) +
                         $da );

     }

     /*******************
     JD_TO_GREGORIAN -- Calculate Gregorian calender date from Julian Date
          note $mo, $da, and $yr are returned by reference
     ********************************/
     function jd_to_gregorian($jd, &$mo, &$da, &$yr) {

          $wjd = floor($jd - 0.5) + 0.5;
          $depoch = $wjd - GREGORIAN_EPOCH;
          $quadricent = floor($depoch / 146097);
          $dqc = $depoch % 146097;
          $cent = floor($dqc / 36524);
          $dcent = $dqc % 36524;
          $quad = floor($dcent / 1461);
          $dquad = $dcent % 1461;
          $yindex = floor($dquad / 365);
          $yr = $quadricent * 400 + $cent * 100 + $quad * 4 + $yindex;

          if (!(($cent == 4) || ($yindex == 4))) $yr++;

          $yearday = $wjd - gregorian_to_jd(1,1,$yr);
          $leapadj = (($wjd < gregorian_to_jd(3,1,$yr)) ? 0 : (leap_gregorian($yr) ? 1 : 2));
          $mo = floor(((($yearday + $leapadj) * 12) + 373) / 367);
          $da = $wjd - gregorian_to_jd($mo, 1, $yr) + 1;

     }


     /***********************
     HEBREW_LEAP -- Is the given Hebrew year a leap year?
     ***********************/
     function hebrew_leap($yr) {
          return ( (($yr * 7 + 1) % 19 ) < 7 );
     }

     /**************************
     HEBREW_YEAR_MONTHS -- Months in Hebrew year ($yr), 12 = normal, 13 = leap
     ***************************/
     function hebrew_year_months($yr) {
          return ( hebrew_leap($yr) ? 13 : 12 );
     }

     /***************************
     HEBREW_DELAY_1 -- Test for delay of start of new year and to avoid
          Sunday, Wednesday, and Friday as start of the new year
     *****************************/
     function hebrew_delay_1($yr) {

          $mos = floor( ((235 * $yr) - 234 ) / 19);
          $parts = 12084 + 13753 * $mos;
          $day = $mos * 29 + floor($parts / 25920);

          if ( (3*($day+1) % 7) < 3 ) $day++;

          return ($day);
     }

     /*************************
     HEWBREW_DELAY_2 -- Check for delay in start of new year due to length of adjacent years
     **************************/

     function hebrew_delay_2($yr) {

          $last = hebrew_delay_1($yr - 1);
          $present = hebrew_delay_1($yr);
          $next = hebrew_delay_1($yr + 1);

          return ( (($next - $present) == 356) ? 2 :
                         ((($present - $last) == 382) ? 1 : 0) );
     }


     /***************************
     HEBREW_YEAR_DAYS -- How many days in a Hebrew year?
     ****************************/
     function hebrew_year_days($yr) {
          return ( hebrew_to_jd(7, 1, $yr + 1) - hebrew_to_jd(7, 1, $yr) );
     }

     /**************************
     HEBREW_MONTH_DAYS -- How many days in given month of given year?
     **************************/
     function hebrew_month_days($mo, $yr) {

          switch ($mo) {
               case 2:          //fixed length 29 day months
               case 4:
               case 6:
               case 10:
               case 13:
                    return (29);
                    break;
               case 12:
                    if (! hebrew_leap($yr) ) return(29);
                    break;
               case 8:
                    //Heshvan depends on length of year
                    if ( !( (hebrew_year_days($yr) % 10) == 5) ) return (29);
                    break;
               case 9:
                    //Kislev also varies with the length of year
                    if ( (hebrew_year_days($yr) % 10) == 3 ) return (29);
                    break;
          }

          //otherwise the month has 30 days
          return (30);
     }

     /***************************
     HEBREW_TO_JD -- Determine Julian date from Hebrew date
     ****************************/
     function hebrew_to_jd($mo, $da, $yr) {

          $mos = hebrew_year_months($yr);

          $jd = HEBREW_EPOCH + hebrew_delay_1($yr) + hebrew_delay_2($yr) + $da + 1;

          if ($mo < 7 ) {
               for ($m = 7; $m <= $mos; $m++) $jd += hebrew_month_days($m, $yr);
               for ($m = 1; $m < $mo; $m++) $jd += hebrew_month_days($m, $yr);
          } else {
               for ($m = 7; $m < $mo; $m++ ) $jd += hebrew_month_days($m, $yr);
          }

          return ($jd);
     }

     /******************************
     JD_TO_HEBREW -- Deterime Hewbrew date from Julian date
          note: month, day, and year are set by reference
     *******************************/
     function jd_to_hebrew($jd, &$mo, &$da, &$yr) {

          $jd = floor($jd) + 0.5;

          $count = floor((($jd - HEBREW_EPOCH) * 98496.0) / 35975351.0);
          $yr = $count - 1;

          $jdtest = hebrew_to_jd(7,1,$count);
          for ( $i = $count; $jd >= $jdtest; ) {
               $yr++;
               $jdtest = hebrew_to_jd(7,1,++$i);
          }

          $first = ($jd < hebrew_to_jd(1,1,$yr)) ? 7 : 1;
          $mo = $first;

          $jdtest = hebrew_to_jd($mo, hebrew_month_days($mo,$yr), $yr);
          for ( $i = $first; $jd > $jdtest; ) {
               $mo++;
               $jdtest = hebrew_to_jd(++$i, hebrew_month_days($i,$yr), $yr);
          }


          $da = $jd - hebrew_to_jd($mo, 1, $yr) +1;
     }


     /*************
     LEAP_ISLAMIC -- Is a given year a leap year in the Islamic calendar?
     **********************/
     function leap_islamic($yr) {
          return (((($yr*11)+14)%30)<11);
     }

     /***************
     ISLAMIC_TO_JD -- determin Julian day from Islamic date
     ****************/
     function islamic_to_jd($mo,$da,$yr) {
          return ( $da + ceil(29.5*($mo-1)) + ($yr-1)*354 +
               floor((3+(11*$yr))/30)+ ISLAMIC_EPOCH - 1);
     }

     /***************
     JD_TO_ISLAMIC -- determin Islamic date from Julian day
          note: mo da and yr set by reference
     *****************/
     function jd_to_islamic($jd, &$mo, &$da, &$yr) {
          $jd = floor($jd)+0.5;
          $yr = floor(((30*($jd-ISLAMIC_EPOCH)) + 10646) / 10631);

          $mo = min(12, ceil(($jd-(29+islamic_to_jd(1,1,$yr)))/29.5)+1);

          $da = $jd - islamic_to_jd($mo,1,$yr) + 1;

     }

     /********************
     JD_TO_UNIX -- determine unix timestamp from julian date
          note the mktime and date functions adjust for local time
     **********************/
     function jd_to_unix($jd) {
          $val=(($jd-UNIX_EPOCH) * SECS_IN_DAY * 1000);
          return ( round($val/1000) ) ;
     }

     /********************
     UNIX_TO_JD -- determin julian day from unix timestamp
     *************************/
     function unix_to_jd($t) {
          return ( UNIX_EPOCH + t / SECS_IN_DAY);
     }


/************8 test functions **********************/

$cal = new holiday_class(2004);

$cal->ListHolidays();


for ($jd = $cal->bjd; $jd <= $cal->ejd; $jd++) {
     //reset($cal->holidays);
     $s = $cal->GetHolidays($jd);
     if (strlen($s) > 0) {
          jd_to_gregorian($jd, $mo, $da, $yr);
          printf("<p> %s, %s %d, %d <br />", $GREGORIAN_DAY[jd_to_weekday($jd)],
               $GREGORIAN_MONTH[$mo], $da, $yr);
          print($s . "</p>");
     }
}

?>


Stefan
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10878075
Now thats what you call a small piece of code.
:~))

0
 
LVL 46

Expert Comment

by:Sjef Bosman
ID: 10878112
If you have Linux, try to print the calendar for 1752, and watch September. Have fun!
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10878207
ankuratvb,
Tiny, isn't it? ;-)

Stefan
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10878309
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 10878378
Heres some VB I use in Excel spreadsheets to calculate what Banks call the Julian date:

' Generates the Julian date value for an Excel date.
Public Function Jdate(ExcelDate As Date) As Integer
    '=MOD(YEAR(B2),100)*1000+B2-DATE(YEAR(B2),1,1)+1
    Jdate = (Year(ExcelDate) Mod 100) * 1000 + DateDiff("d", DateSerial(Year(ExcelDate), 1, 1), ExcelDate) + 1
End Function

Effectively, the julian date is the day of the year with 1 Jan as 1and 31 Dec as 365 or 366, sometimes with the century stuch on at the beginning or the end. Just add up the lengths of each of the earlier months, remembering leap years, then add the day number of the current month.

Paul
0
 

Author Comment

by:hauto
ID: 10878532
Thanks all for answering. Let me explain what I am going to do more clear.
I am working on a Linux machine with C or C++, I want to change date time which is orignally in yyyymmddhhnnss format to Julian format.

 I need to consider minute and second in addition to year, month and day, but I find those code of web only use year, month and day only.

Thanks!
0
 

Author Comment

by:hauto
ID: 10878568
>>stephen73
What's UNIX_EPOCH?
0
 

Author Comment

by:hauto
ID: 10878607
>>stephen73
is UNIX_EPOCH=unix timestamp?

what will return from?
return ( UNIX_EPOCH + unix_d);
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 10878668
short JulianDay (short Day, short Month, short Year )
{
    static short DaysInMonth[] =
    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } ;
    short Julian_Day = 0 ;
    short i ;
      // Tweak february
    DaysInMonth[1]=28 + LeapDay(Year);
      
    // Julianise it
    for ( i = 0 ; i < Month - 1 ; i++ )
    {
        Julian_Day += DaysInMonth[i] ;
    }
      
    Julian_Day += Day ;
      
    return Julian_Day ;
}


// returns 1 for leap year,
//         0 for normal year
// so 28+leap(year) will give the number of days in february
short LeapDay(short year)
{
    if ((year%4==0 && year%100!=0) || year%400==0)
        return 1; // leap year
    // else
    return 0;  // normal year
}

Adding the time to a julian day is unusual. I would suggest you refer to documenation.

0
 
LVL 12

Expert Comment

by:stefan73
ID: 10878764
PaulCaswell,
> Adding the time to a julian day is unusual.

Since the julian day starts at noon, you need this to properly identify the date.

hauto: What do you need this for? Historical or religious date calculations?

Stefan
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10878780
sjef_bosman,
> calendar for 1752

I don't, so what happens?

Stefan
0
 

Author Comment

by:hauto
ID: 10878837
stefan73,
I am going to make the time to be injected by idl(a Matlab like program). Is the program you provide converting unix_timestamp to Julian day?

#define UNIX_EPOCH 2440588


time_t unix_to_jd(time_t unix_d) {
          return ( UNIX_EPOCH + unix_d);
     }
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 10878843
Stefan,

Of course! I am only used to Bank Julian dates which start at 00:00 and usually go back to 001 on 1st Jan.

>> 1752.

Wikipedia states:

September 14 (1752) - The British Empire adopts the Gregorian calendar, making it necessary to skip eleven days (September 2 being followed directly by September 14 this year).


Paul
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:hauto
ID: 10878852
stefan73,
I am doing some data mining work from radar data
0
 
LVL 46

Expert Comment

by:Sjef Bosman
ID: 10878929
Did they have radars back in 1752?
0
 

Author Comment

by:hauto
ID: 10878971
No, my question is simple.
I just want to transform datetime into julian date so that idl can use it to plot some graph. However, I have to take care of hour, minute and second during the transform
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10879040
here is javascript code for what you want.

  if (year > 1582) { gregorian = true; }
  if (year==1582)  {
    if (month > 10)              { gregorian = true; }
    if ((month==10)&&(day>=15))  { gregorian = true; }
  }
  if (gregorian==true) { a = intw(year/100); b = 2-a+intw(a/4); }

  return (intw(365.25 * year) + intw(30.6001 * (month + 1))
          + day + (hour/24) + (minute/1440) + (second/86400)
          + 1720994.5 + b);
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10879051
BTW,the intw() function just truncates the deimal portion.
0
 
LVL 12

Expert Comment

by:stefan73
ID: 10879057
sjef_bosman,
OK, I've installed Apache, but PHP is not working :-/

Stefan
0
 

Author Comment

by:hauto
ID: 10879069
gregorian is always true?
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10879113
Initially gregorian is false.
0
 
LVL 9

Accepted Solution

by:
ankuratvb earned 20 total points
ID: 10879136
Here's the complete function:

function Cal2JD(year,month,day,hour,minute,second) {
  //
  // Compute the Julian Date for a given day, month, year
  //
  var a = 0; var b = 0;
  var gregorian = false;

  if (month < 3) { year -= 1; month += 12; }//i missed this part last time around.

  // Check if date is in the Gregorian calendar.
  if (year > 1582) { gregorian = true; }
  if (year==1582)  {
    if (month > 10)              { gregorian = true; }
    if ((month==10)&&(day>=15))  { gregorian = true; }
  }
  if (gregorian==true) { a = intw(year/100); b = 2-a+intw(a/4); }

  return (intw(365.25 * year) + intw(30.6001 * (month + 1))
          + day + (hour/24) + (minute/1440) + (second/86400)
          + 1720994.5 + b);
}

To see the results:
http://www.starlightccd.com/walter/bytebook/javascript/jdcalc.htm
0
 

Author Comment

by:hauto
ID: 10879152
just wonder the program flow,
it will only return false for the year <1582
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10879205
The gregorian calendar started in 1582.
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10879233
10/15/1582 (Gregorian) immediately followed Thursday, 10/4/1582 (Julian). Note also that if you switch between Julian and Gregorian, there is a 10-day difference for a given date in 1582.

Most JD calculators are not guaranteed for Gregorian dates prior to 1582, nor for negative Julian Day Numbers.

0
 

Author Comment

by:hauto
ID: 10879239
it is relevant, I think I can translate them into c
will grant you the point after I double check the value with idl in my office
0
 

Author Comment

by:hauto
ID: 10879263
Actually I don't know what's Gregorian date is, is it the date format we are using in our daily lives?
0
 
LVL 9

Expert Comment

by:ankuratvb
ID: 10879291
Yes.
0
 

Author Comment

by:hauto
ID: 10879304
Thanks!
0
 

Author Comment

by:hauto
ID: 10884468
I didn't check from idl until now but I deeply think that no other better solution can be found from web at this moment.

And I think that calculating julian day with hour, minute and second will have a round up problem.
0
 

Author Comment

by:hauto
ID: 10884481
sorry,
I think ankuratvb is the best answer
and I grant the mark to PaulCaswell but not ankuratvb by accident
I will ask the mark back to ankuratvb
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now