我目前正在开发一个在线订阅应用程序。我在用户选择订阅天数和开始日期的部分遇到了一些挑战。然后,PHP 应用程序应该能够计算除周末之外的结束日期。
<form method="post">
<input name="startdate" type="text" />
<input name="numberofdays" type="text" />
</form>
有人可以帮助我吗?
取决于startdate
的发送方式,但假设您使用的是 Y-m-d,您可以使用 DateTime
例如:
<?php
$_POST['startdate'] = '2012-08-14';
$_POST['numberofdays'] = 10;
$d = new DateTime( $_POST['startdate'] );
$t = $d->getTimestamp();
// loop for X days
for($i=0; $i<$_POST['numberofdays']; $i++){
// add 1 day to timestamp
$addDay = 86400;
// get what day it is next day
$nextDay = date('w', ($t+$addDay));
// if it's Saturday or Sunday get $i-1
if($nextDay == 0 || $nextDay == 6) {
$i--;
}
// modify timestamp, add 1 day
$t = $t+$addDay;
}
$d->setTimestamp($t);
echo $d->format( 'Y-m-d' ). "'n";
?>
相同的结果,较短的版本:
function addDays($days,$format="Y-m-d"){
for($i=0;$i<$days;$i++){
$day = date('N',strtotime("+".($i+1)."day"));
if($day>5)
$days++;
}
return date($format,strtotime("+$i day"));
}
轮到我提出一个解决此问题的函数:)
public static function addDaysToDate($startDate, $daysToAdd)
{
// loop for X days
for ($i = 0; $i < $daysToAdd; $i++) {
// get what day it is next day
$nextDay = $startDate->modify('+1 day');
// if it's Saturday or Sunday get $i-1
if (in_array($nextDay->format('w'), [0, 6]) || self::isHoliday($nextDay->getTimestamp())) {
$i--;
}
}
return $nextDay;
}
isHoliday函数正在确定这一天是否为公共假期:
/**
* Fonction permettant de retour la date de Pâques au format timestamp
*/
public static function easterDate($year)
{
$a = $year % 4;
$b = $year % 7;
$c = $year % 19;
$m = 24;
$n = 5;
$d = (19 * $c + $m ) % 30;
$e = (2 * $a + 4 * $b + 6 * $d + $n) % 7;
$easterdate = 22 + $d + $e;
if ($easterdate > 31) {
$day = $d + $e - 9;
$month = 4;
} else {
$day = 22 + $d + $e;
$month = 3;
}
if ($d == 29 && $e == 6) {
$day = 10;
$month = 04;
} elseif ($d == 28 && $e == 6) {
$day = 18;
$month = 04;
}
return mktime(0, 0, 0, $month, $day, $year);
}
/**
* Fonction permettant de retourner les jours fériés d'une année passée en paramètre
*/
public static function publicHolidays($year)
{
if ($year === null) {
$year = intval(strftime('%Y'));
}
$easterDate = self::easterDate($year);
$easterDay = date('j', $easterDate);
$easterMonth = date('n', $easterDate);
$easterYear = date('Y', $easterDate);
$holidays = array(
// Jours fériés fixes
mktime(0, 0, 0, 1, 1, $year),// 1er janvier
mktime(0, 0, 0, 5, 1, $year),// Fête du travail
mktime(0, 0, 0, 5, 9, $year),// Fête de l'Europe
mktime(0, 0, 0, 6, 23, $year),// Fête nationale
mktime(0, 0, 0, 8, 15, $year),// Assomption
mktime(0, 0, 0, 11, 1, $year),// Toussaint
mktime(0, 0, 0, 12, 25, $year),// Noël
mktime(0, 0, 0, 12, 26, $year),// Saint-Etienne
// Jour fériés qui dépendent de Pâques
mktime(0, 0, 0, $easterMonth, $easterDay + 1, $easterYear),// Lundi de Pâques
mktime(0, 0, 0, $easterMonth, $easterDay + 39, $easterYear),// Ascension
mktime(0, 0, 0, $easterMonth, $easterDay + 50, $easterYear), // Pentecôte
);
sort($holidays);
return $holidays;
}
/**
* Fonction permettant de savoir si un timestamp d'une date passée en paramètre est férié ou pas
*/
public static function isHoliday($timestamp)
{
$iYear = strftime('%Y', $timestamp);
$aHolidays = self::publicHolidays($iYear);
/*
* On est obligé de convertir les timestamps en string à cause des décalages horaires.
*/
$aHolidaysString = array_map(function ($value) {
return strftime('%Y-%m-%d', $value);
}, $aHolidays);
if (in_array(strftime('%Y-%m-%d', $timestamp), $aHolidaysString)) {
return true;
}
return false;
}
希望对您有所帮助!
此致敬意
埃内斯
我今天开发了一个新功能,可以帮助有此类问题的人。
function sumDays($days = 0, $format = 'd/m/Y') {
$incrementing = $days > 0;
$days = abs($days);
$actualDate = date('Y-m-d');
while ($days > 0) {
$tsDate = strtotime($actualDate . ' ' . ($incrementing ? '+' : '-') . ' 1 days');
$actualDate = date('Y-m-d', $tsDate);
if (date('N', $tsDate) < 6) {
$days--;
}
}
return date($format, strtotime($actualDate));
}
我今天开发了一个新功能,可以帮助有这种问题的人。取决于开始日期的发送方式,但假设您使用的是 Y-m-d,则可以使用 DateTime
<?php public static function getOrderEndDate( $start_date, $orderDaysCode ){
$saturday_off = false;
if( $orderDaysCode == 'meal_monthly_6' ) { $orderDays = 24; }
elseif( $orderDaysCode == 'meal_monthly_5' ) {
$orderDays = 20;
$saturday_off = true;
}elseif( $orderDaysCode == 'meal_weekly' ) {
$orderDays = 5;
$saturday_off = true;
}
else{ $orderDays = 1; } // Daily Meal
$formatted_date = new DateTime( $start_date );
$date_timestamp = $formatted_date->getTimestamp();
// loop for X days
for( $i = 0; $i < ( $orderDays - 1 ); $i++ ) {
// get what day it is next day
$nextDay = date('w', strtotime('+1day', $date_timestamp) );
// if it's Sunday or Saturday get $i-1
if( $nextDay == 0 || ( $nextDay == 6 && $saturday_off ) ) { $i--; }
// modify timestamp, add 1 day
$date_timestamp = strtotime('+1day', $date_timestamp);
}
$formatted_date->setTimestamp($date_timestamp);
return $formatted_date->format( 'Y-m-d' );
}
$orderEndDate = getOrderEndDate( '2020-06-17', 'meal_monthly_6' ); ?>
我来这里寻找解决方案。最后,我找到了一个单线解决方案。
<?php
echo date('d/m/Y',strtotime("+10 weekdays"));
?>