CC-2965: Frontend widget displays shows in UTC time
Not only were frontend widgets showing UTC time, the SQL query was also comparing UTC timestamp with local timestamps, causing widgets to display shows in the wrong day, etc. Another problem was that "On air today" widget was simply calling GetNextShows which returns shows within next 48 hours. Fixed by: 1. Under models/Show.php: In the GetCurrentShow/GetNextShows/GetShowsByDayOfWeek functions, added code to convert UTC timestamp to local timestamp or vice versa, depending on which one is more suitable, in SQL queries, thus removing inconsistency in timezones. Also, before returning query result, added code to convert result to local timezone. In GetNextShows, added an optional parameter endTime to limit the interval of shows to get. This is useful for the "On air today" widget. 2. Under models/DateHelper.php: Added a few timezone functions to help converting timezones easier in Show.php. 3. Under controller/ApiController.php: Added todayInfoAction which is to be used by "On Air Today" widget.
This commit is contained in:
parent
9506161b70
commit
6ffecf80c8
|
@ -199,6 +199,30 @@ class ApiController extends Zend_Controller_Action
|
|||
}
|
||||
}
|
||||
|
||||
public function todayInfoAction()
|
||||
{
|
||||
if (Application_Model_Preference::GetAllow3rdPartyApi()){
|
||||
// disable the view and the layout
|
||||
$this->view->layout()->disableLayout();
|
||||
$this->_helper->viewRenderer->setNoRender(true);
|
||||
|
||||
$date = new Application_Model_DateHelper;
|
||||
$timeNow = $date->getTimestamp();
|
||||
$timeEnd = $date->getDayEndTimestamp();
|
||||
|
||||
$result = array("env"=>APPLICATION_ENV,
|
||||
"schedulerTime"=>gmdate("Y-m-d H:i:s"),
|
||||
"nextShow"=>Application_Model_Show::GetNextShows($timeNow, 5, $timeEnd));
|
||||
|
||||
header("Content-type: text/javascript");
|
||||
echo $_GET['callback'].'('.json_encode($result).')';
|
||||
} else {
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
print 'You are not allowed to access this resource. ';
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
public function weekInfoAction()
|
||||
{
|
||||
if (Application_Model_Preference::GetAllow3rdPartyApi()){
|
||||
|
|
|
@ -56,6 +56,21 @@ class Application_Model_DateHelper
|
|||
$this->_dateTime = strtotime($dateString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and return the timestamp for end of day today
|
||||
* in local time.
|
||||
*
|
||||
* For example, if local time is 2PM on 2011-11-01,
|
||||
* then the function would return 2011-11-02 00:00:00
|
||||
*
|
||||
* @return End of day timestamp in local timezone
|
||||
*/
|
||||
function getDayEndTimestamp() {
|
||||
$dateTime = new DateTime($this->getDate());
|
||||
$dateTime->add(new DateInterval('P1D'));
|
||||
return $dateTime->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the epoch timestamp difference from "now" to the beginning of today.
|
||||
*/
|
||||
|
@ -79,6 +94,43 @@ class Application_Model_DateHelper
|
|||
return $this->_dateTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset in seconds, between local and UTC timezones.
|
||||
* E.g., if local timezone is -4, this function
|
||||
* returns -14400.
|
||||
*
|
||||
* @return type offset in int, between local and UTC timezones
|
||||
*/
|
||||
function getLocalTimeZoneOffset() {
|
||||
$dateTime = new DateTime("@".$this->_dateTime, new DateTimeZone("UTC"));
|
||||
$timezone = new DateTimeZone(date_default_timezone_get());
|
||||
return $timezone->getOffset($dateTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset hour in int, between local and UTC timezones.
|
||||
* E.g., if local timezone is -4:30, this function
|
||||
* returns -4.
|
||||
*
|
||||
* @return type offset hour in int, between local and UTC timezones
|
||||
*/
|
||||
function getLocalOffsetHour() {
|
||||
$offset = $this->getLocalTimeZoneOffset();
|
||||
return (int)($offset / 3600);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset minute in int, between local and UTC timezones.
|
||||
* E.g., if local timezone is -4:30, this function
|
||||
* returns -30.
|
||||
*
|
||||
* @return type offset minute in int, between local and UTC timezones
|
||||
*/
|
||||
function getLocalOffsetMinute() {
|
||||
$offset = $this->getLocalTimeZoneOffset();
|
||||
return (int)(($offset % 3600) / 60);
|
||||
}
|
||||
|
||||
public static function TimeDiff($time1, $time2)
|
||||
{
|
||||
return strtotime($time2) - strtotime($time1);
|
||||
|
|
|
@ -1330,45 +1330,95 @@ class Application_Model_Show {
|
|||
->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given local current time $timeNow, returns the show being played right now.
|
||||
*
|
||||
* @param type $timeNow local current time
|
||||
* @return type show being played right now
|
||||
*/
|
||||
public static function GetCurrentShow($timeNow)
|
||||
{
|
||||
global $CC_CONFIG, $CC_DBC;
|
||||
|
||||
// Need this in the query below, so that we are NOT comparing UTC
|
||||
// timestamps si.starts/si.ends with local timestamps $timeNow
|
||||
$timezoneInterval = Application_Model_Show::GetTimezoneIntervalString(true);
|
||||
|
||||
$sql = "SELECT si.starts as start_timestamp, si.ends as end_timestamp, s.name, s.id, si.id as instance_id, si.record, s.url"
|
||||
." FROM $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] s"
|
||||
." WHERE si.show_id = s.id"
|
||||
." AND si.starts <= TIMESTAMP '$timeNow'"
|
||||
." AND si.ends > TIMESTAMP '$timeNow'";
|
||||
." AND si.starts <= TIMESTAMP '$timeNow' + $timezoneInterval"
|
||||
." AND si.ends > TIMESTAMP '$timeNow' + $timezoneInterval";
|
||||
|
||||
// Convert back to local timezone
|
||||
$rows = $CC_DBC->GetAll($sql);
|
||||
Application_Model_Show::ConvertToLocalTimeZone($rows, array("start_timestamp", "end_timestamp"));
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
public static function GetNextShows($timeNow, $limit)
|
||||
/**
|
||||
* Given local current time $timeNow, returns the next $limit number of
|
||||
* shows within 2 days if $timeEnd is not given; Otherwise, returns the
|
||||
* next $limit number of shows from $timeNow to $timeEnd, both in local time.
|
||||
*
|
||||
* @param type $timeNow local current time
|
||||
* @param type $limit number of shows to return
|
||||
* @param type $timeEnd optional: interval end time
|
||||
* @return type next $limit number of shows
|
||||
*/
|
||||
public static function GetNextShows($timeNow, $limit, $timeEnd = "")
|
||||
{
|
||||
global $CC_CONFIG, $CC_DBC;
|
||||
|
||||
|
||||
// Need this in the query below, so that we are NOT comparing UTC
|
||||
// timestamps si.starts with local timestamps $timeNow
|
||||
$timezoneInterval = Application_Model_Show::GetTimezoneIntervalString(true);
|
||||
|
||||
// defaults to retrieving shows from next 2 days if no end time has
|
||||
// been specified
|
||||
if($timeEnd == "") {
|
||||
$timeEnd = "'$timeNow' + INTERVAL '2 days' + $timezoneInterval";
|
||||
} else {
|
||||
$timeEnd = "'$timeEnd' + $timezoneInterval";
|
||||
}
|
||||
|
||||
$sql = "SELECT *, si.starts as start_timestamp, si.ends as end_timestamp FROM "
|
||||
." $CC_CONFIG[showInstances] si, $CC_CONFIG[showTable] s"
|
||||
." WHERE si.show_id = s.id"
|
||||
." AND si.starts >= TIMESTAMP '$timeNow'"
|
||||
." AND si.starts < TIMESTAMP '$timeNow' + INTERVAL '48 hours'"
|
||||
." AND si.starts >= TIMESTAMP '$timeNow' + $timezoneInterval"
|
||||
." AND si.starts < TIMESTAMP $timeEnd"
|
||||
." ORDER BY si.starts"
|
||||
." LIMIT $limit";
|
||||
|
||||
// Convert timestamps to local timezone
|
||||
$rows = $CC_DBC->GetAll($sql);
|
||||
Application_Model_Show::ConvertToLocalTimeZone($rows, array("start_timestamp", "end_timestamp"));
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a day of the week variable $day, based in local time, returns the
|
||||
* shows being played on this day of the week we're in right now.
|
||||
*
|
||||
* @param type $day day of the week
|
||||
* @return type shows being played on this day
|
||||
*/
|
||||
public static function GetShowsByDayOfWeek($day){
|
||||
//DOW FROM TIMESTAMP
|
||||
//The day of the week (0 - 6; Sunday is 0) (for timestamp values only)
|
||||
|
||||
//SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
|
||||
//Result: 5
|
||||
|
||||
|
||||
global $CC_CONFIG, $CC_DBC;
|
||||
|
||||
// Need this in the query below, so that we are NOT extracting DOW and WEEK
|
||||
// information from UTC timestamps si.starts, and comparing with a local
|
||||
// timezone based variable $day and localtimestamp
|
||||
$timezoneInterval = Application_Model_Show::GetTimezoneIntervalString();
|
||||
|
||||
$sql = "SELECT"
|
||||
." si.starts as show_starts,"
|
||||
." si.ends as show_ends,"
|
||||
|
@ -1377,11 +1427,58 @@ class Application_Model_Show {
|
|||
." FROM $CC_CONFIG[showInstances] si"
|
||||
." LEFT JOIN $CC_CONFIG[showTable] s"
|
||||
." ON si.show_id = s.id"
|
||||
." WHERE EXTRACT(DOW FROM si.starts) = $day"
|
||||
." AND EXTRACT(WEEK FROM si.starts) = EXTRACT(WEEK FROM localtimestamp)"
|
||||
." WHERE EXTRACT(DOW FROM si.starts + $timezoneInterval) = $day"
|
||||
." AND EXTRACT(WEEK FROM si.starts + $timezoneInterval) = EXTRACT(WEEK FROM localtimestamp)"
|
||||
." ORDER BY si.starts";
|
||||
|
||||
// Convert result timestamps to local timezone
|
||||
$rows = $CC_DBC->GetAll($sql);
|
||||
Application_Model_Show::ConvertToLocalTimeZone($rows, array("show_starts", "show_ends"));
|
||||
|
||||
return $CC_DBC->GetAll($sql);
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the columns given in the array $columnsToConvert in the
|
||||
* database result $rows to local timezone.
|
||||
*
|
||||
* @param type $rows arrays of arrays containing database query result
|
||||
* @param type $columnsToConvert array of column names to convert
|
||||
*/
|
||||
public static function ConvertToLocalTimeZone(&$rows, $columnsToConvert) {
|
||||
$timezone = date_default_timezone_get();
|
||||
|
||||
foreach($rows as &$row) {
|
||||
foreach($columnsToConvert as $column) {
|
||||
$row[$column] = Application_Model_DateHelper::ConvertToLocalDateTimeString($row[$column]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the timezone difference as an INTERVAL string that can be used
|
||||
* by SQL queries.
|
||||
*
|
||||
* E.g., if local timezone is -4:30, this function returns:
|
||||
* INTERVAL '-4 hours -30 minutes'
|
||||
*
|
||||
* Note that if $fromLocalToUtc is true, then it returns:
|
||||
* INTERVAL '4 hours 30 minutes'
|
||||
*
|
||||
* @param type $fromLocalToUtc true if we're converting from local to UTC
|
||||
*/
|
||||
public static function GetTimeZoneIntervalString($fromLocalToUtc = false) {
|
||||
$date = new Application_Model_DateHelper;
|
||||
$timezoneHour = $date->getLocalOffsetHour();
|
||||
$timezoneMin = $date->getLocalOffsetMinute();
|
||||
|
||||
// negate the hour and min if converting from local to UTC
|
||||
if($fromLocalToUtc) {
|
||||
$timezoneHour = -$timezoneHour;
|
||||
$timezoneMin = -$timezoneMin;
|
||||
}
|
||||
|
||||
return "INTERVAL '$timezoneHour hours $timezoneMin minutes'";
|
||||
}
|
||||
|
||||
public static function GetMaxLengths() {
|
||||
|
|
|
@ -16,44 +16,28 @@
|
|||
getServerData();
|
||||
|
||||
function updateWidget(){
|
||||
var currentShow = sd.getCurrentShow();
|
||||
var nextShows = sd.getNextShows();
|
||||
|
||||
var currentShowName = "";
|
||||
var nextShowName = ""
|
||||
|
||||
if (currentShow.length > 0){
|
||||
currentShowName = currentShow[0].getName();
|
||||
}
|
||||
|
||||
if (nextShows.length > 0){
|
||||
nextShowName = nextShows[0].getName();
|
||||
}
|
||||
var shows = sd.getNextShows();
|
||||
|
||||
tableString = "";
|
||||
tableString += "<h3>"+options.text.onAirToday+"</h3>";
|
||||
tableString += "<h3>" + options.text.onAirToday + "</h3>";
|
||||
tableString += "<table width='100%' border='0' cellspacing='0' cellpadding='0' class='widget widget no-playing-list small'>"+
|
||||
"<tbody>";
|
||||
|
||||
var shows=currentShow.concat(nextShows);
|
||||
|
||||
obj.empty();
|
||||
for (var i=0; i<shows.length; i++){
|
||||
tableString +=
|
||||
"<tr>" +
|
||||
"<td class='time'>"+shows[i].getRange()+"</td>";
|
||||
|
||||
var url = shows[i].getURL();
|
||||
|
||||
if (url.length > 0)
|
||||
tableString += "<td><a href='"+shows[i].getURL()+"'>"+shows[i].getName()+"</a></td></tr>";
|
||||
else
|
||||
tableString += "<td>"+shows[i].getName()+"</td></tr>";
|
||||
|
||||
if (url.length > 0) {
|
||||
tableString += "<td><a href='" + shows[i].getURL() + "'>" + shows[i].getName() + "</a></td></tr>";
|
||||
} else {
|
||||
tableString += "<td>" + shows[i].getName() + "</td></tr>";
|
||||
}
|
||||
}
|
||||
|
||||
tableString += "</tbody></table>";
|
||||
|
||||
obj.empty();
|
||||
obj.append(tableString);
|
||||
}
|
||||
|
||||
|
@ -66,7 +50,7 @@
|
|||
}
|
||||
|
||||
function getServerData(){
|
||||
$.ajax({ url: options.sourceDomain + "api/live-info/", dataType:"jsonp", success:function(data){
|
||||
$.ajax({ url: options.sourceDomain + "api/today-info/", dataType:"jsonp", success:function(data){
|
||||
processData(data);
|
||||
}, error:airtimeScheduleJsonpError});
|
||||
setTimeout(getServerData, options.updatePeriod*1000);
|
||||
|
@ -268,13 +252,17 @@ function ScheduleData(data){
|
|||
this.estimatedSchedulePosixTime;
|
||||
|
||||
this.currentShow = new Array();
|
||||
for (var i=0; i< data.currentShow.length; i++){
|
||||
this.currentShow[i] = new Show(data.currentShow[i]);
|
||||
if(data.currentShow != undefined) {
|
||||
for (var i=0; i< data.currentShow.length; i++){
|
||||
this.currentShow[i] = new Show(data.currentShow[i]);
|
||||
}
|
||||
}
|
||||
|
||||
this.nextShows = new Array();
|
||||
for (var i=0; i< data.nextShow.length; i++){
|
||||
this.nextShows[i] = new Show(data.nextShow[i]);
|
||||
if(data.nextShow != undefined) {
|
||||
for (var i=0; i< data.nextShow.length; i++) {
|
||||
this.nextShows[i] = new Show(data.nextShow[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue