文字

日历 函数

Table of Contents

  • cal_days_in_month — 返回某个历法中某年中某月的天数
  • cal_from_jd — 转换Julian Day计数到一个支持的历法。
  • cal_info — 返回选定历法的信息
  • cal_to_jd — 从一个支持的历法转变为Julian Day计数。
  • easter_date — 得到指定年份的复活节午夜时的Unix时间戳。
  • easter_days — 得到指定年份的3月21日到复活节之间的天数
  • FrenchToJD — 从一个French Republican历法的日期得到Julian Day计数。
  • GregorianToJD — 转变一个Gregorian历法日期到Julian Day计数
  • JDDayOfWeek — 返回星期的日期
  • JDMonthName — 返回月份的名称
  • JDToFrench — 转变一个Julian Day计数到French Republican历法的日期
  • JDToGregorian — 转变一个Julian Day计数为Gregorian历法日期
  • jdtojewish — 转换一个julian天数为Jewish历法的日期
  • JDToJulian — 转变一个Julian Day计数到Julian历法的日期
  • jdtounix — 转变Julian Day计数为一个Unix时间戳
  • JewishToJD — 转变一个Jewish历法的日期为一个Julian Day计数
  • JulianToJD — 转变一个Julian历法的日期为Julian Day计数
  • unixtojd — 转变Unix时间戳为Julian Day计数

用户评论:

