10
\$\begingroup\$

Goal: To create a countdown to our next available live stream.

Details: We live stream six times a week all (PST). 1. Sunday at 8:00 a.m. 2. Sunday at 10:00 a.m. 3. Sunday at 12:00 p.m. 4. Sunday at 6:30 p.m. 5. Wednesday at 7:00 p.m. 6. Saturday at 10:00 a.m.

My approach: I check what day it is and what time it is then create the countdown to the next stream.

I'm sure what I have done can be cleaned up and improved, so tell me how.

<?php
// Countdown Stuff
$year = date(Y);
$month = date(m);
$month_day = date(d);
$day = date(w);
$hour = date(G);
$min = date(i);
$addDay = 0;

// It's Sunday
if ( $day == 0 ) {
    if ( $hour < 8 ) {
       $hour = 8;
       $min = 0;
    } 
    else if ( $hour < 10 ) {
       $hour = 10;
       $min = 0;
    } 
    else if ( $hour < 12 ) {
       $hour = 12;
       $min = 0;
    }
    else if ( $hour <= 18 && $min < 30 ) {
       $hour = 18;
        $min = 30;
    } 
    else {
     $addDay = 3;
       $hour = 19;
       $min = 0;
    }
} 
// It's Monday
else if ( $day == 1 ) {
    $addDay = 2;
      $hour = 19;
      $min = 0;
} 
// It's Tuesday
else if ( $day == 2 ) {
    $addDay = 1;
      $hour = 19;
      $min = 0;
} 
// It's Wednesday
else if ( $day == 3) {

    if ( $hour < 19 ) {
       $hour = 19;
       $min = 0;
    } else {
     $addDay = 3;
       $hour = 10;
       $min = 0;
    }
} 
// It's Thursday
else if ( $day == 4 ) {
    $addDay = 2;
      $hour = 10;
      $min = 0;
} 
// It's Friday
else if ( $day == 5 ) {
    $addDay = 1;
      $hour = 10;
      $min = 0;
} 
// All that's left is Saturday
else {

    if ( $hour < 10 ) {
       $hour = 10;
       $min = 0;
    } else {
     $addDay = 1;
       $hour = 8;
       $min = 0;
    }
}


$build_date = $year . '-' . $month . '-' . $month_day . ' ' . $hour . ':' . $min . ':00';
$date = new DateTime($build_date);

if ( $addDay ) {
    $date->modify("+$addDay day");
}

$date = strtotime($date->format("Y-m-d G:i:s"));
$now = strtotime("now");
$count = $date - $now;
?>

<script type="text/javascript">
var myTime = <?=$count?>;
$('#countdown').countdown({ until: myTime}); 
</script>
\$\endgroup\$
11
\$\begingroup\$

To add to Andrew's answer about taking advantage of what type of timestamps can be creating using strtotime(), your code can be reduced to around 25 lines...

<?php

$schedule = array(
    'this Sunday 8am',
    'this Sunday 10am',
    'this Sunday 12pm',
    'this Sunday 6:30pm',
    'this Wednesday 7pm',
    'this Saturday 10am'
    );

$current_time = strtotime('now');
foreach ($schedule as &$val) {
    $val = strtotime($val);
    // fix schedule to next week if time resolved to the past
    if ($val - $current_time < 0) $val += 604800; 
    }
sort($schedule);
$countdown = $schedule[0] - $current_time;

?>

<script type="text/javascript">
    var myTime = <?php echo $countdown; // just personally prefer full tags ?>;
    $('#countdown').countdown({ until: myTime}); 
</script>

To add to visionary-software-solutions' answer, it would be best to store the schedule in a database or a separate xml/text/json/etc type file. This way, you can have staff simply use an internal webform to change schedules instead of having the PHP dev hard-code the changes every time. In that webpage, you can allow staff to only select a weekday and time, and have the page translate that into a string usable by strtotime() in this countdown script.

Edit: fixed strtotime() values. Careful with "this day" vs "next". For some insight into what type of strings strtotime() can take, see: http://www.gnu.org/software/tar/manual/html_node/Date-input-formats.html

\$\endgroup\$
4
\$\begingroup\$

I don't have time to look over everything, but I noticed you only set $min to something other than 0 once. You could add the following above $build_date, and then remove all the $min = 0;s, and you'd clear up a few lines:

if($min == date('i')) {
  $min = 0;
}

If it didn't change, which would only happen when you set it to 30 in that one instance, then set it to 0.

\$\endgroup\$
3
\$\begingroup\$

A few things that jumped out.

In your date() calls you are passing constants instead of strings e.g. you use date(Y) as opposed to date('Y'), this issues a notice error. PHP will assume that you meant a string, but it is best to be explicit.

The getdate() function will gives you all that information instead of calling date() 6 times.

For what you are wanting to do, I would recommend taking a look at the mktime() function. Once you calculate the next live stream time from your current time, simply pass those values to mktime() and do a time() - mktime() and thats how many seconds you have until the event. mktime produces a UNIX timestamp, so you can pass that to the date() function or into a DateTime object to format, change timezone, etc.

If you are going to have a lot of if/elseif statements like that, it would be cleaner to use a switch statement.

\$\endgroup\$
2
\$\begingroup\$

Of course, now if your company decides to change streams from Sunday at 8:00am to Tuesday at 2, you're going to have to go in and hack this code. And if you mess up a ';' or '?php' or junior developer passes "NO WAY" to strtotime()?

Evolve your approach. You should be storing the stream times externally; either in a file or a database. You should be querying those times, doing a strtotime() difference between them and now, then taking the minimum positive element and displaying that.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.