:: Sweepstake (periodical events) ::

Sometimes it is necessary to calculate the days of periodical events, like for instance sweepstakes, contests, regular publications, etc..

In general, it is an easy problem to solve. However when the events span multiple days and must not occur in holidays, the problem becomes less trival to solve.

Read this article to learn how you can use the PHP Sweepstakes class to compute the days of regular event taking in account these nuances that may complicate the calculations.

Introduction

There are many types of events that are repeated with regular intervals. That is the case of regular publications or contests like sweepstakes. That is why this class is called PHP Sweepstakes.

This article is about using this class to compute the dates of periodical events considering special conditions that make the computations more complicated.

Periodical Events

The problem we want to solve is of events that start at a specific date and repeat themselves after a specific number of days of the event cycle. Some events can also span through multiple days. In addition there may be days when the events needs to pause because the event day may happen to be in the holidays for instance.
 
This package can generate a lists of an unlimted number of dats of multiple recurring events that could span through multiple days.  
 
It can take a multidimensional array, that includes the start day, the range of the event days, the event cycle (weekly or monthly), as well a list of exceptions that may be holidays for instance.

The package can display the next and previous editions of each of the listed events.

Events that Take Multiple Days

The biggest problems with these calculations are that each event can start at a different day, can span multiple days, and all depends on the cycle of the event (weekly or monthly). 
 
For instance an event can start at on Monday, spans for 3 days and has a weekly cycle. Or another event starts at a Tuesday, spans 6 days and has a monthly cycle.
 
For simple events, we could use a cron job but cron is not that flexible to consider for instance exception days.
 
Using cron is also more difficult to adapt to certain applications needs. Cron considers the server time which often is not in the same time zone of users of the application. Thus we need to implement an algorithm in PHP that uses its date and time functions to consider all these details. 
 
Another limitation of cron is that it only considers the event start thus not considering that the event can span multiple days.

Time Wrap

Time specifications may exceed the 24 hours that each day take. For instance in Europe the time format uses 24:00 hours format. PHP treats 24:00 like I would expect. It should treat 37:00 by wrapping it into 13:00 tomorrow.

This kind of scheduling is seen frequently in radio and TV broadcast schedules, not only in Japan. But strtotime('24:00 today') is 0:00 whereas strtotime('24:00') and strtotime('today 24:00') are 0:00 tomorrow. PHP does not handle any time longer than 24:59:59.9 though. 

Because the date function can parse English text it is also important to know when a day starts and when it ends. Maybe the difference is very tiny and also using 24:00 and/or 37:00 for scheduling depends on the use case but it is important if you need to parse English text to a UNIX timestamp.

Lazy Lists

A greater problem is that the package can also list the current and the previous events. Although a an event repeats itself but the date are different. Basicaly it is the week number. 
 
This was a requirement because the date or time change. For instance the sweepstakes prizes may change and it is also necessary to list older sweepstakes.

Exception Dates 

Additionally, another challenge was the list of exceptions, for instance if the calculated day of the event is a holiday. The parameter array may specify multiple exceptions that are simply dates (timestamps).

Conclusion

As you may have read an apparently simple problem of calculation the dates of periodical events may become much more complicated once you need to consider events details like multiple day spans or exception dates like holidays.

On the next part of this article we will see how to use the PHP Sweepstakes package to solve a real world problem.

If you liked this article or have a question about the problem of calculating periodical events, post a comment here.

 

In the first part of this article it was covered the problem of computing the dates of periodical events and nuances that can make the solution more complicated.

Read this article to learn how to use the PHP Sweepstakes package to solve a real world example of the problem.

 

A Real World Problem

 

To demonstrate how to solve the scheduling problems, nothing like a real world example. For instance a weekly and/or monthly distributed magazine that also organizes regular sweepstakes, such as word game where you have to answer test questions with multiple choice answers.

The reader then can use the browser and navigate to the page that uses this package and choose his magazine to enter the winning word along with his personal data to participate to the sweepstakes.

