I'm creating an application for a friend to handle Deadlines. I have a page set up where each user can see their own 'jobs to do' with a deadline next to it. My question is...
How do I compare a deadline date that comes back from the mysql query as 2010.08.08 with today's date?
For Example...
<?php
while($row = mysql_fetch_array($result)){
$jobfinishdate = $row['jobfinishdate'];
$date = date('Y-m-d');
if ($jobfinishdate>$date)
$jobfinishdate .= " - Not due yet!" ;
else if ($jobfinishdate<$date)
$jobfinishdate .= " - You didn't meet this deadline!";
else if ($jobfinishdate==$date)
$jobfinishdate .= " - Deadline is TODAY!";
}
?>
This works ok. But what I'd really like to do is display a message saying 'you have 5 days until deadline. Any ideas how to get around this?
Thanks.
Shane.
If possible I would let the database return the number of days, with a query like this:
SELECT jobfinishdate, datediff(jobfinishdate, NOW() AS days) FROM table
Then use this number of days:
while ($row = mysql_fetch_array($result)){
$jobfinishdate = $row['jobfinishdate'];
$days = $row['days'];
if ($days > 0) {
$jobfinishdate .= " - Not due yet! $days until deadline" ;
} elseif ($days < 0) {
$jobfinishdate .= " - You didn't meet this deadline!";
} else {
$jobfinishdate .= " - Deadline is TODAY!";
}
}
Some other remarks:
If you keep the date calculation in PHP, move the $date declaration outside the while loop because you only need to do that once.
you can remove the last condition, if ($jobfinishdate==$date). If the date is not larger and not smaller, it can only be equal.
$days = (strtotime($jobfinishdate) - strtotime($date)) / (60 * 60 * 24);
Should get you the amount of days left on the deadline.
Edit: The above will always return the difference in days - to handle whether or not its before or beyond the due date, maybe (using just time() as Adam suggested):
$date_passed = false;
$days = strtotime($jobfinishdate) - time();
if ($days < 0) { $date_passed = true; }
$days = $days / (60 * 60 * 24);
if (!$date_passed)
{
echo "You have $days days left on this project.";
}
else
{
echo "Deadline has expired $days days ago.";
}
// calculate days left
$daysleft = round( ( strtotime( $jobfinishdate ) - time() ) / 86400 );
// print out text for $daysleft
if( $daysleft == 0 )
print( "Deadline is today!" );
else if ( $daysleft > 0 )
printf( "You have %d days until deadline.", $daysleft );
else
print( "You did not meet the deadline!" );
If you're using PHP 5.3.0 or newer you can use the DateTime object
In SQL query:
SELECT
...,
TIMESTAMPDIFF(DAY, NOW(), `date_deadline`) AS days_to_deadline
...
This will produce positive number of days due deadline and negative for expired tasks.
Related
I want to get a user registered date, count the days since registration and show max days left to given days and show message after period ends.
What I got so far works:
$regDatestr = '2020-04-09 19:38:10';
$regDate = strtotime($regDatestr);
$regSince = time() - $regDate;
$days = round ($regSince / ( 60 * 60 * 24 ));
$maxDays = 20;
$maxDaysstr = strtotime("-$maxDays days");
$maxReg = ($regSince + $maxDaysstr);
$daysleft = time() - $maxReg;
$restDays = round ($daysleft / ( 60 * 60 * 24 ));
if ($regdate <= $maxDaysstr) :
echo 'period ended'
else :
echo 'Registered since' . $days . ' .days . Rest days ' . $restDays . '
endif;
$daysleft and days gives me the right days. But the period doesnt end exact after 20 days.
What I need is max 20 days since registration date. So when
'2020-04-09 19:38:10';
plus 20 days should end the period at
'2020-04-29 19:38:10';
but it seems my if condition doesnt work as expected. So Im getting "Registered since 21 days. Rest days 0".
Why is that so?
Because you have an typo in with your variable names
if ($regdate <= $maxDaysstr)
should be
if ($regDate <= $maxDaysstr)
and your code could be shorter
$regDatestr = '2020-04-01 19:38:10';
$regDate = new DateTime($regDatestr);
$diffToday = $regDate->diff(new DateTime());
$maxDays = 10;
$diffMax = $regDate->diff(new DateTime("-$maxDays days"));
if ($diffMax->invert == 0) :
echo 'period ended';
else :
echo 'Registered since ' . $diffToday->days . ' .days . Rest days ' . $diffMax->days;
endif;
This question already has answers here:
How do I find the hour difference between two dates in PHP?
(10 answers)
Closed 5 years ago.
I have datetimes in the following format:
Start: 2017-07-16 20:00
End: 2017-07-16 23:30
Start: 2017-07-18 21:30
End: 2017-07-19 00:30
I need to tell from these intervals how many hours (in 0,5 increments) are spent between 18:00-22:00 and 22:00-06:00 in total for a month.
Thanks in advance for any hint.
The current code I have is this, but I'm not sure if it is covering all timeframe possibilities:
<?php
date_default_timezone_set("UTC");
$start = array(
"2017-07-16 21:30:00",
"2017-07-16 18:00:00"
);
$end = array(
"2017-07-17 00:30:00",
"2017-07-16 18:30:00"
);
$amount_low = 0;
$amount_high = 0;
for($i = 0; $i < sizeof($start); $i++) {
$start_time = date("H:i:s", strtotime($start[$i]));
$end_time = date("H:i:s", strtotime($end[$i]));
$start_date = date("Ymd", strtotime($start[$i]));
$end_date = date("Ymd", strtotime($end[$i]));
// getting chunk before 22:00 if
if(
(strtotime($start[$i]) >= strtotime($start_date . " 18:00") && strtotime($start[$i]) < strtotime($start_date . " 22:00"))
&&
$start_date < $end_date
) {
$interval_low = strtotime($start_date . " 22:00") - strtotime($start[$i]);
$amount_low += ceil($interval_low / 1800) / 2;
}
//amount_high
if(strtotime($start[$i]) > strtotime($start_date . " 22:00") && strtotime($start[$i]) < strtotime($start_date . " 06:00")) {
$interval_high = strtotime($end[$i]) - strtotime($start[$i]); //needs further things
$amount_high += ceil($interval_high / 1800) / 2;
} elseif (strtotime($start[$i]) < strtotime($start_date . " 22:00") && strtotime($end[$i]) > strtotime($start_date . " 22:00")) {
$interval_high = strtotime($end[$i]) - strtotime($start_date . " 22:00");
$amount_high += ceil($interval_high / 1800) / 2;
} else {
$interval_low = strtotime($end[$i]) - strtotime($start[$i]);
$amount_low += ceil($interval_low / 1800) / 2;
}
}
echo $amount_low;
echo "\n$amount_high";
?>
Would this work for you?
$start = strtotime('2017-07-16 20:00');
$end = strtotime('2017-07-16 23:30');
$interval = $end - $start;
$hours = floor($interval / 1800)/2;
echo($hours);
This will display the total hours (in 0,5 increments) between the two dates (rounding down, so if it's 55 minutes, it's 0,5 hours; replace 'floor' with 'ceil' for the opposite).
I believe a part of your solution is found here from Aillyn
You can convert them to timestamps and go from there:
$hourdiff = round((strtotime($time1) - strtotime($time2))/3600, 1);
Dividing by 3600 because there are 3600 seconds in one hour and using round()
to avoid having a lot of decimal places.
$hourdiff = round((strtotime($time1) - strtotime($time2))/3600, 1);
This will give you a rounded hour difference between the two times. You could do something similar, just apply it for each interval for which ever month and adjust your math. There's not really going to be a single PHP function you can call to solve this.
I've been trying to figure out how to output the amount of weeks between 2 dates using strings given to my server.
Every thread I found that has potentially the same problem as me is using datetime() which I'm not extremely familiar with, and I believe uses a different structure than me.
Anyways, I can't figure this out and I've been trying for a couple of hours.
These are the strings I need to feed into the function:
From: "8/3/2015" to: "07/27/2015"
Note, the from string will change each week according to the monday from every week. Also, there are several To dates, and there will be a new one each week.
It would also be a lovely feature if it converted to months and years if it applies.
UPDATE
This is what I came up with, with the help of phplovers answer. This should successfully give you back the amount of days, unless its more than 7, then it would give you weeks, then months, then years.
Pardon the messiness.
$from = date_create($startDate);
$to = date_create($endDate);
$interval = date_diff($from, $to);
if( $interval->format("%a") % 7 == 0 ){
$amt = ($interval->format("%a") / 7);
if($amt == 1) {
$display = $amt . " Week";
} else {
if($amt >= 4) {
$amt2 = $interval->format("%m");
if($amt2 == 1) {
$display = $amt2 . " Month";
} else {
$display = $amt2 . " Months";
$amt3 = $interval->format("%y");
if($amt3 == 1) {
$display = $amt3 . " Year";
} else {
$display = $amt3 . " Years";
}
}
} else {
$display = $amt . " Weeks";
}
}
} else {
$display = ($interval->format("%a")) . " Days";
}
You'd just echo $display anywhere you needed the time difference.
I have used this in some earlier project. Hope this might help you.
function datediffInWeeks($date1, $date2)
{
if($date1 > $date2) return datediffInWeeks($date2, $date1);
$first = DateTime::createFromFormat('d/m/Y', $date1);
$second = DateTime::createFromFormat('d/m/Y', $date2);
return floor($first->diff($second)->days/7);
}
var_dump(datediffInWeeks('8/3/2015', '7/27/2015'));
First thing you need to do is convert the strings to something that is easy to work with. Unixtime is probably the easiest when you are doing comparisons. Unixtime is the number of seconds since the Unix Epoch (January 1, 1970). Here is what I would do:
$date_from = strtotime( '8/3/2015' ) // Change to your input
$date_to = strtotime( '07/27/2015' ) // Change to your input
$difference = $date_to - $date_from; // The seconds between these times
$seconds_in_minute = 60;
$seconds_in_hour = $seconds_in_minute * 60;
$seconds_in_day = $seconds_in_hour * 24;
$seconds_in_week = $seconds_in_day * 7;
$seconds_in_month = $seconds_in_day * 30;
$seconds_in_year = $seconds_in_day * 365;
Each of these variables store how many seconds are in the specific timeframe. What you can do is check agains these variables using some basic math.
$years = floor( $difference / $seconds_in_year );
$months = floor( ($difference - $years * $seconds_in_year ) / ( $seconds_in_month ) );
$days = floor( ( $difference - $years * $seconds_in_year - $months * $seconds_in_month ) / ( $seconds_in_day ) );
This is a long form example of what is happening in the date_diff() function in PHP. However, that function is only available post PHP 5.3, so if you are using an older version of PHP you can try this method.
As MrT stated, using date() functions you can achieve this easily:
$from = date_create("07/27/2015");
$to = date_create("08/03/2015");
$interval = date_diff($from, $to);
echo $interval->format("%a"); // %a will give difference in days
For more about formatting this take a look at date_diff()
Visit: http://php.net/manual/en/datetime.diff.php
$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');
There is an awesome PHP extension for this thing.Its called carbon.
Specifically, for your given task you can do the following(I am skipping the code of importing and stuff):
$dt = Carbon::create(2014, 1, 1);
$dt2 = Carbon::create(2014, 12, 31);
echo $dt->diffInWeeks($dt2);
The above function will give you your answer.
Also, you can use their createFromFormat() method to create carbon objects of date
Link:
http://carbon.nesbot.com/
The 'W' date format fetches the week of the year that the date falls in.
$from = date('W', strtotime('07/27/2015') ) ;
$to = date('W', strtotime('8/3/2015') ) ;
//$from and $to now have the week of the year that their dates fall in.
//This simple math produces the the number of weeks from one date to the next.
$numOfWeeks = $to - $from;
Okay, so, I have a list table with 2 columns: codes and dates.
I want to display the LATEST 25 AND tell the user how long ago they were submitted.
So, for example:
ABCDEF (1 Second Ago)
CCDEE (12 Seconds Ago)
329492 (45 Minutes Ago)
I've gotten this far:
$result = mysql_query("SELECT `code` FROM `fc` ORDER by datetime LIMIT 25") or die(mysql_error());
but, it doesn't do what I want. It does the reverse. It shows what was inputted FIRST, not LAST.
My output looks like this:
$output .= "<li>" . htmlspecialchars($fetch_array["code"]) . "</li>";
I have NO Idea how to add the (time since) part.
Help?
Thanks :)
Consider ORDER BY datetime DESC to sort in the other direction.
Consider adding datetime to the SELECT list, so you can access the posting date in PHP. You can then use PHP date/time functions to calculte the difference between the current date, and the date posted, to work out how long ago the posting was posted.
Added: a bit of code to calculate the time since the posting in a friendly format.
$seconds = time() - strtotime($fetch_array["datetime"]);
if($seconds < 60)
$interval = "$seconds seconds";
else
if($seconds < 3600)
$interval = floor($seconds / 60) . " minutes";
else
if($seconds < 86400)
$interval = floor($seconds / 3600) . " hours";
else
$interval = floor($seconds / 86400) . " days";
// You can keep on going
At the end $interval contains a textual representation of the interval
Try using
order by datetime desc
Then in PHP grab the current time, subtract the time returned from the query, and then take a look at this SO question about relative time to display your time in the proper units.
If I understand right the question the problem is that you don't specify the order of sort.
If you want to obtain the latest posts you have to specify the descendant order.
$result = mysql_query("SELECT code FROM fc ORDER by datetime DESC LIMIT 25") or die(mysql_error());
To fix the ordering:
"SELECT `code`, `datetime` FROM `fc` ORDER by datetime DESC LIMIT 25"
To get time diff, something like this should work. Note that you should refactor this into better methods, remove the "magic number" etc. (It can also be extended to be more sophisticated):
function getTimeAgo ($dateTime) {
$timestamp = new DateTime($dateTime);
$currentTimestamp = new DateTime();
$diff = $currentTimestamp->getTimestamp() - $timestamp->getTimestamp();
if($diff < 0) {
throw new Exception (__METHOD__ . ':parameter $dateTime can not be
in the future!');
}
if($diff < 60) {
return "$diff seconds ago";
}
if($diff < 3600) {
return $diff/60 . " minutes ago";
}
if($diff < 86400) {
return $diff/3600 . " hours ago";
}
}
Changing datetime order:
Try DESC or ASC at the end of your ORDER BY. This should do the trick:
SELECT code
FROM fc
ORDER BY datetime DESC
LIMIT 25
Time since:
Write or find a PHP function that converts MySQL datetime format to 'real English'. Here's a quick basic example:
<?php
// your code goes here
$timeStr = "2009-08-01 15:43:34";
$time = Sec2Time( time() - strtotime($timeStr) );
print_r($time);
// this converts mysql datetime into english
// borrowed from http://ckorp.net/sec2time.php
function Sec2Time($time){
if(is_numeric($time)){
$value = array(
"years" => 0, "days" => 0, "hours" => 0,
"minutes" => 0, "seconds" => 0,
);
if($time >= 31556926){
$value["years"] = floor($time/31556926);
$time = ($time%31556926);
}
if($time >= 86400){
$value["days"] = floor($time/86400);
$time = ($time%86400);
}
if($time >= 3600){
$value["hours"] = floor($time/3600);
$time = ($time%3600);
}
if($time >= 60){
$value["minutes"] = floor($time/60);
$time = ($time%60);
}
$value["seconds"] = floor($time);
return (array) $value;
}else{
return (bool) FALSE;
}
}
?>
And the output is:
Array ( [years] => 0 [days] => 4 [hours] => 5 [minutes] => 29 [seconds] => 38 )
Hope that helps
So, I have a field in my users table named last_active which updates every time a user reloads a page. It's stored in unix timestamp.
I would like to output it like this: Last online: 4 d 18 h 19 m ago
How would one do that? Can you do it with php's date()?
Thank you.
You could achieve this directly in MySQL if you like:
select date_format(from_unixtime(current_timestamp - last_timestamp),
'Last online: %e days, %k hours, %i minutes, %s seconds ago.');
(current_timestamp can be replaced with unix_timestamp(now()) if you want it calculated in-place)
DATE_FORMAT allows you to have a custom string based on a specific date. If you populate its date with the difference between two timestamps, it will work as you've asked.
The above solution will only work if it's under a month; if you want days of the year, use %j. The documentation for the function shows more.
The simplest approach to this is to take the last_active timestamp, and the current timestamp with time(). Then subtract the last active from the current timestamp, and then you simply divide the result with the amount of seconds in a day to get difference in days, amount of seconds in an hour to get difference in hours and so on.
This approach may be slightly inaccurate in some special cases (leap years, etc.) but it should suffice for your simpler usecase
After finding dozens of broken or half-there solutions, I built the following function for UNIX timestamps.
You can limit the detail level ...
echo timeDiff(1350297908); will show "5 minutes, 42 seconds ago".
echo timeDiff(1350297908, 1); will just show "5 minutes ago".
function timeDiff( $from, $levels=7 ){
$now = time();
$diff = ($from > $now) ? $from - $now : $now - $from;
$status = ($from > $now) ? ' away' : ' ago';
$times = array(31536000, 2628000, 604800, 86400, 3600, 60, 1);
$words = array('year', 'month', 'week', 'day', 'hour', 'minute', 'second');
$str = array();
foreach ($times as $k=>$v){
$val = floor($diff/$v);
if ($val) {
$str[] = $val .' '. $words[$k] . ($val==1 ? '' : 's');
$levels--;
}
$diff %= $v;
if ($levels==0) break;
}
return implode(', ', $str) . $status;
}
I wrote this simple function when I need this kind of solution (it gets minutes as input):
function minutes_to_time($minutes)
{
$obj = "";
// extract days
$days = floor($minutes/(1440)); # Divide on the daily minutes 60 min * 24 hours
# echo "Days: " . $days;
// extract hours
$hours = floor(($minutes-($days*1440))/60);
# echo " Hours: " . $hours;
// extract left minutes
$minutes = ($minutes-($days*24*60)-($hours*60));
# echo " Minutes: " . $minutes;
if ($days > 0)
{
$obj .= $days . "d ";
}
if ($hours > 0)
{
$obj .= $hours . "h ";
}
if ($minutes >= 0)
{
$obj .= $minutes . "m ";
}
$obj .= "ago";
return $obj;
}