I have a record returned from MySQL that has a datetime field. What I want to do is take this value and see if it is older then 24 hours, I presume using PHP's time() to get the current time.
At the moment if I echo them out I get:
1276954824 this is php's time()
2010-06-19 09:39:23 this is the MySQL datetime
I presume the top one is a unix time? Have been playing around with strtotime but with not much success..
ANy help welcome!
No success?
echo strtotime("2010-06-19 09:39:23");
gives me
1276940363
(mktime(9, 39, 23, 6, 19, 2010) gives the same time, so the parsing works correctly)
To get the differences in seconds, you can substract the timestamps, e.g.
$diff = time() - strtotime("2010-06-19 09:39:23");
If the differences is larger than 86400 (60*60*24) seconds, then the timestamps are more than one day apart:
if(time() - strtotime("2010-06-19 09:39:23") > 60*60*24) {
// timestamp is older than one day
}
You can also do:
SELECT * FROM my_table WHERE timestamp < NOW() - INTERVAL 1 DAY;
Why are you mixing PHP times and MySQL times?
Instead, do the comparison directly in MySQL:
To get the current date/time in MySQL use the NOW() function. You can compare, for example, 2010-06-19 09:39:23' < DATE_SUB(NOW(), INTERVAL 1 DAY)
This would check to see if the given date (presumably in a column) is older than 24 hours.
If it's absolutely necessary to convert a MySQL timestamp to a UNIX timestamp, you can use MySQL's UNIX_TIMESTAMP() function to do so.
I wrote a function, by which you can determine if the first given date is one day or n days bigger or smaller than the second given date.
$date1 = "2013/03/01";
$date2 = "2013/03/01";
$sign = "-";
$diff = 1;
$result = isDaysSmallerBigger($date1, $date2, $sign, $diff);
var_dump($result);
/**
* Note: this function is only supported in php 5.3 or above
* 1. If $date1 - $date2 = $sign $diff days, return true;
* 2. If $date1 equals $date2 and $diff euqals 0, whether $sign is "+" or "-", return true
* 3. Else return false;
* #param unknown_type $date1
* #param unknown_type $date2
* #param string $sign: "-": $date1 < $date2; "+": $date1 > $date2;
* Besides if $diff is 0, then both "-" and "+" means $date1 === $date2;
* #param integer $diff: date difference between two given dates
*/
function isDaysSmallerBigger($date1, $date2, $sign, $diff) {
$dateTime1 = new DateTime($date1);
$dateTime2 = new DateTime($date2);
$interval = $dateTime2->diff($dateTime1);
$dayDiff = $interval->format('%a');
$diffSign = $interval->format('%R');
if((int)$dayDiff === (int)$diff) {
// Correct date difference
if((int)$diff !== 0) {
// Day difference is not 0
if($diffSign === $sign) {
return true;
} else {
return false;
}
} else if((int)$diff === 0) {
// Day difference is 0, then both given "+" and "-" return true
return true;
}
} else {
// Incorrect date difference
return false;
}
}
Related
In this case $interval i am giving as integer means it is working fine returning true, suppose $interval i am giving as string means not working properly returning false.
scenario 1
<?php
$restDate = "2018-11-21 11:58:55";
$difference = strtotime(date('Y-m-d H:i:s')) - strtotime($restDate);
$interval = 60 * 60 * 24 * 7;
if($difference <= $interval){
$data['passwordResetStatus'] = true;
}else{
$data['passwordResetStatus'] = false;
}
var_dump($data);
?>
Output
array(1) { ["passwordResetStatus"]=> bool(true) }
scenario 2
<?php
$restDate = "2018-11-21 11:58:55";
$difference = strtotime(date('Y-m-d H:i:s')) - strtotime($restDate);
$interval = "60 * 60 * 24 * 7"; // changes from here
if($difference <= $interval){
$data['passwordResetStatus'] = true;
}else{
$data['passwordResetStatus'] = false;
}
var_dump($data);
?>
Output
array(1) { ["passwordResetStatus"]=> bool(false) }
My expected out
scenario 2 also it should return as array(1) { ["passwordResetStatus"]=> bool(true) }
Instead of having the user input "60*60*24*7", can't the user input "1 week"?
If yes a much safer way than eval is to use strtotime to compute the time.
echo strtotime("1 week")-time();
// Same as 60*60*24*7
Obviously you cannot put math equations in string, but if for some reason you got them in string format, and you are sure they will be always is format like this, you can parse it..
f.e.:
$interval = array_product(explode('*',"60 * 60 * 24 * 7"));
Why not working with the PHP DateTime classes? Here 's a short solution.
$today = new \DateTime();
$rest = new \DateTime('2018-11-21 11:58:55');
$interval = $rest->diff($today);
$passwordValid = $interval->format('%a') >= 7 ? false : true;
What I 've done here? First we need todays time. After that we need the time, with which we compare todays time. Both times are DateTime instances. Because of that we can calculate the difference between both time pretty easy. The DateTime class got the diff method, which calculates the difference between two DateTime objects. It returns a DateInterval object, which holds the difference. Now we can compare the calculated difference with your interval of 7 days.
Pretty easy, hm?
$date1 = "2017-04-13 09:09:80:300"
$date2 = "2017-04-13 09:09:80:400"
how can I check if the date2 is more or less 100 milliseconds then $date 1 in and false if not (101 - more or less)
Your question, while deceptively appearing simple, is actually fairly ugly, because it is the case that PHP's strtotime() function truncates milliseconds from a timestamp. Actually, it won't even correctly process the timestamps $date1 and $date2 which you have in your question. One workaround is to trim off the millisecond portion of the timestamp, use strtotime() to get milliseconds since the epoch, then use a regex to obtain and add the millisecond portion to this amount.
$date1 = "2017-04-13 09:09:40:300";
$date2 = "2017-04-13 09:09:40:400";
preg_match('/^.+:(\d+)$/i', $date1, $matches);
$millis1 = $matches[1];
$ts1 = strtotime(substr($date1, 0, 18))*1000 + $millis1;
preg_match('/^.+:(\d+)$/i', $date2, $matches);
$millis2 = $matches[1];
$ts2 = strtotime(substr($date2, 0, 18))*1000 + $millis2;
if (abs($ts1 - $ts2) < 100) {
echo "within 100 millseconds";
}
else {
echo "not within 100 millseconds";
}
Demo here:
Rextester
If you get your time in such format (I changed 09:09:80 to 09:09:40 as it was incorrect format)
$date1 = "2017-04-13 09:09:40:300"
$date2 = "2017-04-13 09:09:40:400"
create custom function since strtotime doesn't support ms
function myDateToMs($str) {
list($ms, $date) = array_map('strrev', explode(":", strrev($str), 2));
$ts = strtotime($date);
if ($ts === false) {
throw new \InvalidArgumentException("Wrong date format");
}
return $ts * 1000 + $ms;
}
now just check does difference is less than 100
$lessOrEqual100 = abs(myDateToMs($date1) - myDateToMs($date2)) <= 100;
According to the php manual for strtotime fractions of a second are allowed, although currently ignored by the strtotime function.
This means you could express your dates like this 2017-04-13 09:00:20.100 to have them parsed by strtotime without error (keeping them futureproofed) and then use a custom function to compare just the millisecond portion of the dates if the timestamps are the same
The below function will return true if the dates are within 100 milliseconds, false otherwise. You can pass in the amount to compare them by as an argument.
<?php
date_default_timezone_set ( "UTC" );
$date1 = "2017-04-13 09:00:20.100";
$date2 = "2017-04-13 09:00:20.300";
// pass date1, date2 and the amount to compare them by
$res = compareMilliseconds($date1,$date2,100);
var_dump($res);
function compareMilliseconds($date1,$date2,$compare_amount){
if(strtotime($date1) == strtotime($date2)){
list($throw,$milliseond1) = explode('.',$date1);
list($throw,$milliseond2) = explode('.',$date2);
return ( ($milliseond2 - $milliseond1) < $compare_amount);
}
}
?>
PHP 7.1 lets you do it with DateTime objects...
Be sure to test all other answers with a change of day as a true indicator of a successful process.
Demo
Code:
$dt1 = DateTime::createFromFormat('Y-m-d H:i:s:u e', "2017-04-14 0:00:00:000 UTC");
$dt2 = DateTime::createFromFormat('Y-m-d H:i:s:u e', "2017-04-13 23:59:59:999 UTC");
var_export($dt1->format('Y-m-d H:i:s:u'));
echo "\n";
var_export($dt2->format('Y-m-d H:i:s:u'));
echo "\n";
//var_export($dt1->diff($dt2));
echo "\n";
$diff=$dt1->diff($dt2);
// cast $diff as an array so array_intersect_assoc() can be used
if(sizeof(array_intersect_assoc(['y'=>0,'m'=>0,'d'=>0,'h'=>0,'i'=>0],(array)$diff))==5){
// years, months, days, hours, and minutes are all 0
var_export($micro=round(abs($diff->s+$diff->f),3));
// combine seconds with microseconds then test
echo "\n";
if($micro>.1){
echo "larger than .1";
}else{
echo "less than or equal to .1";
}
}else{
echo "too large by units larger than seconds";
}
Outputs:
'2017-04-14 00:00:00:000000'
'2017-04-13 23:59:59:999000'
0.001
less than or equal to .1
Ok so I am working on a calendar application within my CRM system and I need to find the upper and lower bounds of the half an hour surrorunding the timestamp at which somebody entered an event in the calendar in order to run some SQL on the DB to determine if they already have something booked in within that timeslot.
For example I have the timestamp of 1330518155 = 29 February 2012 16:22:35 GMT+4
so I need to get 1330516800 and 1330518600 which equal 16:00 and 16:30.
If anyone has any ideas or think I am approaching developing the calendar in a stupid way let me know! Its my first time on such a task involving so much work with times and dates so any advice appreciated!
Use modulo.
$prev = 1330518155 - (1330518155 % 1800);
$next = $prev + 1800;
The modulo operator gives the remainder part of division.
I didn't read the questions clearly, but this code will round to the nearest half hour, for those who don't need the range between the two. Uses some of SenorAmor's code. Props and his mad elegant solution to the correct question.
$time = 1330518155; //Or whatever your time is in unix timestamp
//Store how many seconds long our rounding interval is
//1800 equals one half hour
//Change this to whatever interval to round by
$INTERVAL_SECONDS = 1800; //30*60
//Find how far off the prior interval we are
$offset = ($time % $INTERVAL_SECONDS);
//Removing this offset takes us to the "round down" half hour
$rounded = $time - $offset;
//Now add the full interval if we should have rounded up
if($offset > ($INTERVAL_SECONDS/2)){
$nearestInterval = $rounded + $INTERVAL_SECONDS;
}
else{
$nearestInterval = $rounded
}
You could use the modulo operator.
$time -= $time % 3600; // nearest hour (always rounds down)
Hopefully this is enough to point you in the right direction, if not please add a comment and I'll try to craft a more specific example.
PHP does have a DateTime class and a whole slough of methods that it provides. You could use these if you like, but I find it easier to use the built-in date() and strtotime() functions.
Here's my solution:
// Assume $timestamp has the original timestamp, i.e. 2012-03-09 16:23:41
$day = date( 'Y-m-d', $timestamp ); // $day is now "2012-03-09"
$hour = (int)date( 'H', $timestamp ); // $hour is now (int)16
$minute = (int)date( 'i', $timestamp ); // $minute is now (int)23
if( $minute < 30 ){
$windowStart = strtotime( "$day $hour:00:00" );
$windowEnd = strtotime( "$day $hour:30:00" );
} else {
$windowStart = strtotime( "$day $hour:30:00" );
if( ++$hour > 23 ){
// if we crossed midnight, fix the date and set the hour to 00
$day = date( 'Y-m-d', $timestamp + (24*60*60) );
$hour = '00';
}
$windowEnd = strtotime( "$day $hour:00:00" );
}
// Now $windowStart and $windowEnd are the unix timestamps of your endpoints
There are a few improvements that can be made on this, but that's the basic core.
[Edit: corrected my variable names!]
[Edit: I've revisited this answer because, to my embarrassment, I realized that it didn't handle the last half-hour of a day correctly. I've fixed that issue. Note that $day is fixed by adding a day's worth of seconds to the timestamp -- doing it this way means we don't have to worry about crossing month boundaries, leap days, etc. because PHP will format it correctly for us regardless.]
If you need to get the current time and then apply the rounding (down) of the time, I would do the following:
$now = date('U');
$offset = ($now % 1800);
$now = $now-$offset;
for ($i = 0;$i < 24; $i++)
{
echo date('g:i',$now);
$now += 1800;
}
Or you could round up by adding the offset, and do something more than just echo the time. The for loop then displays the 12 hours of increments. I used the above in a recent project.
I'd use the localtime and the mktime function.
$localtime = localtime($time, true);
$localtime['tm_sec'] = 0;
$localtime['tm_min'] = 30;
$time = mktime($localtime);
Far from my best work... but here's some functions for working with string or unix time stamp.
/**
* Takes a timestamp like "2016-10-01 17:59:01" and returns "2016-10-01 18:00"
* Note: assumes timestamp is in UTC
*
* #param $timestampString - a valid string which will be converted to unix with time()
* #param int $mins - interval to round to (ex: 15, 30, 60);
* #param string $format - the format to return the timestamp default is Y-m-d H:i
* #return bool|string
*/
function roundTimeString( $timestampString, $mins = 30, $format="Y-m-d H:i") {
return gmdate( $format, roundTimeUnix( time($timestampString), $mins ));
}
/**
* Rounds the time to the nearest minute interval, example: 15 would round times to 0, 15, 30,45
* if $mins = 60, 1:00, 2:00
* #param $unixTimestamp
* #param int $mins
* #return mixed
*/
function roundTimeUnix( $unixTimestamp, $mins = 30 ) {
$roundSecs = $mins*60;
$offset = $unixTimestamp % $roundSecs;
$prev = $unixTimestamp - $offset;
if( $offset > $roundSecs/2 ) {
return $prev + $roundSecs;
}
return $prev;
}
This is a solution using DateTimeInterface and keeping timezone information etc. Will also handle timezones that are not a multiple of 30 minutes offset from GMT (e.g. Asia/Kathmandu).
/**
* Return a DateTimeInterface object that is rounded down to the nearest half hour.
* #param \DateTimeInterface $dateTime
* #return \DateTimeInterface
* #throws \UnexpectedValueException if the $dateTime object is an unknown type
*/
function roundToHalfHour(\DateTimeInterface $dateTime)
{
$hours = (int)$dateTime->format('H');
$minutes = $dateTime->format('i');
# Round down to the last half hour period
$minutes = $minutes >= 30 ? 30 : 0;
if ($dateTime instanceof \DateTimeImmutable) {
return $dateTime->setTime($hours, $minutes);
} elseif ($dateTime instanceof \DateTime) {
// Don't change the object that was passed in, but return a new object
$dateTime = clone $dateTime;
$dateTime->setTime($hours, $minutes);
return $dateTime;
}
throw new UnexpectedValueException('Unexpected DateTimeInterface object');
}
You'll need to have created the DateTime object first though - perhaps with something like $dateTime = new DateTimeImmutable('#' . $timestamp). You can also set the timezone in the constructor.
Math.round(timestamp/1800)*1800
As you probably know, a UNIX timestamp is a number of seconds, so substract/add 1800 (number of seconds in 30 minutes) and you will get the desired result.
Here's a more semantic method for those that have to make a few of these, perhaps at certain times of the day.
$time = strtotime(date('Y-m-d H:00:00'));
You can change that H to any 0-23 number, so you can round to that hour of that day.
I had two times in the format like 7:30:00 and 22:30:00 stored in the variables $resttimefrom and $resttimeto respectively.
I want to check whether the current time is between these two values. I am checking this with the code
$time = date("G:i:s");
if ($time > $resttimefrom and $time < $resttimeto ){
$stat = "open";
} else {
$stat = "close";
}
But I am always getting the $stat as Close. What may cause that?
you can try using strtotime
$st_time = strtotime($resttimefrom);
$end_time = strtotime($resttimeto);
$cur_time = strtotime(now);
then check
if($st_time < $cur_time && $end_time > $cur_time)
{
echo "WE ARE CLOSE NOW !!";
}
else{
echo "WE ARE OPEN NOW !!";
}
i hope this may help you..
A simple yet smart way to do this is to remove the ':' from your dates.
$resttimefrom = 73000;
$resttimeto = 223000;
$currentTime = (int) date('Gis');
if ($currentTime > $resttimefrom && $currentTime < $resttimeto )
{
$stat="open";
}
else
{
$stat="close";
}
$today = date("m-d-y ");
$now = date("m-d-y G:i:s");
if (strtotime($today . $resttimefrom) < $now && $now > strtotime($today . $resttimeto)) {
$stat = 'open';
else
$stat = 'close
Try reformatting them into something that you can compare like that. For example, numbers:
$resttimefrom = mktime(7,30,0);
$resttimeto = mktime(22,30,0);
$time = mktime(date('H'),date('i'),date('s'));
You are comparing strings.
Convert the Time Strings to timestamps with strtotime().
Then compare against time().
Just convert your dates to a Unix Timestamp, compare them, you have your results! It might look something like this:
$time =date("G:i:s");
$time1 = strtotime($time);
$resttimefrom1 = strtotime($resttimefrom );
$resttimeto1 = strtotime($resttimeto );
if ($time1 >$resttimefrom and $time1 <$resttimeto)
{
$stat="open";
}
else
{
$stat="close";
}
The date function returns a string, so the comparison you're making would be a string comparison - so 7:30 would be more than 22:30
It would be much better to use mktime, which will return a Unix timestamp value (integer) so it would make for a better comparison
$currentTime = mktime();
$resttimefrom = mktime(hour,min,second);
http://php.net/mktime
The trick to manipulating and comparing dates and times in PHP is to store date/time values in an integer variable and to use the mktime(), date() and strtotime() functions. The integer repesentation of a date/time is the number of seconds since midnight, 1970-Jan-1, which is referred to as the 'epoch'. Once your date/time is in integer form you'll be able to efficiently compare it to other dates that are also in integer form.
Of course since you'll most likely be receiving date/time values from page requests and database select queries you'll need to convert your date/time string into an integer before you can do any comparison or arithmetic.
Assuming you are sure that the $resttimefrom and $resttimeto variables contain properly formatted time you can use the strtotime() function to convert your string time into an integer. strtotime() takes a string that is formatted as a date and converts it to the number of seconds since epoch.
$time_from = strtotime($resttimefrom);
$time_to = strtotime($resttimeto);
Side note: strtotime() always returns a full date in integer form. If your string doesn't have a date, only a time, strtotime() return today's date along with the time you gave in the string. This is not important to you, though, because the two dates returned by strtotime() will have the same date and comparing the two variables will have the desired effect of comparing the two times as the dates cancel each other out.
When you compare the two integers keep in mind that the earlier the date/time is, the smaller its integer value will be. So if you want to see if $time_from is earlier than $time_to, you would have this:
if ($time_from < $time_to)
{
// $time_from is ealier than $time_to
}
Now to compare a date/time with the current system date/time, just use mktime() with no parameters to represent the current date/time:
if ($time_from < mktime())
{
// $time_from is in the past
}
$firstTime = '1:07';
$secondTime = '3:01';
list($firstMinutes, $firstSeconds) = explode(':', $firstTime);
list($secondMinutes, $secondSeconds) = explode(':', $secondTime);
$firstSeconds += ($firstMinutes * 60);
$secondSeconds += ($secondMinutes * 60);
$difference = $secondSeconds - $firstSeconds;
$Time1 = date_parse($time);
$seconds1 = $Time1['hour'] * 3600 + $Time1['minute'] * 60 + $Time1['second'];
$Time2 = date_parse($current_time);
$seconds2 = Time2['hour'] * 3600 + Time2['minute'] * 60 + Time2['second'];
$actula_time = $seconds1 - $seconds2;
echo floor($actula_time / 3600) .":". floor(($actula_time / 60)%60) .":". $actula_time%60;
As Col. Shrapnel Said i am doing by converting all the time in to seconds and then compare it with current time's total seconds
I'm trying to work with dates for the first time, I did it something about that with Flash but it's different.
I have two different dates and I'd like to see the difference in hours and days with them, I've found too many examples but not what I'm loking for:
<?php
$now_date = strtotime (date ('Y-m-d H:i:s')); // the current date
$key_date = strtotime (date ("2009-11-21 14:08:42"));
print date ($now_date - $key_date);
// it returns an integer like 5813, 5814, 5815, etc... (I presume they are seconds)
?>
How can I convert it to hours or to days?
The DateTime diff function returns a DateInterval object. This object consists of variabeles related to the difference. You can query the days, hours, minutes, seconds just like in the example above.
Example:
<?php
$dateObject = new DateTime(); // No arguments means 'now'
$otherDateObject = new DateTime('2008-08-14 03:14:15');
$diffObject = $dateObject->diff($otherDateObject));
echo "Days of difference: ". $diffObject->days;
?>
See the manual about DateTime.
Sadly, it's a PHP 5.3> only feature.
Well, you can always use date_diff, but that is only for PHP 5.3.0+
The alternative would be math.
How can I convert it [seconds] to hours or to days?
There are 60 seconds per minute, which means there are 3600 seconds per hour.
$hours = $seconds/3600;
And, of course, if you need days ...
$days = $hours/24;
If you dont have PHP5.3 you could use this method from userland (taken from WebDeveloper.com)
function date_time_diff($start, $end, $date_only = true) // $start and $end as timestamps
{
if ($start < $end) {
list($end, $start) = array($start, $end);
}
$result = array('years' => 0, 'months' => 0, 'days' => 0);
if (!$date_only) {
$result = array_merge($result, array('hours' => 0, 'minutes' => 0, 'seconds' => 0));
}
foreach ($result as $period => $value) {
while (($start = strtotime('-1 ' . $period, $start)) >= $end) {
$result[$period]++;
}
$start = strtotime('+1 ' . $period, $start);
}
return $result;
}
$date_1 = strtotime('2005-07-31');
$date_2 = time();
$diff = date_time_diff($date_1, $date_2);
foreach ($diff as $key => $val) {
echo $val . ' ' . $key . ' ';
}
// Displays:
// 3 years 4 months 11 days
TheGrandWazoo mentioned a method for php 5.3>. For lower versions you can devide the number of seconds between the two dates with the number of seconds in a day to find the number of days.
For days, you do:
$days = floor(($now_date - $key_date) / (60 * 60 * 24))
If you want to know how many hours are still left, you can use the modulo operator (%)
$hours = floor((($now_date - $key_date) % * (60 * 60 * 24)) / 60 * 60)
<?php
$now_date = strtotime (date ('Y-m-d H:i:s')); // the current date
$key_date = strtotime (date ("2009-11-21 14:08:42"));
$diff = $now_date - $key_date;
$days = floor($diff/(60*60*24));
$hours = floor(($diff-($days*60*60*24))/(60*60));
print $days." ".$hours." difference";
?>
I prefer to use epoch/unix time deltas. Time represented in seconds and as such you can very quickly divide by 3600 for hours and divide by 24*3600=86400 for days.