The package shows all the current sweepstakes and also the previous sweepstakes, so that the reader can participate on the sweepstakes a week or a month later.

 

This image shows an example screenshot. In the first row all the magazines from the 35 week of the year and in the second row all the magazines from the 34 week of the year.

The Implementation Algorithm

It uses an algorithm that simply loops over the given range of days starting from a given day. Then it compares each day with each sweepstakes to find the right sweepstakes. So, it is all gathered in two loops.

The PHP Date Functions

The exact calendar (time and date) calculations are very difficult. Fortunately PHP offers several functions, like for instance strtotime(), mktime(), date() and DateTime(), that help the developers to solve problems like this.

For instance the mktime() function can return the current timestamp or any other timestamp. This is useful to change the reference time of the programming system or testing server.

The date() function can return the day of the week, the week number and the month number. For instance date("D") returns the day of the week and it is useful because the sweepstakes starts at specific day.

The DateTime() function is useful to return the UNIX timestamp with respect to the users time zone. For instance echo $d->modify("monday this week") returns the UNIX timestamp of the monday of this week. The method modify() is needed because the DateTime() functions needs a UNIX timestamp to initialize the class object similar to a seed for a random generator.

The PHP date functions can also parse english text to unix timestamp. For instance strtotime('14:00 today');

Basically these 4 php functions are needed to change the reference clock of the user system needed for testing and also for production without actually change the time of the server operating system.

Example Tutorial

The package takes a multidimensional array as input. The array holds the title, a unique ID, the start day (not to confuse with the start of package), the period cycle (weekly or monthly), the duration of the sweepstakes (currently it can be 3 day, 6 day or a month).
array(
"title" => "Sweepstake 1",
"uid" => "1",
"day" => "2",
"cycle" => "0",
"end" => "0",
"table" => array( array
(
"ST" => "18 December",
"SD" => 1355785200,
),
array
(
"ST" => "24 December",
"SD" => 1356303600,
),
array
(
"ST" => "2 October",
"SD" => 1349128800,
)
)
)

In addition there is the table array that holds the list of exceptions which is simply a date (timestamp). An event can then be saved with many other events together to feed the main function.

Creating the Class Object

To compute the events create an object and feed it with the array of events and the range of the days to list:
$s = new sweepstake();
$result = $s->main($table,31);
echo $result;

Changing to the User Time Zone

You can change the timezone the match the current timezone by changing the main.php file and the date_default_timezone_set('Europe/Berlin') function.

Installation

The PHP Sweepstakes package requires PHP 5.3 or later. Download the package from phpclasses.org and save the files to where you can include the file main.php.

The Complete Example Code

require ("main.php");
 
$table = array( 

 array( 
  "title" => "Sweepstake 1", 
  "uid" => "1", 
  "day" => "2", 
  "cycle" => "0", 
  "end" => "0", 
  "table" => array(

   array 
   ( 
    "ST" => "18 December", 
    "SD" => 1355785200, 
   ),

   array 
   ( 
    "ST" => "24 December", 
    "SD" => 1356303600, 
   ),
 
   array 
   ( 
    "ST" => "2 October", 
    "SD" => 1349128800, 
   )

  ) 
 )
);

$s = new sweepstake(); 

$result=$s->main($table,31); 

echo $result; 
 

Example package output

In the example package output above you can see 5 weekly sweepstakes magazines and 1 monthly sweepstake magazine at the start day 1.

You can also see new and old issues when new is the current week and old is the previous week. In day 3 you can see old is empty because the participation on the sweepstake magazine is terminated and/or the magazine is not available anymore.

Conclusion

The PHP Sweepstakes package makes much simpler the calculation of periodical events when you have more complicated factors to take in account, like multiple days span or exception days like holidays.

If you like this article or have a question about to use this class to solve the problem of scheduling periodical events, post a comment to this article.

 

[1] Thank you to phpclasses.org!

Sourcecode: