在月底和月初之间,与具体年份无关
Between late month and early month, without regards to specific year
要显示 "current season" 可用的农产品,我可以问:
是('Y-m-d',strtotime('today'))
大于$start_of_season
小于$end_of_season
,只要开始日期在结束日期之前,逻辑就很简单。
$date_format = 'Y-m-d';
if ((date_i18n($date_format,strtotime('today')) > date_i18n($date_format,strtotime($start_of_season))) &&
(date_i18n($date_format,strtotime('today')) < date_i18n($date_format,strtotime($end_of_season)))):
# display the produce
但是如果我想忽略 11 月和 2 月之间的年份和度量值怎么办?如果今天是 12 月 1 日,则大于 11 月,但也大于 2 月。
我的第一个尝试是说,
如果 end_date 大于 start_date
- 如果今天是下半年
- 然后调用end_date 12-31
- 其他
- 致电start_date01-01
这是代码:
$date_format = 'm-d';
if (date_i18n($date_format,strtotime($start_of_season)) > date_i18n($date_format,strtotime($end_of_season))):
if (date_i18n($date_format,strtotime('today')) > date_i18n($date_format,strtotime('2000-06-01'))):
$end_of_season = '2000-12-31';
else:
$start_of_season = '2000-01-01';
endif;
endif;
if ((date_i18n($date_format,strtotime('today')) > date_i18n($date_format,strtotime($start_of_season))) &&
(date_i18n($date_format,strtotime('today')) < date_i18n($date_format,strtotime($end_of_season)))):
大多数情况下 "work"。
但是如果有一个项目的季节是 12 月到 7 月并且当前日期是 7 月 1 日,那么就会有一个 $start_of_season > $end_of_season
,但是因为它在 6 月 1 日之后 $end_of_season
将被设置到 12 月 31 日,将我们置于 "in_season" 显示 window.
之外
我确信有合理的 eloquent 方法可以做到这一点,并且可以提供一些启示。
您可以构建允许的月份数组。然后检查月份是否在允许的月份数组中。如果是,您只需要检查您是在本赛季的第一个月还是最后一个月。如果在第一个月,您必须检查该日期是否大于或等于开始日期。如果在上个月你必须检查日期是否小于或等于结束日期。
这是一个代码示例:
function getMonthArray($startMonth, $endMonth) {
$return = array();
$return[] = $startMonth;
while($startMonth != $endMonth) {
$startMonth++;
if ($startMonth > 12) {
$startMonth = 1;
}
$return[] = $startMonth;
}
return $return;
}
function isInSeason($start, $end, $check) {
$month = (int) substr($check, 0, 2);
$startMonth = (int) substr($start, 0, 2);
$endMonth = (int) substr($end, 0, 2);
if (in_array($month, getMonthArray($startMonth, $endMonth))) {
$day = (int) substr($check, 3, 2);
if ($month == $startMonth) {
$startDay = (int) substr($start, 3, 2);
return ($day >= $startDay);
} elseif ($month == $endMonth) {
$endDay = (int) substr($end, 3, 2);
return ($day <= $endDay);
} else {
return TRUE;
}
}
return FALSE;
}
$start = '12-01';
$end = '06-30';
$check = '07-10';
if (isInSeason($start, $end, $check)) {
echo 'In season';
} else {
echo 'Not in season';
}
您可以将您的月份正常化为赛季开始。例如,如果您的季节开始于 11 月(第 11 个月),结束于 2 月(第 2 个月),则它们将分别标准化为第 1 个月和第 4 个月。然后你可以检查任何月份与标准化年份的对比,看看它是否在季节内。
$startMonth = 11; // November
$endMonth = 2; // February
$futureFactor = $startMonth - 1;
$pastFactor = 13 - $startMonth;
$months = [];
// Create a normalized year to the start month.
foreach (range(1,12) as $r) {
if ($r == $startMonth) {
$months[$r] = 1;
}
else {
$months[$r] = $r < $startMonth ? $r + $pastFactor : $r - $futureFactor;
}
}
// Check if December(12) is in season
if ($months[12] >= $months[$startMonth] && $months[12] <= $months[$endMonth]) {
print "In season...\n";
}
else {
print "Out of season...\n";
}
标准化年份示例:
Array
(
[1] => 3
[2] => 4
[3] => 5
[4] => 6
[5] => 7
[6] => 8
[7] => 9
[8] => 10
[9] => 11
[10] => 12
[11] => 1
[12] => 2
)
我个人会封装此逻辑并使用日期对象。这是我目前能想到的最简单的方法。 Class 为简洁起见,属性为 public。
<?php
date_default_timezone_set('America/New_York');
class Season {
public $startMonth;
public $startDay;
public $endMonth;
public $endDay;
public function setStart($month, $day) {
$this->startMonth = (int) $month;
$this->startDay = (int) $day;
}
public function setEnd($month, $day) {
$this->endMonth = (int) $month;
$this->endDay = (int) $day;
}
function isActiveForDate(DateTime $date) {
$seasonStartDate = new DateTime(sprintf('%d-%d-%d', $date->format('Y'), $this->startMonth, $this->startDay));
$seasonEndDate = new DateTime(sprintf('%d-%d-%d', $date->format('Y'), $this->endMonth, $this->endDay));
// Edge case
if ($this->startMonth > $this->endMonth) {
$seasonStartDate->modify('-1 year');
// This line is only useful if you wish to calculate inclusively
if ($date == $seasonStartDate || $date == $seasonEndDate) return true;
// If this condition is true, no need to calculate anything
if ($date->format('n') < $this->startMonth && $date->format('n') >= $this->endMonth) {
return false;
}
$seasonEndDate->modify('+1 year');
}
return ($date->getTimestamp() >= $seasonStartDate->getTimestamp()
&& $date->getTimestamp() <= $seasonEndDate->getTimestamp());
}
}
定义季节:
$season = new Season();
$season->setStart(11, 1);
$season->setEnd(7, 1);
并测试结果:
echo ($season->isActiveForDate(new DateTime("2000-7-2"))) ? "pass" : "fail"; // fail
echo ($season->isActiveForDate(new DateTime("2000-10-31"))) ? "pass" : "fail"; // fail
echo ($season->isActiveForDate(new DateTime("2000-11-1"))) ? "pass" : "fail"; // pass
echo ($season->isActiveForDate(new DateTime("2000-6-31"))) ? "pass" : "fail"; // pass
要显示 "current season" 可用的农产品,我可以问:
是('Y-m-d',strtotime('today'))
大于$start_of_season
小于$end_of_season
,只要开始日期在结束日期之前,逻辑就很简单。
$date_format = 'Y-m-d';
if ((date_i18n($date_format,strtotime('today')) > date_i18n($date_format,strtotime($start_of_season))) &&
(date_i18n($date_format,strtotime('today')) < date_i18n($date_format,strtotime($end_of_season)))):
# display the produce
但是如果我想忽略 11 月和 2 月之间的年份和度量值怎么办?如果今天是 12 月 1 日,则大于 11 月,但也大于 2 月。
我的第一个尝试是说,
如果 end_date 大于 start_date
- 如果今天是下半年
- 然后调用end_date 12-31
- 其他
- 致电start_date01-01
这是代码:
$date_format = 'm-d';
if (date_i18n($date_format,strtotime($start_of_season)) > date_i18n($date_format,strtotime($end_of_season))):
if (date_i18n($date_format,strtotime('today')) > date_i18n($date_format,strtotime('2000-06-01'))):
$end_of_season = '2000-12-31';
else:
$start_of_season = '2000-01-01';
endif;
endif;
if ((date_i18n($date_format,strtotime('today')) > date_i18n($date_format,strtotime($start_of_season))) &&
(date_i18n($date_format,strtotime('today')) < date_i18n($date_format,strtotime($end_of_season)))):
大多数情况下 "work"。
但是如果有一个项目的季节是 12 月到 7 月并且当前日期是 7 月 1 日,那么就会有一个 $start_of_season > $end_of_season
,但是因为它在 6 月 1 日之后 $end_of_season
将被设置到 12 月 31 日,将我们置于 "in_season" 显示 window.
我确信有合理的 eloquent 方法可以做到这一点,并且可以提供一些启示。
您可以构建允许的月份数组。然后检查月份是否在允许的月份数组中。如果是,您只需要检查您是在本赛季的第一个月还是最后一个月。如果在第一个月,您必须检查该日期是否大于或等于开始日期。如果在上个月你必须检查日期是否小于或等于结束日期。
这是一个代码示例:
function getMonthArray($startMonth, $endMonth) {
$return = array();
$return[] = $startMonth;
while($startMonth != $endMonth) {
$startMonth++;
if ($startMonth > 12) {
$startMonth = 1;
}
$return[] = $startMonth;
}
return $return;
}
function isInSeason($start, $end, $check) {
$month = (int) substr($check, 0, 2);
$startMonth = (int) substr($start, 0, 2);
$endMonth = (int) substr($end, 0, 2);
if (in_array($month, getMonthArray($startMonth, $endMonth))) {
$day = (int) substr($check, 3, 2);
if ($month == $startMonth) {
$startDay = (int) substr($start, 3, 2);
return ($day >= $startDay);
} elseif ($month == $endMonth) {
$endDay = (int) substr($end, 3, 2);
return ($day <= $endDay);
} else {
return TRUE;
}
}
return FALSE;
}
$start = '12-01';
$end = '06-30';
$check = '07-10';
if (isInSeason($start, $end, $check)) {
echo 'In season';
} else {
echo 'Not in season';
}
您可以将您的月份正常化为赛季开始。例如,如果您的季节开始于 11 月(第 11 个月),结束于 2 月(第 2 个月),则它们将分别标准化为第 1 个月和第 4 个月。然后你可以检查任何月份与标准化年份的对比,看看它是否在季节内。
$startMonth = 11; // November
$endMonth = 2; // February
$futureFactor = $startMonth - 1;
$pastFactor = 13 - $startMonth;
$months = [];
// Create a normalized year to the start month.
foreach (range(1,12) as $r) {
if ($r == $startMonth) {
$months[$r] = 1;
}
else {
$months[$r] = $r < $startMonth ? $r + $pastFactor : $r - $futureFactor;
}
}
// Check if December(12) is in season
if ($months[12] >= $months[$startMonth] && $months[12] <= $months[$endMonth]) {
print "In season...\n";
}
else {
print "Out of season...\n";
}
标准化年份示例:
Array
(
[1] => 3
[2] => 4
[3] => 5
[4] => 6
[5] => 7
[6] => 8
[7] => 9
[8] => 10
[9] => 11
[10] => 12
[11] => 1
[12] => 2
)
我个人会封装此逻辑并使用日期对象。这是我目前能想到的最简单的方法。 Class 为简洁起见,属性为 public。
<?php
date_default_timezone_set('America/New_York');
class Season {
public $startMonth;
public $startDay;
public $endMonth;
public $endDay;
public function setStart($month, $day) {
$this->startMonth = (int) $month;
$this->startDay = (int) $day;
}
public function setEnd($month, $day) {
$this->endMonth = (int) $month;
$this->endDay = (int) $day;
}
function isActiveForDate(DateTime $date) {
$seasonStartDate = new DateTime(sprintf('%d-%d-%d', $date->format('Y'), $this->startMonth, $this->startDay));
$seasonEndDate = new DateTime(sprintf('%d-%d-%d', $date->format('Y'), $this->endMonth, $this->endDay));
// Edge case
if ($this->startMonth > $this->endMonth) {
$seasonStartDate->modify('-1 year');
// This line is only useful if you wish to calculate inclusively
if ($date == $seasonStartDate || $date == $seasonEndDate) return true;
// If this condition is true, no need to calculate anything
if ($date->format('n') < $this->startMonth && $date->format('n') >= $this->endMonth) {
return false;
}
$seasonEndDate->modify('+1 year');
}
return ($date->getTimestamp() >= $seasonStartDate->getTimestamp()
&& $date->getTimestamp() <= $seasonEndDate->getTimestamp());
}
}
定义季节:
$season = new Season();
$season->setStart(11, 1);
$season->setEnd(7, 1);
并测试结果:
echo ($season->isActiveForDate(new DateTime("2000-7-2"))) ? "pass" : "fail"; // fail
echo ($season->isActiveForDate(new DateTime("2000-10-31"))) ? "pass" : "fail"; // fail
echo ($season->isActiveForDate(new DateTime("2000-11-1"))) ? "pass" : "fail"; // pass
echo ($season->isActiveForDate(new DateTime("2000-6-31"))) ? "pass" : "fail"; // pass