php - timestamp - interval between days not always 86400 seconds - why? - php

Supplementry Question to timestamp - php incrementing time stamp error
Whilst accepting that class DateTime may provide a resolution to my original query there remains the unexplained variance in the timestamps. I really would like to understand this variance, whether there are other such timestamp "adjustments" and how they arise.
Please consider the following:
/*
* test time stamp variances
*/
$time_Stamp_1 = mktime(0,0,0,10,15,2012);echo "15/10/12: " . $time_Stamp_1;
$time_Stamp_2 = mktime(0,0,0,10,16,2012);echo "<br/>16/10/12: " . $time_Stamp_2 . "increment= " . ($time_Stamp_2 - $time_Stamp_1);
$time_Stamp_3 = mktime(0,0,0,10,17,2012);echo "<br/>17/10/12: " . $time_Stamp_3 . "increment= " . ($time_Stamp_3 - $time_Stamp_2);
$time_Stamp_4 = mktime(0,0,0,10,18,2012);echo "<br/>18/10/12: " . $time_Stamp_4 . "increment= " . ($time_Stamp_4 - $time_Stamp_3);
$time_Stamp_5 = mktime(0,0,0,10,19,2012);echo "<br/>19/10/12: " . $time_Stamp_5 . "increment= " . ($time_Stamp_5 - $time_Stamp_4);
$time_Stamp_6 = mktime(0,0,0,10,20,2012);echo "<br/>20/10/12: " . $time_Stamp_6 . "increment= " . ($time_Stamp_6 - $time_Stamp_5);
$time_Stamp_7 = mktime(0,0,0,10,21,2012);echo "<br/>21/10/12: " . $time_Stamp_7 . "increment= " . ($time_Stamp_7 - $time_Stamp_6);
$time_Stamp_8 = mktime(0,0,0,10,22,2012);echo "<br/>22/10/12: " . $time_Stamp_8 . "increment= " . ($time_Stamp_8 - $time_Stamp_7);
$time_Stamp_9 = mktime(0,0,0,10,23,2012);echo "<br/>23/10/12: " . $time_Stamp_9 . "increment= " . ($time_Stamp_9 - $time_Stamp_8);
$time_Stamp_10 = mktime(0,0,0,10,24,2012);echo "<br/>24/10/12: " . $time_Stamp_10 . "increment= " . ($time_Stamp_10 - $time_Stamp_9);
$time_Stamp_11 = mktime(0,0,0,10,25,2012);echo "<br/>25/10/12: " . $time_Stamp_11 . "increment= " . ($time_Stamp_11 - $time_Stamp_10);
$time_Stamp_12 = mktime(0,0,0,10,26,2012);echo "<br/>26/10/12: " . $time_Stamp_12 . "increment= " . ($time_Stamp_12 - $time_Stamp_11);
$time_Stamp_13 = mktime(0,0,0,10,27,2012);echo "<br/>27/10/12: " . $time_Stamp_13 . "increment= " . ($time_Stamp_13 - $time_Stamp_12);
$time_Stamp_14 = mktime(0,0,0,10,28,2012);echo "<br/>28/10/12: " . $time_Stamp_14 . "increment= " . ($time_Stamp_14 - $time_Stamp_13);
$time_Stamp_15 = mktime(0,0,0,10,29,2012);echo "<br/>29/10/12: " . $time_Stamp_15 . "increment= " . ($time_Stamp_15 - $time_Stamp_14);
Reports:
15/10/12: 1350255600
16/10/12: 1350342000increment= 86400
17/10/12: 1350428400increment= 86400
18/10/12: 1350514800increment= 86400
19/10/12: 1350601200increment= 86400
20/10/12: 1350687600increment= 86400
21/10/12: 1350774000increment= 86400
22/10/12: 1350860400increment= 86400
23/10/12: 1350946800increment= 86400
24/10/12: 1351033200increment= 86400
25/10/12: 1351119600increment= 86400
26/10/12: 1351206000increment= 86400
27/10/12: 1351292400increment= 86400
28/10/12: 1351378800increment= 86400
29/10/12: 1351468800increment= 90000
Hence:
> 15/10/2012 1350255600 + 604800 does increment 1 week to 22/10/2012 ..
> 22/10/2012 1350860400 + 604800 does not increment 1 week to 29/10/2012
> because although this results in 1351465200 which should be 29/10/2012
> you can see from the above that it resolves to 28/10/2012 because for
> some unexplained reason an extra hour 3600sec has been added to the
> time stamp for 29/10/2012.
I want to know because from my reading of the documentation mktime should create a timestamp just as valid as say strtotime or DateTime.
Indeed using class DateTime method getTimestamp
28/10/2012 = 1351378800
29/10/2012 = 1351468800 an increment of 90000
So once again an hour has been added implying that I am correct in this assumption.
Obviously the class can deal with this. BUT no where up until this point has there been any mention of the fact that incrementing a timestamp however it is generated could result in an issue... thus making the use of the DateTime class or another approach mandatory to avoid issues such as have been encountered.
If I have to convert the code you use the class so be it. But I would like to know why this is necessary.

Due to a daylight savings shift, 28/10/12 has an extra hour in your timezone. There are 25 hours between midnight 28/10 and midnight 29/10.
You will also find a day with 23 hours in spring.
If this is not what you expect, change the timezone to something that has no DST. UTC is one option:
php > echo mktime(0,0,0,10,29,2012) - mktime(0,0,0,10,28,2012);
90000
php > ini_set('date.timezone', 'UTC');
php > echo mktime(0,0,0,10,29,2012) - mktime(0,0,0,10,28,2012);
86400

I'm going to take a stab at this. October 29th is exactly 1 week before daylight savings time (unless you are in a country with a different daylight savings time). But falling back 1 hour would cause a day to have 1 more hour.

Related

Identify if an specific time is between a time range defined by two time fields

I have this variable containing a time:
$actualTime="22:00:00";
And a table (turn_conf) with scholar classes times, each one contaning 3 couples of time fields (6 time fields in total), indicating the time to start and finish each of the 3 blocks that every class can have (tu_mon_1_s/tu_mon_1_e , tu_mon_2_s/tu_mon_2_e , tu_mon_3_s/tu_mon_3_e).
As you see, can also be NULL for classes with only one or two blocks:
I am looking for the most efficient way to check which element (tu_id) has a couple of blocks containig time given by $actualTime
Examples:
if $actualTime stores "16:50:00", the Query must select tu_id 225, because "16:50:00" is a time between tu_mon_3_s ("16:40:00) and tu_mon_3_e ("19:30:00).
if $actualTime stores "13:30:00", the Query must select tu_id 253, because "13:30:00" is a time between tu_mon_1_s ("11:00:00) and tu_mon_1_e ("14:00:00).
"SELECT tu_id FROM turn_conf WHERE
(tu_mon_1_s >= " . $actualTime . " AND tu_mon_1_e <= " . $actualTime . ") OR
(tu_mon_2_s >= " . $actualTime . " AND tu_mon_2_e <= " . $actualTime . ") OR
(tu_mon_3_s >= " . $actualTime . " AND tu_mon_3_e <= " . $actualTime . ")"
Not tested out, but tell me if it worked.

add variable seconds to time foreach loop

