【问题标题】:Return opening hours, past midnight返回营业时间,午夜过后
【发布时间】:2018-10-08 11:47:03
【问题描述】:

我的 MySQL 数据库中存储了打开和关闭时间,如下所示:

opening_time_Sunday  10:30
closing_time_Sunday  00:00
opening_time_Monday  09:30
closing_time_Monday  01:30
opening_time_Tuesday  09:30
closing_time_Tuesday  01:30
opening_time_Wednesday  09:30
closing_time_Wednesday  01:30
opening_time_Thursday  09:30
closing_time_Thursday  01:30
opening_time_Friday  09:30
closing_time_Friday  23:00
opening_time_Saturday  10:30
closing_time_Saturday  00:00

我遇到的问题是在尝试显示商店的营业时间和关闭时间时,比如说星期一,如果过了午夜,它会开始读取星期二的时间并显示商店已经关闭,即使它本来应该一直营业到上午 01:30。

我理解为什么会发生这种情况,但不确定使用什么逻辑来读取(例如)星期一直到截止日期,这是我当前的功能:

public static function setting($setting)
{
    $config = Settings::where('setting', $setting)->first();
    if ($config) {
        return $config->value;
    }
}

public static function Today() {
    $today = date('l');
    $start      = self::setting('opening_time_' . $today); // Select value from settings table
    $end        = self::setting('closing_time_' . $today); // Select value from settings table
    return $start . " - " . $end;
}

【问题讨论】:

  • 请把设置方法也贴出来
  • 你需要展示你用来设置close_time_Monday的代码,单独展示调用方法并不能提供任何线索。
  • 所以closing_time_Monday 是星期二的 1:30?那么严格意义上来说,这并不是真正的周一收盘时间。我的第一个想法是您可以将时间设置为正确的工作日,或者您需要某种方法来确定保存的时间确实是在第二天(例如将关闭时间与打开时间进行比较,或者只是一个标志)。
  • 我已经添加了设置功能,它从表格中返回值。
  • @Karsten Koop 没错,它与星期二重叠。

标签: php


【解决方案1】:

要动态确定要显示的时间日期,您需要通过检查今天的结束日期是否大于当前时间,对前一个日期的结束时间执行消除过程。

但是由于关闭时间不包括星期几,您还必须验证关闭时间是am,以避免误报。

动态示例:https://3v4l.org/Cs6jS

public static function Today() {
    $currentDate = new \DateTimeImmutable;
    $priorDate = $currentDate->sub(new \DateTimeInterval('P1D'));
    $yesterday = $priorDate->format('l');

    $priorClosing = self::setting('closing_time_' . $yesterday);
    $closeDate = $currentDate->setTime(...explode(':', $priorClosing));

    if ($closeDate->format('a') === 'am' && $currentDate < $closeDate) {
        //check if the closing has not occurred yet
        $currentDate = $priorDate;
    }

    $today = $currentDate->format('l');
    $start = self::setting('opening_time_' . $today);
    $end = self::setting('closing_time_' . $today);

    return $start . " - " . $end;
}

结果:

Day         |   00:15:00                    |   23:00:00
Monday      |   Monday: 09:30 - 01:30       |   Monday: 09:30 - 01:30
Tuesday     |   Monday: 09:30 - 01:30       |   Tuesday: 09:30 - 01:30
Wednesday   |   Tuesday: 09:30 - 01:30      |   Wednesday: 09:30 - 01:30
Thursday    |   Wednesday: 09:30 - 01:30    |   Thursday: 09:30 - 01:30
Friday      |   Thursday: 09:30 - 01:30     |   Friday: 09:30 - 23:00
Saturday    |   Saturday: 10:30 - 00:00     |   Saturday: 10:30 - 00:00
Sunday      |   Sunday: 10:30 - 00:00       |   Sunday: 10:30 - 00:00

(每种方法都相同,但结果会因使用的开盘截止日期而异)

根据您当前的营业时间结构,当开盘日期和收盘日期的时间均为AM 时,上述示例将提供误报。 避免这种情况的唯一方法是在给定日期的开始和结束时间中包含星期几。


对比示例:https://3v4l.org/q57eD

(最准确 - 如果操作持续时间不超过 24 小时)

解决前一天在AM 中开始和结束时出现误报的问题。问题是关闭一天是未知的,并且假设操作持续时间始终少于 24 小时。您还可以比较前一个日期的开放时间和结束日期,并确保它们不超过 24 小时。

public static function Today() {
    $currentDate = new \DateTimeImmutable;
    $priorDate = $currentDate->sub(new \DateTimeInterval('P1D'));
    $yesterday = $priorDate->format('l');

    $priorOpening = self::setting('opening_time_' . $yesterday);
    $priorClosing = self::setting('closing_time_' . $yesterday);

    $priorOpenDate = $priorDate->setTime(...explode(':', $priorOpening));
    $closeDate = $currentDate->setTime(...explode(':', $priorClosing));
    $diff = $priorOpenDate->diff($closeDate);

    if ($diff->d === 0 && $currentDate < $closeDate) {
        //check if the closing has not occurred yet
        $currentDate = $priorDate;
    }

    $today = $currentDate->format('l');
    $start = self::setting('opening_time_' . $today);
    $end = self::setting('closing_time_' . $today);

    return $start . " - " . $end;
}

另外,由于只有 Mon-Thur 在午夜后营业,您可以硬编码日期以检查并根据当前时间确定选择哪一天。

本例只检查当前日期是否为Tues-Fri,当当前时间未到01:30时,将today更改为yesterday

硬编码示例:https://3v4l.org/Vtr6L

public static function Today() {
    $currentDate = new \DateTimeImmutable;
    if (in_array($currentDate->format('N'), [2, 3, 4, 5])) {              
        //check current time is not beyond the threshold
        $closedDate = $currentDate->setTime(1, 30, 00);
        if ($currentDate < $closedDate) {
            //change the date to display to day prior
            $currentDate = $currentDate->sub(new \DateInterval('P1D'));
        }
    }
    $today = $currentDate->format('l');

    $start      = self::setting('opening_time_' . $today); // Select value from settings table
    $end        = self::setting('closing_time_' . $today); // Select value from settings table
    return $start . " - " . $end;
}

【讨论】:

    猜你喜欢
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 2016-01-13
    • 2017-01-28
    • 1970-01-01
    相关资源
    最近更新 更多