0

Given the schedule:

{
  "start_day": "Monday",
  "end_day": "Friday",
  "start_time": "9:00 AM",
  "end_time": "6:00 PM"
}

How can I determine if the current time in a specified time zone falls within the above given schedule? Are there any functions in PHP that'll help me? Issues that I foresee:

  1. Dealing with time zones
  2. The given schedule doesn't provide year information, but I guess I can assume it applies to the current year
  3. Dealing with the range of days (Monday and Friday are provided; how do I know that there are Tuesday, Wednesday, and Thursday in between?

UPDATE 1:

Change JSON so it encompasses all days/times:

{
  "start_day": "Monday",
  "end_day": "Sunday",
  "start_time": "12:00 AM",
  "end_time": "11:59 PM"
}

Then change $now assignment to $now = new DateTime("Saturday next month 10 am", $timezone);

Nothing is outputted.

StackOverflowNewbie
  • 39,403
  • 111
  • 277
  • 441
  • 2
    Look at [DateTime objects](http://php.net/manual/en/class.datetime.php), which deal with timezones – Mark Baker Apr 12 '15 at 11:57
  • 1
    1. Are these times also in the specified timezone or not? 2. So to say you just want a "simple" if statement to tell either yes the current time is in between the schedule or not, right? 3. Have you tried something? – Rizier123 Apr 12 '15 at 11:58
  • The schedule does not have a timezone specified. I'm been toying with a few PHP function trying to get things to work, mainly `strtotime`. – StackOverflowNewbie Apr 12 '15 at 12:01

1 Answers1

2

You can use the following code. I check for all available timezones in that example:

<?php

$json = <<<EOF
{
  "start_day": "Friday",
  "end_day": "Sunday",
  "start_time": "9:00 AM",
  "end_time": "6:00 PM"
}
EOF;

$when = json_decode($json);

// Get weekdays between start_day and end_day.
$start_day = new DateTime($start);
$nstart_day = (int) $start_day->format('N');
$end_day = new DateTime($end);
$nend_day = (int) $end_day->format('N');

// If the numeric end day has a lower value than the start
// day, we add "1 week" to the end day
if($nend_day < $nstart_day) {
    $end_day->modify('+1 week');
}
// Add one day to end_day to include it into the return array
$end_day->modify('+1 day');

// Create a DatePeriod to iterate from start to end
$interval = new DateInterval('P1D');
$period = new DatePeriod($start_day, $interval, $end_day);
$days_in_between = array();
foreach($period as $day) {
    $days_in_between []= $day->format('l');
}


// Check for all timezones in this example
foreach(DateTimeZone::listIdentifiers() as $tzid) {
    $timezone = new DateTimeZone($tzid);
    // Current time in that timezone
    $now = new DateTime("now", $timezone);
    // start_time in that timezone
    $start_time = new DateTime($when->start_time, $timezone);
    // end_time in that timezone
    $end_time = new DateTime($when->end_time, $timezone);
    // Get weekday for that timezone
    $day = $now->format('l');

    if($now >= $start_time && $now <= $end_time
        && in_array($day, $days_in_between))
    {
        printf("In %s the current time %s is between %s and %s (%s-%s)\n",
            $tzid, $now->format('H:i:s'), $when->start_time, $when->end_time,
                $when->start_day, $when->end_day);
    }
}
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • Why are you checking all time zones? And how does this check for Tuesday 9am-6pm? – StackOverflowNewbie Apr 12 '15 at 14:12
  • It is just an example, that's why I check all timezones. In your application you will have to check only for the target timezone, of course. You didn't named it. `And how does this check for Tuesday 9am-6pm?` <-- I don't get this. Do you understand what the code above is doing? – hek2mgl Apr 12 '15 at 14:17
  • OK, I see how you get the days and do the `in_array` check. What if the time to check against the schedule is not the current time? Say it's some time in the past or future? – StackOverflowNewbie Apr 13 '15 at 04:04
  • I guess your `next week` was arbitrary. It could have been `next month` or `last week`, right? I guess if the time to check against is not `now`, something needs to be done about those arbitrary times added??? – StackOverflowNewbie Apr 13 '15 at 04:12
  • The `next week` trick will work even if the date is in the past or future. It is just using day names. – hek2mgl Apr 13 '15 at 08:06
  • If `$now` refers to a time in the future or past, your if-condition will fail, right? For example, is Saturday next month at 10am within the schedule? – StackOverflowNewbie Apr 13 '15 at 10:08
  • In which timezone? Note, that you can simply replace `$now = new DateTime("now", $timezone);` by `$now = new DateTime("Saturday next month 10 am", $timezone);` – hek2mgl Apr 13 '15 at 10:11
  • It doesn't work. Please see my UPDATE 1. Also, I think this may help solve the problem: http://stackoverflow.com/questions/2784484/how-to-find-nearest-day-of-week-in-php – StackOverflowNewbie Apr 13 '15 at 11:34
  • I fixed the `days_in_between` calculation. It should work as expected now. – hek2mgl Apr 13 '15 at 14:00
  • I think `$start_time` and `$end_time` needs to be the same date as `$now` in order for the first two if-conditions to work properly. Perhaps it should be set something like this, instead: `$start_time = new DateTime($now->format('Y-m-d') . ' ' . $when->start_time, $timezone);` ??? – StackOverflowNewbie Apr 15 '15 at 05:52