PHP:判断日期减去周末和节假日
PHP: determination of the date minus weekends and holidays
有一个 WordPress 和 ACF 字段,日期格式为 2022-04-30。从这个日期开始,需要计算另外 2 个日期,-2 天和 +25 天。问题是只需要考虑工作日,即检查周末和节假日。
比如我们设置日期2022年5月3日,也就是星期二。从这个日期开始,我需要减去2天,即2022年5月1日,但这是星期天,所以我们必须return到5月1日之前的第一个工作日,即2022年4月29日星期五。是一样的有假期。
目前我有这个代码:
$setDate = get_field('set_date'); // ACF field, set May 3, 2022 (2022-05-03)
$offDate = wp_date('j F Y', strtotime('-2 days', strtotime($setDate)));
echo $offDate; // returns Sunday, May 1, 2022
我在 json https://github.com/d10xa/holidays-calendar/blob/master/json/consultant2022.json
找到假期和周末
所以我需要将给定日期与 json 中的日期进行比较,如果匹配,则减去一天并再次检查收到的日期。如果有匹配项,则再次减去一天,依此类推,直到找不到匹配项。我的想法是否正确,你能告诉我如何实施吗?我是一个非常糟糕的程序员,但是有一个任务)
目前我只能比较日期和 return 找到的结果 found/not。但是想不通怎么在这个基础上请假,再发来验证(
$setDate = '2022-05-01';
$file = file_get_contents('https://raw.githubusercontent.com/d10xa/holidays-calendar/master/json/consultant2022.json', true);
$data = json_decode($file);
$found = array_search($setDate, $data->holidays);
if ($found === False) {
echo 'Not Found';
} else {
echo 'found';
}
以下内容已经过几个日期的测试,我认为它可以正常工作。
/*
JSON file is saved locally to a sub-directory
for the current working script directory.
This is to avoid unneccessary hits to the
remote site.
*/
$format='Y-m-d';
$url='https://raw.githubusercontent.com/d10xa/holidays-calendar/master/json/consultant2022.json';
$setDate = '2022-05-01';
$filepath=sprintf('%s/json/%s', __DIR__, basename( $url ) );
if( !file_exists( $filepath ) ){
file_put_contents( $filepath, file_get_contents( $url ) );
}
# read the file and generate JSON
$json=json_decode( file_get_contents( $filepath ) );
$hols=$json->holidays;
# create the initial DateTime object and find which weekday we are dealing with
# where 1 (for Monday) through 7 (for Sunday)
$obj=new DateTime( $setDate );
$date=$obj->format( $format );
$day=$obj->format('N');
# Is the given date a holiday/weekend?
if( array_search( $date, $hols ) ){
if( $day > 5 ){
# Date is either Sat or Sun... go back to previous working day
$subtract = 2 - ( 7 - $day );
$int=new DateInterval( sprintf('P%sD', $subtract ) );
$obj=new DateTime( $setDate );
$previous=$obj->sub( $int );
}else{
$previous=$obj->sub( new DateInterval('P2D') );
}
# create the future date ( add 25 days )
$int=new DateInterval('P25D');
$obj=new DateTime( $setDate );
$future=$obj->add( $int );
if( array_search( $future->format( $format ), $hols ) ){
# Future date is a holiday... go back to previous working day
$day=$future->format('N');
$subtract = 2 - ( 7 - $day );
$int=new DateInterval( sprintf('P%sD',$subtract ) );
$future=$future->sub( $int );
}
}else{
# Given date is NOT a holiday...
# take a copy of the original DateTime object for generating future date.
$ref=new DateTime( $setDate );
$int=new DateInterval( 'P2D' );
$previous=$obj->sub( $int );
$day=$previous->format('N');
# Is this a holiday?
if( $day > 5 ){
# yes - go back to previous working day
$subtract = 2 - ( 7 - $day );
$int=new DateInterval( sprintf('P%sD',$subtract ) );
$previous=$previous->sub( $int );
}
$int=new DateInterval('P25D');
$future=$ref->add( $int );
$day=$future->format('N');
# Is this a holiday?
if( $day > 5 ){
$subtract = 2 - ( 7 - $day );
$int=new DateInterval( sprintf('P%sD',$subtract ) );
$future=$future->sub( $int );
}
}
printf(
'<pre>
Given date: %s
Previous (-2): %s
Future (+25): %s
</pre>',
$date,
$previous->format( $format ),
$future->format( $format )
);
产生:
Given date: 2022-05-01
Previous (-2): 2022-04-29
Future (+25): 2022-05-26
有一个 WordPress 和 ACF 字段,日期格式为 2022-04-30。从这个日期开始,需要计算另外 2 个日期,-2 天和 +25 天。问题是只需要考虑工作日,即检查周末和节假日。
比如我们设置日期2022年5月3日,也就是星期二。从这个日期开始,我需要减去2天,即2022年5月1日,但这是星期天,所以我们必须return到5月1日之前的第一个工作日,即2022年4月29日星期五。是一样的有假期。
目前我有这个代码:
$setDate = get_field('set_date'); // ACF field, set May 3, 2022 (2022-05-03)
$offDate = wp_date('j F Y', strtotime('-2 days', strtotime($setDate)));
echo $offDate; // returns Sunday, May 1, 2022
我在 json https://github.com/d10xa/holidays-calendar/blob/master/json/consultant2022.json
找到假期和周末所以我需要将给定日期与 json 中的日期进行比较,如果匹配,则减去一天并再次检查收到的日期。如果有匹配项,则再次减去一天,依此类推,直到找不到匹配项。我的想法是否正确,你能告诉我如何实施吗?我是一个非常糟糕的程序员,但是有一个任务)
目前我只能比较日期和 return 找到的结果 found/not。但是想不通怎么在这个基础上请假,再发来验证(
$setDate = '2022-05-01';
$file = file_get_contents('https://raw.githubusercontent.com/d10xa/holidays-calendar/master/json/consultant2022.json', true);
$data = json_decode($file);
$found = array_search($setDate, $data->holidays);
if ($found === False) {
echo 'Not Found';
} else {
echo 'found';
}
以下内容已经过几个日期的测试,我认为它可以正常工作。
/*
JSON file is saved locally to a sub-directory
for the current working script directory.
This is to avoid unneccessary hits to the
remote site.
*/
$format='Y-m-d';
$url='https://raw.githubusercontent.com/d10xa/holidays-calendar/master/json/consultant2022.json';
$setDate = '2022-05-01';
$filepath=sprintf('%s/json/%s', __DIR__, basename( $url ) );
if( !file_exists( $filepath ) ){
file_put_contents( $filepath, file_get_contents( $url ) );
}
# read the file and generate JSON
$json=json_decode( file_get_contents( $filepath ) );
$hols=$json->holidays;
# create the initial DateTime object and find which weekday we are dealing with
# where 1 (for Monday) through 7 (for Sunday)
$obj=new DateTime( $setDate );
$date=$obj->format( $format );
$day=$obj->format('N');
# Is the given date a holiday/weekend?
if( array_search( $date, $hols ) ){
if( $day > 5 ){
# Date is either Sat or Sun... go back to previous working day
$subtract = 2 - ( 7 - $day );
$int=new DateInterval( sprintf('P%sD', $subtract ) );
$obj=new DateTime( $setDate );
$previous=$obj->sub( $int );
}else{
$previous=$obj->sub( new DateInterval('P2D') );
}
# create the future date ( add 25 days )
$int=new DateInterval('P25D');
$obj=new DateTime( $setDate );
$future=$obj->add( $int );
if( array_search( $future->format( $format ), $hols ) ){
# Future date is a holiday... go back to previous working day
$day=$future->format('N');
$subtract = 2 - ( 7 - $day );
$int=new DateInterval( sprintf('P%sD',$subtract ) );
$future=$future->sub( $int );
}
}else{
# Given date is NOT a holiday...
# take a copy of the original DateTime object for generating future date.
$ref=new DateTime( $setDate );
$int=new DateInterval( 'P2D' );
$previous=$obj->sub( $int );
$day=$previous->format('N');
# Is this a holiday?
if( $day > 5 ){
# yes - go back to previous working day
$subtract = 2 - ( 7 - $day );
$int=new DateInterval( sprintf('P%sD',$subtract ) );
$previous=$previous->sub( $int );
}
$int=new DateInterval('P25D');
$future=$ref->add( $int );
$day=$future->format('N');
# Is this a holiday?
if( $day > 5 ){
$subtract = 2 - ( 7 - $day );
$int=new DateInterval( sprintf('P%sD',$subtract ) );
$future=$future->sub( $int );
}
}
printf(
'<pre>
Given date: %s
Previous (-2): %s
Future (+25): %s
</pre>',
$date,
$previous->format( $format ),
$future->format( $format )
);
产生:
Given date: 2022-05-01
Previous (-2): 2022-04-29
Future (+25): 2022-05-26