[#1] simon at chronolabs dot org dot au [2007-11-20 00:20:07]

<?php

// You need to replace this section in Function EgyptianCalendar
// As well as Function MayanTihkalCalendar
$revolutionsperyear $ttl_num $i;
$numyears floor((ceil($roun) / $revolutionsperyear));
$avg_num_month $ttl_num_months/$i;
$jtl abs(abs($roun) - ceil($revolutionsperyear*($numyears+1)));
while(
$month==0){
    
$day=0;
    
$u=0;
    foreach(
$monthusage as $key => $item){
        
$t=0;   
        foreach(
$item as $numdays){
            
$t++;
            
$tt=0;
            for(
$sh=1;$sh<=$numdays;$sh++){
                
$ii=$ii+1;
                
$tt++;
                if (
$ii==floor($jtl)){
                    if (
$roun<0){
                        
$daynum $tt;
                        
$month $t;
                    } else {
                        
$daynum $numdays-($tt-1);
                        
$month $avg_num_month-($t-1);
                    }
                    
$sequence $key;
                    
$nodaycount=true;
                }
            }
            if (
$nodaycount==false)
                
$day++;
        }
        
$u++;
    }
}
?>


This section of code need to be changed in the calculation I noticed today in our RounCalendar we had a zero day this function will calculate the month and day correctly for the calendars, it is a pretty universe piece of code, I am sorry it wasn't properly tested and need some refactoring.

[#2] simon at chronolabs dot org dot au [2007-11-09 11:44:01]

This is the egyptian calendar which was the first 365 day calendar on the planet it has no leap year which makes it a little inaccurate but you can work on your own implementation of this code when you like, this is another implementation of the roun floating point code which is a universal code for generating date codec's you can make practically all calendars with this code the $pweight is based on my research on carbon date stamping etc of when egypt epoch or PPO was made, some people argue a few thousand years while other can date egypts epoch being around 30000 years ago!! This is on the basis of tidal marking on statues and momuments when the are was covered in water after construction from sea level rising.

<?php

print_r
(EgyptCalendar(time(),0));

function 
EgyptianCalendar($unix_time$gmt
                 
$poffset '1970-02-26 7:45 PM'
                 
$pweight '-9777600.22222222223'
                 
$defiency='nonedeficient'
                 
$timeset= array("hours" => 24
                                 
"minutes" => 60
                                 
"seconds" => 60))
{
// Code Segment 1 ?C Calculate Floating Point
$tme $unix_time;

if (
$gmt>0){$gmt=-$gmt;} else {$gmt=abs($gmt);}

$ptime strtotime($poffset)+(60*60*gmt);
$weight $pweight+(1*gmt);

$egypt_xa = ($tme)/(24*60*60);
$egypt_ya $ptime/(24*60*60);
$egypt = (($egypt_xa -$egypt_ya) -
         
$weight)+(microtime/999999);

// Code Segment 2 ?C Set month day arrays
$nonedeficient = array(
   
"seq1" => array(30,30,30,30,30,30,30,30,30,30,30,30,5));

$monthnames = array(
   
"seq1" => array('Thoth','Phaophi','Athyr','Choiak',
   
'Tybi''Mecheir','Phamenoth','Pharmuthi','Pachon',
   
'Payni','Epiphi','Mesore','epagomenai'));
                                    
$monthusage = isset($defiency) ? ${$defiency} : $deficient;

// Code Segment 3 ?C Calculate month number, day number
foreach($monthusage as $key => $item){
    
$i++;
    foreach(
$item as $numdays){
        
$ttl_num=$ttl_num+$numdays;
        
$ttl_num_months++;
    }
}

$revolutionsperyear $ttl_num $i;
$numyears egyptd((floor($egypt) / $revolutionsperyear),0);
$avg_num_month $ttl_num_months/$i;
$jtl abs(abs($egypt) - 
       
ceil($revolutionsperyear*($numyears+1)));

while(
$month==0){
    
$day=0;
    
$u=0;
    foreach(
$monthusage as $key => $item){
        
$t=0;   
        foreach(
$item as $numdays){
            
$t++;
            
$tt=0;
            for(
$sh=1;$sh<=$numdays;$sh++){
                
$ii=$ii+1;
                
$tt++;
                if (
$ii==floor($jtl)){
                    if (
$egypt>0){
                        
$daynum $tt;
                        
$month $t;
                    } else {
                        
$daynum $numdays-$tt;
                        
$month $avg_num_month-$t;
                    }
                    
$sequence $key;
                    
$nodaycount=true;
                }
            }
            if (
$nodaycount==false)
                
$day++;
        }
        
$u++;
    }
}

//$numyears = abs($numyears);

$timer substr($egyptstrpos($egypt,'.')+1,
    
strlen($egypt)-strpos($egypt,'.')-1);
$egypt_out$numyears.'/'.$month.'/'.$daynum.' '.$day.'.'
    
floor(intval(substr($timer,0,2))/100*$timeset['hours']).':'
    
floor(intval(substr($timer,2,2))/100*$timeset['minutes']).':'
    
floor(intval(substr($timer,4,2))/100*$timeset['seconds']).'.'.
    
substr($timer,6,strlen($timer)-6);
$egypt_obj = array('year'=>$numyears,
    
'month'=>$month
    
'mname' => $monthnames[$sequence][$month-1],
    
'day'=>$daynum
    
'jtl'=>$jtl
    
'day_count'=>$day,
    
'hours'=>floor(intval(substr($timer,0,2))/100
             
*$timeset['hours']),
    
'minute'=>floor(intval(substr($timer,2,2))/100
              
*$timeset['minutes']),
    
'seconds'=>floor(intval(substr($timer,4,2))/100
               
*$timeset['seconds']),
    
'microtime'=>substr($timer,6,strlen($timer)-6),
                 
'strout'=>$egypt_out);

return 
$egypt_obj;
}

?>


btw in my previous post of the Mayan Tikal calendar the top part of the function was chopped off in my code cut and paste that is the line for the function which looks like, the top 3 line will need to be replace with:

<?php

print_r
(MayanTikalCalendar(time(),0));

function 
MayanTikalCalendar($unix_time$gmt
                                   
?>

[#3] simon at chronolabs dot org dot au [2007-11-08 05:27:07]

Well this is the second part, well more the second calendar of Maya the Tikal there is two of them one for long count, one for general date seeding, this is using an implementation of floating point time (roun).

<?php

$maya 
MayanTikalCalendar(time(),0);

print_r($maya);

                 
$poffset '2012-12-21 8:24 PM'
                 
$pweight '-1872000.22222222223'
                 
$defiency='nonedeficient'
                 
$timeset= array("hours" => 24
                                 
"minutes" => 60
                                 
"seconds" => 60))
{
// Code Segment 1 ?C Calculate Floating Point
$tme $unix_time;
if (
$gmt>0){ $gmt=-$gmt; } else { $gmt=abs($gmt); }

$ptime strtotime($poffset)+(60*60*gmt);
$maya_xa = ($tme)/(24*60*60);
$maya_ya $ptime/(24*60*60);
$maya = (($maya_xa -$maya_ya) - $pweight)+(microtime/999999);

// Code Segment 2 ?C Set month day arrays
$nonedeficient = array(
"seq1" => array(20,20,20,20,20,20,20,20,20,
                
20,20,20,20,20,20,20,20,20,5));

$monthnames = array("seq1" => array(
 
'Pop''Uo''Zip''Zot\'z''Tzec''Xul'
 
'Yaxkin''Mol''Ch\'en''Yax''Zac''Ceh'
 
'Mac''Kankin''Muan''Pax''Kayab'
 
'Cumku''Uayeb'));
$daynames = array("seq1" => array(
 
'Imix''Ik''Akbal''Kan''Chicchan'
 
'Cimi','Manik''Lamat''Muluc''Oc'
 
'Chuen''Eb''Ben''Ix''Men'
 
'Cib''Caban''Etz\'nab''Cauac''Ahau'));
$monthusage = isset($defiency) ? ${$defiency} : $deficient;

// Code Segment 3 ?C Calculate month number, day numbers etc
foreach($monthusage as $key => $item){
    
$i++;
    foreach(
$item as $numdays){
        
$ttl_num=$ttl_num+$numdays;
        
$ttl_num_months++;
    }
}

$revolutionsperyear $ttl_num $i;
$numyears = (round((floor($maya) / $revolutionsperyear),0));
$avg_num_month $ttl_num_months/$i;
$jtl abs(abs($maya) - 
       
ceil($revolutionsperyear*($numyears+1)));

while(
$month==0){
    
$day=0;
    
$u=0;
    foreach(
$monthusage as $key => $item){
        
$t=0;   
        foreach(
$item as $numdays){
            
$t++;
            
$tt=0;
            for(
$sh=1;$sh<=$numdays;$sh++){
                
$ii=$ii+1;
                
$tt++;
                if (
$ii==floor($jtl)){
                    if (
$maya>0){
                        
$daynum $tt;
                        
$month $t;
                    } else {
                        
$daynum $numdays-$tt;
                        
$month $avg_num_month-$t;
                    }
                    
$sequence $key;
                    
$nodaycount=true;
                }
            }
            if (
$nodaycount==false)
                
$day++;
        }
        
$u++;
    }
}

$timer substr($mayastrpos($maya,'.')+1,
         
strlen($maya)-strpos($maya,'.')-1);
$maya_out$numyears.'/'.$month.'/'.$daynum.' '.$day.'.'
  
floor(intval(substr($timer,0,2))/100*$timeset['hours']).':'
  
floor(intval(substr($timer,2,2))/100*$timeset['minutes']).':'
  
floor(intval(substr($timer,4,2))/100*$timeset['seconds']).'.'.
  
substr($timer,6,strlen($timer)-6);

$maya_obj = array(
  
'longcount'=>MayanLongCount($tme),'year'=>abs($numyears),
  
'month'=>$month'mname' => $monthnames[$sequence][$month-1],
  
'day'=>$daynum'dayname'=>$daynames[$sequence][$daynum-1], 
  
'day'=>$daynum'jtl'=>$jtl'day_count'=>$day,
  
'hours'=>     floor(intval(substr($timer,0,2))/100
             
*$timeset['hours']),
  
'minute'=> floor(intval(substr($timer,2,2))/100
             
*$timeset['minutes']),
  
'seconds'=>floor(intval(substr($timer,4,2))/100
             
*$timeset['seconds']),
  
'microtime'=>substr($timer,6,strlen($timer)-6),
  
'strout'=>$maya_out);

return 
$maya_obj;
}

?>

[#4] simon at chronolabs dot org dot au [2007-11-07 22:00:11]

This will return the mayan long count calendar which cycle reaches 13.0.0.0.0 in 2012, I have had to compress the changemaya function for this code library so if you want to space it out your more than welcome. It works with unix time. To call the routine use the following syntax. The mayan calendar is a day count that is around 5000 years old, it tracks our cestial position in the galaxy 

<?php

echo MayanLongCount(time());

function 
MayanLongCount($tme){
    
    
$config = array('ppo' => array(13,0,0,0,0),
                    
'epoch' => strtotime('2012-12-21'));

    
$diff=(($tme-$config['epoch'])/(60*60*24));
    
$ppo changemaya($config['ppo'],ceil($diff));

    return 
$ppo[0].'.'.$ppo[1].'.'.$ppo[2].'.'.$ppo[3].'.'.$ppo[4];
}

function 
changemaya($ppo,$diff){
if (
$diff>0) { $amount=1; } else { $amount=-1; }
for (
$sh=1;$sh<abs($diff);$sh++){ if ($ppo[4]+$amount>20){
if (
$ppo[3]+$amount>20){ if ($ppo[2]+$amount>20){
if (
$ppo[1]+$amount>20){ if ($ppo[0]+$amount>20){
$ppo[0]=0$ppo[1]=0$ppo[2]=0$ppo[3]=0$ppo[4]=0;
} else { 
$ppo[1]=0$ppo[0]=$ppo[0]+$amount;}        
} else { 
$ppo[2]=0$ppo[1]=$ppo[1]+$amount;    }        
} else {
$ppo[3]=0$ppo[2]=$ppo[2]+$amount; }
} else { 
$ppo[4]=0$ppo[3]=$ppo[3]+$amount; }
} elseif (
$ppo[4]+$amount<0){ if ($ppo[3]+$amount<0){
if (
$ppo[2]+$amount<0){    if ($ppo[1]+$amount<0){
if (
$ppo[0]+$amount<0){    $ppo[0]=20;    $ppo[1]=0
$ppo[2]=0$ppo[3]=0$ppo[4]=0;
} else { 
$ppo[1]=20$ppo[0]=$ppo[0]+$amount; }        
} else { 
$ppo[2]=20$ppo[1]=$ppo[1]+$amount; }        
} else { 
$ppo[3]=20$ppo[2]=$ppo[2]+$amount; }
} else { 
$ppo[4]=20$ppo[3]=$ppo[3]+$amount; }
} else { 
$ppo[4]=$ppo[4]+$amount;}}
    return 
$ppo;
}

?>


Thanks!!

[#5] schotm29 at hotmail dot com [2007-09-07 06:00:09]

fRay Fergusons light reimplimentation doesn't work all of the time, because of the inaccuracy in the calculations (it is quite accurate but not accurate enough for a live web app)

[#6] david dot scourfield at llynfi dot co dot uk [2007-08-17 03:13:48]

I created this function a while ago and needed it again recently, so had to trawl through some old files to find it. Thought I'd post it here in case anyone else finds it useful.

<?php



function calculateBankHolidays($yr) {

    
$bankHols = Array();

    
// New year's:
    
switch ( date("w"strtotime("$yr-01-01 12:00:00")) ) {
        case 
6:
            
$bankHols[] = "$yr-01-03";
            break;
        case 
0:
            
$bankHols[] = "$yr-01-02";
            break;
        default:
            
$bankHols[] = "$yr-01-01";
    }

    
// Good friday:
    
$bankHols[] = date("Y-m-d"strtotime"+".(easter_days($yr) - 2)." days"strtotime("$yr-03-21 12:00:00") ));

    
// Easter Monday:
    
$bankHols[] = date("Y-m-d"strtotime"+".(easter_days($yr) + 1)." days"strtotime("$yr-03-21 12:00:00") ));

    
// May Day:
    
if ($yr == 1995) {
        
$bankHols[] = "1995-05-08"// VE day 50th anniversary year exception
    
} else {
        switch (
date("w"strtotime("$yr-05-01 12:00:00"))) {
            case 
0:
                
$bankHols[] = "$yr-05-02";
                break;
            case 
1:
                
$bankHols[] = "$yr-05-01";
                break;
            case 
2:
                
$bankHols[] = "$yr-05-07";
                break;
            case 
3:
                
$bankHols[] = "$yr-05-06";
                break;
            case 
4:
                
$bankHols[] = "$yr-05-05";
                break;
            case 
5:
                
$bankHols[] = "$yr-05-04";
                break;
            case 
6:
                
$bankHols[] = "$yr-05-03";
                break;
        }
    }

    
// Whitsun:
    
if ($yr == 2002) { // exception year
        
$bankHols[] = "2002-06-03";
        
$bankHols[] = "2002-06-04";
    } else {
        switch (
date("w"strtotime("$yr-05-31 12:00:00"))) {
            case 
0:
                
$bankHols[] = "$yr-05-25";
                break;
            case 
1:
                
$bankHols[] = "$yr-05-31";
                break;
            case 
2:
                
$bankHols[] = "$yr-05-30";
                break;
            case 
3:
                
$bankHols[] = "$yr-05-29";
                break;
            case 
4:
                
$bankHols[] = "$yr-05-28";
                break;
            case 
5:
                
$bankHols[] = "$yr-05-27";
                break;
            case 
6:
                
$bankHols[] = "$yr-05-26";
                break;
        }
    }

    
// Summer Bank Holiday:
    
switch (date("w"strtotime("$yr-08-31 12:00:00"))) {
        case 
0:
            
$bankHols[] = "$yr-08-25";
            break;
        case 
1:
            
$bankHols[] = "$yr-08-31";
            break;
        case 
2:
            
$bankHols[] = "$yr-08-30";
            break;
        case 
3:
            
$bankHols[] = "$yr-08-29";
            break;
        case 
4:
            
$bankHols[] = "$yr-08-28";
            break;
        case 
5:
            
$bankHols[] = "$yr-08-27";
            break;
        case 
6:
            
$bankHols[] = "$yr-08-26";
            break;
    }

    
// Christmas:
    
switch ( date("w"strtotime("$yr-12-25 12:00:00")) ) {
        case 
5:
            
$bankHols[] = "$yr-12-25";
            
$bankHols[] = "$yr-12-28";
            break;
        case 
6:
            
$bankHols[] = "$yr-12-27";
            
$bankHols[] = "$yr-12-28";
            break;
        case 
0:
            
$bankHols[] = "$yr-12-26";
            
$bankHols[] = "$yr-12-27";
            break;
        default:
            
$bankHols[] = "$yr-12-25";
            
$bankHols[] = "$yr-12-26";
    }

    
// Millenium eve
    
if ($yr == 1999) {
        
$bankHols[] = "1999-12-31";
    }

    return 
$bankHols;

}



header("Content-type: text/plain"); 

$bankHolsThisYear calculateBankHolidays(2007);

print_r($bankHolsThisYear);

?>


Will output this result:

Array
(
    [0] => 2007-01-01
    [1] => 2007-04-06
    [2] => 2007-04-09
    [3] => 2007-05-07
    [4] => 2007-05-28
    [5] => 2007-08-27
    [6] => 2007-12-25
    [7] => 2007-12-26
)

[#7] amichauer at gmx dot de [2005-06-27 21:46:12]

<?php

class HijriCalendar
{
    function 
monthName($i// $i = 1..12
    
{
        static 
$month  = array(
            
"M?x?rr?m""Safar""Rabig-?l-?ww?l""Rabig-?l-Ax?r",
            
"C?m?d-?l-?ww?l""C?m?d-?l-Ax?r""Rac?b""???b?n",
            
"Ramazan""??w?l""Z?-?l-Q??d?""Z?-?l-Xicc?"
        
);
        return 
$month[$i-1];
    }

    function 
GregorianToHijri($time null)
    {
        if (
$time === null$time time();
        
$m date('m'$time);
        
$d date('d'$time);
        
$y date('Y'$time);

        return 
HijriCalendar::JDToHijri(
            
cal_to_jd(CAL_GREGORIAN$m$d$y));
    }

    function 
HijriToGregorian($m$d$y)
    {
        return 
jd_to_cal(CAL_GREGORIAN,
            
HijriCalendar::HijriToJD($m$d$y));
    }

    
# Julian Day Count To Hijri
    
function JDToHijri($jd)
    {
        
$jd $jd 1948440 10632;
        
$n  = (int)(($jd 1) / 10631);
        
$jd $jd 10631 $n 354;
        
$j  = ((int)((10985 $jd) / 5316)) *
            ((int)(
50 $jd 17719)) +
            ((int)(
$jd 5670)) *
            ((int)(
43 $jd 15238));
        
$jd $jd - ((int)((30 $j) / 15)) *
            ((int)((
17719 $j) / 50)) -
            ((int)(
$j 16)) *
            ((int)((
15238 $j) / 43)) + 29;
        
$m  = (int)(24 $jd 709);
        
$d  $jd - (int)(709 $m 24);
        
$y  30*$n $j 30;

        return array(
$m$d$y);
    }

    
# Hijri To Julian Day Count
    
function HijriToJD($m$d$y)
    {
        return (int)((
11 $y 3) / 30) +
            
354 $y 30 $m -
            (int)((
$m 1) / 2) + $d 1948440 385;
    }
};

$hijri HijriCalendar::GregorianToHijritime() );
echo 
$hijri[1].'. '.HijriCalendar::monthName($hijri[0]).' '.$hijri[2];

?>

[#8] jthome at fcgov dot com [2003-10-02 11:38:55]

Had a similar problem as curlee, except I needed to create a JDE_ERP date.  [format is CYYDDD]

<?php

function jde_date_create($month$day$year){
    

    
$jde_year_prefix substr($year01) - 1;
    
$jde_year_suffix substr($year, -2);
    
    
//note that valid years for mktime are 1902-2037
    
$timestamp mktime(0,0,0,$month$day$year);
    
$baseline_timestamp mktime(0,0,0,1,0,$year);
    
    
$day_count round(($timestamp $baseline_timestamp)/86400);
    
$day_count_padded str_pad($day_count,3,"0",STR_PAD_LEFT);

    return (
$jde_year_prefix $jde_year_suffix $day_count_padded);
    
}

echo 
jde_date_create(6,25,2000);// will return '103176'

?>


--
Jim

[#9] curlee at mindspring dot com [2003-08-29 08:55:20]

I solved a problem with Julian dates that are used in the JD Edwards ERP package (running on AS/400).  The Julian format for this system is as follows:  CYYDDD 

Where C is 0 for 1900 and 1 for 2000
DDD is the day of the year count

I used the mktime built-in php function to convert dates to the normal DD/MM/YYYY format.  This function will convert dates that are between 1970 and 2038 (limitation of unix timestamps and the mktime function)

The $jde_date var needs to be a 6 len STRING.... if you use a numeric var type it will drop the leading 0 for any date that represents 1900.... this will botch the substr functions and thus make the whole thing wrong.  

<?php
function jde_date_conv($jde_date)
{

$ct substr($jde_date,0,1);
$yr substr($jde_date,1,2);
$dy substr($jde_date,3,3);

if(
$ct == 0$yr_pfx 19;
if(
$ct == 1$yr_pfx 20;

$tlt_yr $yr_pfx.$yr;

$base_time mktime(0,0,0,1,0,$tlt_yr);

$unix_time = ($dy 86400) + $base_time;

return 
date("m/d/Y" $unix_time);
}
?>

上一篇: 下一篇: