PHP Conference Japan 2024

日历函数

目录

  • cal_days_in_month — 返回指定年份和日历的月份的天数
  • cal_from_jd — 将儒略日转换为支持的日历
  • cal_info — 返回有关特定日历的信息
  • cal_to_jd — 将支持的日历转换为儒略日
  • easter_date — 获取指定年份复活节当天的 Unix 时间戳(当地午夜)
  • easter_days — 获取指定年份复活节在 3 月 21 日之后的几天
  • frenchtojd — 将法国共和历日期转换为儒略日
  • gregoriantojd — 将公历日期转换为儒略日
  • jddayofweek — 返回一周中的某一天
  • jdmonthname — 返回月份名称
  • jdtofrench — 将儒略日转换为法国共和历
  • jdtogregorian — 将儒略日转换为公历日期
  • jdtojewish — 将儒略日转换为犹太历日期
  • jdtojulian — 将儒略日转换为儒略历日期
  • jdtounix — 将儒略日转换为 Unix 时间戳
  • jewishtojd — 将犹太历日期转换为儒略日
  • juliantojd — 将儒略历日期转换为儒略日
  • unixtojd — 将 Unix 时间戳转换为儒略日
添加注释

用户贡献的注释 8 条注释

david dot scourfield at llynfi dot co dot uk
17 年前
我很久以前创建了这个函数,最近又需要它,所以不得不翻阅一些旧文件才能找到它。我想我会把它发布在这里,以防其他人发现它有用。



<?php

/*
* 用于计算给定年份英国银行假日(英格兰和威尔士)的函数。
*
* 由 David Scourfield 于 2006 年 8 月 7 日创建,并发布到公共领域。
* 任何人都可以使用和/或修改此代码。
*
* 用法:
*
* array calculateBankHolidays(int $yr)
*
* 参数
*
* $yr = 年份的 4 位数字表示(例如 1997)。
*
* 返回值
*
* 返回一个字符串数组,其中每个字符串都是银行假日的日期,格式为“yyyy-mm-dd”。
*
* 请参阅下面的示例
*
*/

function calculateBankHolidays($yr) {

$bankHols = Array();

// 元旦:
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";
}

// 好星期五:
$bankHols[] = date("Y-m-d", strtotime( "+".(easter_days($yr) - 2)." days", strtotime("$yr-03-21 12:00:00") ));

// 复活节星期一:
$bankHols[] = date("Y-m-d", strtotime( "+".(easter_days($yr) + 1)." days", strtotime("$yr-03-21 12:00:00") ));

// 五月节:
if ($yr == 1995) {
$bankHols[] = "1995-05-08"; // 欧洲胜利日 50 周年纪念日例外
} 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;
}
}

// 圣灵降临节:
if ($yr == 2002) { // 例外年份
$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;
}
}

// 夏日银行假日:
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;
}

// 圣诞节:
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";
}

// 千禧夜
if ($yr == 1999) {
$bankHols[] = "1999-12-31";
}

return
$bankHols;

}

/*
* 示例:
*
*/

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

$bankHolsThisYear = calculateBankHolidays(2007);

print_r($bankHolsThisYear);

?>

将输出以下结果

数组
(
[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
)
obaida dot habboush at gmail dot com
7 年前
您好,

函数名称有错误

在类 HijriCalendar 中 {
.
.
.
.
.
.
函数 HijriToGregorian($m, $d, $y)
{
//// jd_to_cal -> 应为 -> cal_to_jd
return jd_to_cal(CAL_GREGORIAN, HijriCalendar::HijriToJD($m, $d, $y));
}
}
jthome at fcgov dot com
21 年前
遇到了与 curlee 类似的问题,除了我需要创建一个 JDE_ERP 日期。[格式为 CYYDDD]

<?php

function jde_date_create($month, $day, $year){
/*
* 注意:$month 和 $day 不能有前导零,
* $year 必须为'YYYY' 格式
*/
$jde_year_prefix = substr($year, 0, 1) - 1;
$jde_year_suffix = substr($year, -2);

//注意 mktime 函数有效的年份范围是 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);// 将返回 '103176'

?>

--
Jim
simon at chronolabs dot org dot au
17 年前
这是埃及历法,它是地球上第一个365天的历法,它没有闰年,这使得它有点不准确,但您可以根据需要自行实现此代码,这是对roun浮点代码的另一种实现,它是一个用于生成日期编解码器的通用代码,您可以用此代码创建几乎所有的日历,$pweight 基于我对碳年代测定等的研究,以及埃及纪元或PPO的创建时间,一些人认为是几千年,而另一些人则认为埃及纪元大约在30000年前!这是基于海平面上升后,在该地区被水覆盖后,雕像和纪念碑上的潮汐标记。

<?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 – 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 – 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 – 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($egypt, strpos($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;
}

?>

顺便说一下,在我之前关于玛雅蒂卡尔历法的帖子中,函数的顶部部分在我的代码剪切粘贴中被截断了,这就是函数的行,它看起来像,前三行需要替换为

<?php

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

function
MayanTikalCalendar($unix_time, $gmt,

?>
amichauer at gmx dot de
19年前

<?php

class HijriCalendar
{
function
monthName($i) // $i = 1..12
{
static
$month = array(
"穆哈兰", "萨法尔", "莱比一世", "莱比二世",
"朱麦达一世", "朱麦达二世", "拉贾布", "沙班",
"斋月", "朝月", "都尔黑哲", "都尔希杰"
);
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));
}

# 儒略日计数到伊斯兰历
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);
}

# 伊斯兰历到儒略日计数
function HijriToJD($m, $d, $y)
{
return (int)((
11 * $y + 3) / 30) +
354 * $y + 30 * $m -
(int)((
$m - 1) / 2) + $d + 1948440 - 385;
}
};

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

?>
[email protected]
17 年前
<?php

// 您需要替换埃及历和玛雅蒂卡尔历函数中的这段代码
// 以及玛雅蒂卡尔历函数
$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++;
}
}
?>

这段代码需要在计算中进行更改,我今天在我们的RounCalendar中注意到出现了一个零日,此函数将为日历正确计算月份和日期,它是一段非常通用的代码,很抱歉它没有得到充分的测试,需要一些重构。
[email protected]
17 年前
这将返回玛雅长纪历,该周期在2012年达到13.0.0.0.0,我不得不为此代码库压缩changemaya函数,因此如果您想将其展开,非常欢迎。它使用Unix时间。要调用例程,请使用以下语法。玛雅历是一种大约有5000年历史的日期计数,它跟踪我们在银河系中的天体位置

<?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;
}

?>

谢谢!
curlee at mindspring dot com
21 年前
我解决了一个与 JD Edwards ERP 软件包(在 AS/400 上运行)中使用的儒略日期相关的问题。此系统的儒略日期格式如下:CYYDDD

其中 C 为 0 表示 1900 年,1 表示 2000 年
DDD 为一年中的天数

我使用了内置的 php 函数 mktime 将日期转换为正常的 DD/MM/YYYY 格式。此函数将转换 1970 年到 2038 年之间的日期(unix 时间戳和 mktime 函数的限制)

变量 $jde_date 需要是长度为 6 的字符串……如果使用数字变量类型,则对于表示 1900 年的任何日期,它都会删除前导 0……这将破坏 substr 函数,从而使整个过程出错。

<?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);
}
?>
To Top