Ravens PHP Scripts: Forums
 

 

View next topic
View previous topic
Post new topic   Reply to topic    Ravens PHP Scripts And Web Hosting Forum Index -> PHP
Author Message
mrmortimer
New Member
New Member



Joined: Jan 22, 2008
Posts: 13

PostPosted: Thu Mar 06, 2008 4:17 am Reply with quote

I've posted this same question to several PHP related sites almost a week ago, with absolutely no response. You folks seem to be my "last resort", so to speak. Confused

I've built a "web app" in PHP to handle data and business operations for the cab company I work for, and a part of the application acts as a sort of "alarm clock", displaying pre-arranged pick-ups and wake up calls. Here's the "full story":

The other day, our server was upgraded to a faster computer, and the entire application's infrastructure were upgraded, as well (apache server 2.0 to 2.2.3, php 5.0 to 5.2.5, and mySQL 4.3 to 5.0.25). I've gotten all the usual headaches dealt with (changing query syntax, fixing the "old password" hassle, etc.), except for one, and I'm not sure what to do about it. I'm missing something simple, I just know it. The trouble lies in the following section of code:
Code:


          list($h, $m) = split(":", $time);
          // hh:mm syntax string, retrieved from the db
          $timeOffset = "+$h hours $m minutes";
          // $timeOffset is the fine offset (from midnight) to add to  the event's current timestamp
          $recurring = ($recurring >= 128) ? $recurring - 128 : $recurring;
          // $recurring is an 8 bit flag field, denoting wether to repeat the event
          // on a later day/days, or if it's a single-use event.
          // If $recurring is 128, that denotes a monthly event, which is
          // handled later on (and works fine)
          $rBin = str_pad(decBin($recurring),7,"0",STR_PAD_LEFT);
          //$rBin converts $recurring to a string, representing a 7 bit binary number
          $w = date("w", $timestamp);
          $c1 = substr($rBin,0,$w);
          $c2 = substr($rBin,$w);
          $c3 = "$c2$c1";
          // the above block determines which day of the week is current, and
          // reconstructs the string, starting with the current day
          $c = $x = 0;
          while ($c == 0) {
            $x++;
            $c = intval(substr($c3,$x,1));
            if ($x >= 7) break;
          }
// the above loop counts the number of days till the next event is to occur

          $next = "+$x day";
          $next .= ($x == 1) ? "" : "s";// if more than one day, make it plural
//  $next is the gross offset, in days, to add to the event's current timestamp

          break;// Part of an earlier switch statement (not shown)
      }
      $oldDate = $date;// The event's last stored date
      $oldTS = strtotime($date);// The current unix timestamp for the event (midnight)
      $oldTS = strtotime($next, $oldTS);// Add the gross offset
      $newTimestamp = strtotime($timeOffset, $oldTS);// Add the fine offset


Fact Sheet:
$recurring binary bit values (shown in decimal):
Monthly = 128
Sunday = 64
Monday = 32
Tuesday = 16
Wednesday = 8
Thursday = 4
Friday = 2
Saturday = 1
None = 0

Now here's where it gets interesting. The generated timestamp is accurate about half of the time. But when it's off, it's off by as much as several hours, in either direction (e.g. gets set for 09:15, instead of 05:30, or for 23:30 on the previous day, rather than 06:00 {military time is used for ease of coding}). I have no clue at all what's triggering the inaccuracies.

I'm completely baffled by this behavior, and I'm looking for a more reliable way to handle this. Any suggestions would be humbly and gratefully accepted.


Last edited by mrmortimer on Fri Mar 07, 2008 7:41 am; edited 1 time in total 
View user's profile Send private message
Gremmie
Former Moderator in Good Standing



Joined: Apr 06, 2006
Posts: 2415
Location: Iowa, USA

PostPosted: Thu Mar 06, 2008 8:18 am Reply with quote

Sorry, thats an awful lot of code to try and digest. My first thought is "why do all that yourself?". There is this amazing function in php called strtotime() which I use all over the place in GCalendar. It is built on top of a GNU C library which does the same thing. Anyway, it can parse just about any "natural language" string into a time for you, and it handles all the corner cases as well. Maybe you could leverage that in your code.

http://us.php.net/manual/en/function.strtotime.php

What it can parse:
http://www.gnu.org/software/tar/manual/html_node/tar_113.html

You can say things like