I'm building a queue to generate something and I want it visible for users to see how long it will take till the generation is ready.
So I have an estimated time it takes to generate something, but that is a variable because it can be anywhere between 5-120 seconds. And now I need to add the variable time to the time of the day and make a loop because the queue has more values.
So for example I need this:
Object 1 - Estimated generation time: 15 sec - 09:00:15
Object 2 - Estimated generation time: 20 sec - 09:00:35
Object 3 - Estimated generation time: 10 sec - 09:00:45
And so on..
I already tried this:
$my_time = date('h:i:s',time());
$seconds2add = $estimated_time;
$new_time= strtotime($my_time);
$new_time+=$seconds2add;
echo date('h:i:s',$new_time);
And:
$time = date("m/d/Y h:i:s a", time() + $estimated_time);
It loops but both gives me like this output:
Object 1 - Estimated generation time: 15 sec - 09:00:15
Object 2 - Estimated generation time: 20 sec - 09:00:20
Object 3 - Estimated generation time: 10 sec - 09:00:10
So how can I make it loop that it works?
Edit: This is my loop
$this_time = date('h:i:s',time());
$my_time = $this_time;
$num = 1;
foreach($orders as $order) {
echo '<tr>'
. '<td>'.($num++).'</td>'
. '<td>'. $order->url .'</td>'
. '<td>'. $order->product_desc .'</td>'
. '<td>'. $order->size .' cm</td>'
. '<td>'. $order->estimated_time .' sec</td>';
$seconds2add = $order->estimated_time;
$my_time= strtotime($my_time);
$my_time+=$seconds2add;
echo '<td>'. date('h:i:s',$my_time) . '</td>'
. '</tr>';
}
Showing your loop code might help, but here is the general idea of what you should do:
$current_time = time(); // seconds since unix epoch
echo 'Start: ' . date('h:i:s') . PHP_EOL;
while($you_do_stuff == true) {
// do stuff
$now = time();
$time_taken = $now - $current_time;
echo $time_taken . ' seconds to process: ' . date('h:i:s', $now) . PHP_EOL;
// set current time to now
$current_time = $now;
}
echo 'Finished: ' . date('h:i:s');
Edit: here's an example with a bunch of random "estimated times" in seconds:
// ... in seconds
$estimated_times = array(
5,
20,
35,
110
);
$current_time = time(); // seconds since unix epoch
echo 'Start: ' . date('h:i:s') . PHP_EOL;
foreach($estimated_times as $estimated_time) {
// add estimated time to current time (this increases each loop)
$current_time += $estimated_time;
// output estimated time and finish time
echo 'Estimated time: ' . $estimated_time . ' seconds: ' . date('h:i:s', $current_time) . PHP_EOL;
}
Demo

Function in code I'm debugging seems to not take into account shifts to and from DST

I'm debugging a conference room booking calendar which was put together by someone which is no longer working with me. It's been a nightmare since there were so many things wrong with it, but I'm having trouble figuring out exactly what's causing this last bug. The calendar checks to see if rooms have already been booked at certain times and they aren't having an issue showing as booked at the right time, but if someone tries to book the same room an hour or less after the room is vacated after a shift to or from DST, it shows the room as booked still.
Example:
User sees that a room is reserved for Nov. 29th from 9am-10am.
User then tries to book the room on Nov. 29th from 10:30am-12:00pm.
The calendar cancels this second request and informs the user that the room is already booked.
It should be noted that this doesn't happen any time before the shift to DST (Nov. 4th). Here's the function which determines if the room is available:
function calCheck($starttime, $endtime, $cal_name, $cat_id, $myDB, $myHost, $myUser, $myPass) {
$timezone = 'America/Denver';
date_default_timezone_set ($timezone);
$dset = new DateTime($odate, new DateTimeZone($timezone));
$dset2 = $dset->getOffset();
//$starttime = $starttime + 1;
//$endtime = $endtime - 1;
$starttime = $starttime - $dset2 + 1;
$endtime = $endtime - $dset2 - 1;
$starttime = $starttime;
$endtime = $endtime;
//echo $starttime .'</br>'. $endtime . '</br>';
$db = new myDB($myDB, $myHost, $myUser, $myPass);
$db->myDB_Connect();
//echo 'calcheck</br>';
$ck_query = 'SELECT * FROM vw_cal_chk
WHERE (stime < '. $starttime . ' AND etime > ' . $starttime . ' ) and Calendar = "' . $cal_name . '" and cat_id = "' .$cat_id . '"
OR (stime < ' . $endtime . ' AND etime > ' . $endtime . ') and Calendar = "' . $cal_name . '" and cat_id = "' .$cat_id . '"
OR (stime >= '. $starttime . ' AND etime < ' . $endtime .') and Calendar = "' . $cal_name . '" and cat_id = "' .$cat_id . '"';
$ck_result = $db->myQuery($ck_query);
$num = mysql_num_rows($ck_result);
//echo $ck_query . '</br>' . $num;
if ($num >> 0){
$avail = 1;
} else {
$avail = 0;
}
return $avail;
}
All of my timestamps up to this point are in UTC and I notice the $odate variable is actually never instantiated anywhere, but I haven't been able to determine what value to pass it in order for the offsetting to work correctly. If I can find out what kind of date it wants, I should be able to work the rest out.
$odate is null which defaults to now giving you the current offset. What you want is the offset at the time that the schedule is being set not the offset right at this moment. It looks like your database dates are in Mountain time and that your startdate is utc and you are subtracting the offset to get back to mountain (I would think that you would add the offsets not subtract , so I might have this reversed, can you query your database and figure it out?)
In any event you should be computing your offset using $startdate not now(), try switching $startdate for $odate and see what happens. If this doesn't work try building a string from startdate and then generating a new date from that string. If nothing else outputting that string should give you a clear picture as to whether $startdate is UTC or mountain

