【问题标题】:Is there a way to skip specific days in Carbon?有没有办法跳过 Carbon 中的特定日期?
【发布时间】:2020-06-04 17:36:07
【问题描述】:

我有一个计算运输天数的方法。我需要能够在 Carbon 实例上添加天数,但我需要跳过添加一天,具体取决于它是否是一周中的特定日期,不一定是周六/周日,也可能是周一或周二。我似乎无法在 Carbon Docs 中找到任何指定在添加天数时将一周中的某些天列入黑名单的内容。

【问题讨论】:

  • 真的需要最后一个问题吗?我的意思是,还有谁应该这样做?
  • @Andreas 你是对的。有点傻。删除它
  • 一个只有问题描述的问题通常不会引起注意,至少不会引起正确的注意。添加更具体的问题是什么。 “我在这个日期发货,10 天发货,不是星期一,预期结果,此代码不起作用,我做错了什么。”那不见了……
  • 尝试将各种假期转换为代码是一个非常重要的问题。这就是为什么几乎每个人都简单地告诉你“5-7 个工作日”,因为人类很容易弄清楚它几乎是隐含的。

标签: php php-carbon


【解决方案1】:

Carbon 库有助于设置一周的开放/关闭天数,因此您可以:

https://github.com/kylekatarnls/business-time

你可以这样做:

BusinessTime::enable(Carbon::class, [
  'monday'.   => [],
  'tuesday'   => ['00:00-24:00'],
  'wednesday' => ['00:00-24:00'],
  'thursday'  => ['00:00-24:00'],
  'friday'    => [],
  'saturday'  => ['00:00-24:00'],
  'sunday'    => ['00:00-24:00'],
]);

$date = Carbon::parse('2019-06-01');

echo $date->addOpenTime('4 days');

这会增加 4 天,跳过周五和周一。

您基本上可以通过逐天添加循环来获得相同的结果,但是间隔越大,它的速度就会越慢。要优化操作,您应该首先添加完整的周数:

$daysToAdd = 36;
$skippedDays = ['Monday', 'Friday'];
$daysPerWeek = 7 - count($skippedDays);
$completeWeeks = floor($daysToAdd / $daysPerWeek);

function skip(CarbonInterface $date, array $skippedDays): CarbonInterface {
  $date = $date->copy(); // if not using CarbonImmutable

  while (in_array($date->format('l'), $skippedDays)) {
    $date = $date->addDay();
  }

  return $date;
}

$start = Carbon::now(); // Or whatever date
$end = $start->copy()->addWeeks($completeWeeks); // ->copy() not needed if you use CarbonImmutable
$end = skip($end, $skippedDays);

// For each remaining days
for ($i = $daysToAdd % $daysPerWeek; $i--; $i > 0) {
  $end = skip($end->addDay(), $skippedDays);
}

这是针对您的特定情况的普通版本,但如果您认为有一天,您将不得不处理小时间隔/小时精度而不是天,或者会有特殊的日子(如节假日例外),那么您应该绝对使用cmixin/business-time(上面的链接)。

【讨论】:

    猜你喜欢
    • 2020-03-20
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2019-07-09
    • 2015-10-01
    相关资源
    最近更新 更多