$x = some timestamp value
strtotime('+4 hours', $x);
strtotime('-1 month, $x);
strtotime('3 years ago', $x);
strtotime('third monday', $x);
strtotime('next tuesday', $x);

I'm only scratching the surface, it's an amazingly useful function.

_________________
Only registered users can see links on this board! Get registered or login! - An Event Calendar for PHP-Nuke
Only registered users can see links on this board! Get registered or login! - A Google Maps Nuke Module 
View user's profile Send private message
mrmortimer







PostPosted: Thu Mar 06, 2008 5:47 pm Reply with quote

Well, after working on trying to state the problem more clearly, I decided to rewrite that section to make it more understandable, and guess what? It now works! Very Happy

The new and improved code (more of it, actually) follows:

Code:


function fillIn($out = "") {
  $id = $_POST['id'];
  $sql = "select * from `time calls` where `id` = $id";
  $out .= "<!-- SQL1 = $sql -->\n";
  $row = getDB_row($sql, "fillIn");
  if ($row != NULL) {
    foreach ($row as $key => $value) {
      $$key = $value;
    }
    $tcn = ($type == "Time Call") ? "tc$time" : "";
    $tcNotes = ($notes != "") ? "$tcn - $notes" : $tcn;
    $addnotes = ($type == "Time Call") ? "top.frmNew.dbMain[mn].value = '$tcNotes';" : "";
    $out .= <<<endScript
    <script type="text/javascript">
      addTCvals("$address", "$addnotes")
    </script>

endScript;
/*
 Values for recurring time calls:
   Monthly   = 128
   Sunday    = 64
   Monday    = 32
   Tuesday   = 16
   Wednesday = 8
   thursday  = 4
   Friday    = 2
   Saturday  = 1
*/
    $fineOffset = "+0 minutes";
    if ($recurring != 0) {
      switch ($recurring) {
        case 128:
          $next = "+1 month";
          break;
        default:
          list($h, $m) = split(":", $time);
          $fineOffset = "+$h hours $m minutes";
          $recurring = ($recurring >= 128) ? $recurring - 128 : $recurring;
          $rBin = str_pad(decBin($recurring),7,"0",STR_PAD_LEFT);
          $w = date("w", $timestamp);
          $c1 = substr($rBin,0,$w);
          $c2 = substr($rBin,$w);
          $c3 = "$c2$c1";
          $c = $x = 0;
          while ($c == 0) {
            $x++;
            $c = intval(substr($c3,$x,1));
            if ($x >= 7) break;
          }
          $next = ($x == 1) ? "+$x day" : "+$x days";
        }
        $typeOffset = ($type == "Time Call") ? 15 : 1;
        $typeOffset += $sendEarly;
        $typeOffsetString = "-$typeOffset minutes";

        $oldDate = "$date 00:00";
        $timestamp = strtotime($date);
        $oldTimestamp = strtotime($oldDate);
        $oldTimestampDate = date("m/d/Y H:i", $oldTimestamp);

        $grossOffsetTimestamp = strtotime($next, $oldTimestamp);
        $grossOffsetDate = date("m/d/Y H:i", $grossOffsetTimestamp);

        $fineOffsetTimestamp = strtotime($fineOffset, $grossOffsetTimestamp);
        $fineOffsetDate = date("m/d/Y H:i", $fineOffsetTimestamp);

        $finalTimestamp = strtotime($typeOffsetString, $fineOffsetTimestamp);
        $finalDate = date("m/d/Y", $finalTimestamp);
        $finalTime = date("H:i", $finalTimestamp);
        $out .= "<!-- newTimestamp = $finalTimestamp -->\n";
        $sql = "update `time calls` set `timestamp` = $finalTimestamp, `testTime` = '$testTime', `date` = '$finalDate', `time` = '$time' where `ID` = $ID";
    }
    else {
      $sql = "update `time calls` set `sent` = 1 where `ID` = $ID";
    }
    $out .= "<!-- SQL2 = $sql -->\n";
    $tmp = updateDB($sql, "fillIn");
  }
  return $out;
}


I'm not 100% sure why recoding it with different variable names did the trick, unless I used the wrong variable in the earlier version, and just plain missed it. But at least it works, and that's what matters. Smile

Thanks for helping, Gremmie. Causing me to sharpen my code is what turned the trick.
 
Display posts from previous:       
Post new topic   Reply to topic    Ravens PHP Scripts And Web Hosting Forum Index -> PHP

View next topic
View previous topic
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Powered by phpBB © 2001-2007 phpBB Group
All times are GMT - 6 Hours
 
Forums ©