Schedule Post - Displaying Some Content only for Some time or any time in future or Repitative

I am trying to display some content only for some time or some days
I have start time, start date, end time and end date in database so that when the data is fetched from database this time and dates should be checked and display the content accordingly
My code that i have tried
$startDateTime = strtotime($result['StartDate']." ".$result['StartTime']);
$endDateTime = strtotime($result['EndDate']." ".$result['EndTime']);
$now = time();
echo "START : ".$startDateTime;
echo "<br/>END : ".$endDateTime;
echo "<br/>CURRENT : ".$now;
if($now >= $startDateTime && $now <= $endDateTime){
echo $result['content'];
}
But its not working its displaying the content every time
Please Help Me
Thanks in advance
output a list of your $result['StartDate']." ".$result['StartTime'] I think you'll find that it might be leaving off leading 0's or something which would give it trouble casting it as a time.
Rather than using the time() function - try creating '$now' as strtotime("now").
Also, as a debugging step, it probably would have helped you to echo the comparisons to see if they evaluated the way that you expected.
Actually - I just tried your code exactly as it was...Except that I had hard coded values for the starting and ending dates and times. And it worked, so switching to use strtotime("now") will probably not make a difference.
What are the values that were printed out? You didn't tell us.
So VoronoiPotato is probably right...The values you are storing for StartDate/StartTime and EndDate/EndTime must have something wrong with them.
What is the output of your program if you change it like this (to add more debugging):
$startDateTime = $result['StartDate'] . " " . $result['StartTime'];
$endDateTime = $result['EndDate'] . " " . $result['EndTime'];
$now = time();
echo "START : " . $startDateTime."<br />\n";
echo "END : " . $endDateTime . "<br />\n";
$startDateTime = strtotime($startDateTime);
$endDateTime = strtotime($endDateTime);
echo "Start as time: " . $startDateTime . "<br />\n";
echo "End as time: " . $endDateTime . "<br />\n";
echo "CURRENT : " . $now . "\n";
if (($now >= $startDateTime) && ($now <= $endDateTime)) {
echo $result['content'];
}

Calculate If it's been less or more than 24 Hours using PHP

I want to calculate the times between two set times (Cron job run 1 Hour, every Hour).
E.G:
2:18 PM on 20/06/2012
3:00 PM on 21/06/2012 * Cron Job Runs, More than 24 Hours
How would I calculate this in PHP to do a task that I will develop later.
Script I've attempted:
define("SECONDS_PER_HOUR", 60*60);
date_default_timezone_set('UTC');
$result = mysql_query("SELECT * FROM tickets") or die(mysql_error());
while($row = mysql_fetch_array($result)) {
// Calculate the start time
$str = $row['openTime'] . " " . $row['openDate'];
$startdatetime = strtotime($str);
$enddatetime = time();
// calculate the difference in seconds.
$difference = $enddatetime - $startdatetime;
$hoursDiff = $difference / SECONDS_PER_HOUR;
$minutesDiffRemainder = $difference % SECONDS_PER_HOUR;
echo $row['ticketID'] . ": " . $hoursDiff . "h " . $minutesDiffRemainder . "m<br />";
}
Have you considered actually doing a query that does what you need and not pull all data and doing the comparison in PHP? You could do
SELECT * from TICKETS WHERE DATE_ADD(open time, INTERVAL 24 HOUR) > CURTIME();
From reading your code, I'd assume you need to make the opentime field is a timestamp, containing both date and time. But that is the sensible choice in most cases, anyway.

Categories