I have a table containing the following:
StartWeek | StartName |
2012-07-16 | 1 |
What I want to do. Is take the starting week, the current date, and calculate how much time has passed between then and now.
So far I have this:
function getCurrentWeekName() {
$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME);
if (!$mysqli) {
die('There was a problem connecting to the database.');
}
else {
date_default_timezone_set('UTC');
echo "Current date: ".$current_date = date('Y-m-j')."<br>";
$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME);
$query = $mysqli->prepare("SELECT StartWeek FROM Week");
$query->execute();
$query->bind_result($start_date);
while ($query->fetch()){
$start_date = $start_date;
}
echo "start date: ".$start_date."<br>";
echo "time passed: ".$time_passed = strtotime($current_date) - strtotime($start_date)."<br>";
echo "number of days since start: ".$num_of_days = ceil($time_passed/(86400*7))."<br>";
$week_num = ceil($num_of_days/7);
$query = $mysqli->prepare("SELECT StartName FROM Week");
$query->execute();
$query->bind_result($start_name);
while ($query->fetch()){
echo "Start name: ".$start_name = $start_name."<br>";
}
$week_num = $start_name + $week_num;
echo "Week Number: ".$week_num;
}
$mysqli->close();
}
The problem is, this returns the following information:
Current date: 2013-03-18
start date: 2012-07-16
time passed: -1342394787
number of days since start: -2219
Start name: 1
Week Number: -316
So clearly I'm doing it wrong. I think it must be something to do with my time passed calculation, maybe I shouldn't be using strtotime. Can anybody help?
If you're looking for just a difference in days, you can do it directly in MySQL:
SELECT DATEDIFF(now(), StartDate) AS diff_in_days
for other differences, e.g. hours, you can also do things like
SELECT unix_timestamp(now()) - unix_timestamp(start_date) AS seconds
you can do this with php date-diff => http://php.net/manual/en/function.date-diff.php
Check if this you can use:
//replace the values for $startDate and $endDate:
$startDate = strtotime($startDate);
$endDate = strtotime($endDate);
$intervalo = date_diff(date_create($startDate), date_create($endDate));
$out = $intervalo->format("Years:%Y,Months:%M,Days:%d,Hours:%H,Minutes:%i,Seconds:%s");
if(!$out_in_array)
return $out;
$a_out = array();
array_walk(explode(',',$out),
function($val,$key) use(&$a_out){
$v=explode(':',$val);
$a_out[$v[0]] = $v[1];
});
print_r($a_out);
Related
I wonder if its possible to use my $today in WHERE query.
If $today is Monday, i want my WHERE to be p650Wdat = 1 (1 stands for monday)
And and tuesday will be 2 and so on.
$today = date("l");
<?php
$today = date("l");
//Establish connection to database
$host = "randomtext";
$conn = myacc");
$query = " Select *
from P660F
where p660WDAT = $today
ORDER BY P660PRIO DESC";
?>
OK so you want to match Monday to 1 and Tuesday to 2 etc. Really you should have same values in table as variables for simplicity and clarity butyou can return the day name as an integer like so
<?php
$day_name = date("l");
$today = date('N', strtotime($day_name));
echo 'Today name is ' . $day_name .'<br>';
echo 'Today number is ' . $today;
?>
Then your query should work
Use this in the where clause:
SQL:
WHERE DATENAME(dw, p660WDAT) = $today
MySQL:
WHERE DAYNAME(p660WDAT)= $today
And your function Date(l) will also return day name as Sunday, Monday... instead of 1,2,3...
Depends on your RDBMS you can use different ways:
MySQL:
WHERE WEEKDAY(p660WDAT)+1 = $today;
PostgreSQL:
WHERE EXTRACT(DOW FROM TIMESTAMP p660WDAT) = $today;
P.S. Of course, you should think about escaping values and etc. I didn't mention to give cleaner answer.
P.P.S. If I understood you properly, just use date('w') to get day of week.
<?php
$day_name = date("l");
$today = date('N', strtotime($day_name));
echo 'Today name is ' . $day_name .'<br>';
echo 'Today number is ' . $today;
$today = date("l");
//Establish connection to database
$host = "randomtext";
$conn = myacc");
$query = " Select *
from P660F
where p660WDAT = $today
ORDER BY P660PRIO DESC";
?>
My database data are table of dates. I want to create a list to report entries of expired dates.
for that, I used the following php script:
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT Batch#, Date1, Date2 FROM users";
$result = $conn->query($sql);
$now= strtotime("-1 Months");
if ($result->num_rows > 0) {
$Date1= $row["Date1"];
$Date2= $row["Date2"];
echo "<table id='t1'><tr><th>Alert</th><th>Action</th></tr>";
// output data of each row
while($row = $result->fetch_assoc()) {
if($Date1 >= $now)
echo "<tr><td>One month or less to expiry date of product with batch# " . $row["Batch#"]. "</td><td>Please take an action</td></tr>";
}
echo "</table>";
} else {
echo "0 results";
}
$conn->close();
?>
I kept getting an error: "Notice: Trying to get property of non-object in C:\xampp\htdocs\Testing\AlertTest.php on line 17
0 results"
I couldn't figure out what that means or how to fix it. I've been this method before and this is the first time I get such an error.
As you are comparing the dates, you have to mind that the both dates are in same format (Date string or time stamp). For comparison both the format as timestamp is best. So using the PHP function timestamp() just convert your database time to a unique number.
Your comparison:
if($Date1 >= $now){
....
}
Here The $Date1 is a string like '2016-07-07' and the $now something like '1468057029', so the condition not goes correct / success. What you have to do is just convert both time into timestamp and execute the comparison.
$Date1 = strtotime($row["Date1"]);
$Date2 = strtotime($row["Date2"]);
Hope this helped you.
I'm working on a PHP page that calculates the percentage of completion of a project. For example, if you had a start date of January 1st, 2015, and an end date of March 3rd, 2015, and today was February 2nd, 2015, the project would be estimated to be about 50% done. So far I've attempted using the DateTime class and the date_diff function, but I couldn't divide the two, so I'm back at square one. Obviously I need to take Daylight Saving and leap years into account, so that adds an additional layer of complexity to the matter. Any ideas? Here the current block.
try {
$dbh = new PDO('mysql:host=localhost; dbname=jkaufman_hartmanbaldwin', $username, $password, array(
PDO::MYSQL_ATTR_SSL_KEY => '../php_include/codekaufman_com.key',
PDO::MYSQL_ATTR_SSL_CERT => '../php_include/codekaufman_com.crt',
PDO::MYSQL_ATTR_SSL_CA => '../php_include/codekaufman_com.ca_bundle'
));
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$projectName = $_GET['project'];
$sth = $dbh->prepare('SELECT start, end FROM projects WHERE name = ?');
$sth->execute([$projectName]);
if($sth->rowCount()) {
$row = $sth->fetchAll(PDO::FETCH_ASSOC);
date_default_timezone_set('America/Los_Angeles');
$date = strtotime($row[0]['start']);
$start = date('m/d/Y', $date);
echo $start;
$date = strtotime($row[0]['end']);
$end = date('m/d/Y', $date);
echo " " . $end;
$today = date('m/d/y');
echo $end - $start;
}
} catch(PDOException $e) {
echo $e->getMessage();
}
With reference to How to Minus two dates in php:
$start = new DateTime($row[0]['start']);
$end = new DateTime($row[0]['end']);
$today = new DateTime();
$total = $start->diff($end);
$current = $start->diff($today);
$completion = $current->days / $total->days;
MySQL has some pretty easy to use functions for this sort of thing, you can just gather the info you need in your query:
SELECT start, end, DATEDIFF(end, start) as total_days, DATEDIFF(end, NOW()) as days_remaining
FROM projects WHERE name = ?
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_datediff
From there you just need to divide days_remaining by total_days to get the percentage. Datediff should take leap years and DST into account.
You can use TIMEDIFF in place of DATEDIFF if you need to be more precise, just make sure to convert the sql timestamps to integers with strtotime.
You may also need to set the timezone:
SET time_zone = 'America/Los_Angeles';
The formula is:
percentage = (date - start) / (end - start) * 100
As a PHP function:
function date_progress($start, $end, $date = null) {
$date = $date ?: time();
return (($date - $start) / ($end - $start)) * 100;
}
Example:
$start = strtotime("January 1st 2015");
$end = strtotime("March 3rd 2015");
$date = strtotime("February 2nd 2015");
$percent = date_progress($start, $end, $date);
// "You are 52.46% there!"
echo 'You are ', round($percent, 2), '% there!';
Get your SQL output in the right format (YYYY-MM-DD) and then shove it into the code below:
<?php
$startDate = date_create('2015-01-01');
$endDate = date_create('2015-01-30');
$currentDate = date_create('2015-01-08');
$totalTime = date_diff($endDate, $startDate);
$elapsedTime = date_diff($currentDate, $startDate);
$totalTimeDays = $totalTime->format("%d");
$elapsedTimeDays = $elapsedTime->format("%d");
echo "Total project time = " . $totalTimeDays . "<br/>";
echo "Elapsed project time = " . $elapsedTimeDays . "<br/>";
echo "Percent of project complete = " . ($elapsedTimeDays / $totalTimeDays) * 100.0;
?>
$start = new DateTime("<YOUR START DATE>"); // example input "2014/06/30"
$end= new DateTime("<YOUR END DATE>");
$now = new DateTime();
$intervalOBJ = $start->diff($end);
$totalDaysOfProject = $intervalOBJ->format('%a');
$intervalOBJ_2 = $now->diff($end);
$daysRemaining = $intervalOBJ_2->format('%a');
$completedPercentage = round(($daysRemaining/$totalDaysOfProject)*100);
echo $completedPercentage . "% of this project has been completed!";
Description: This calculates the percentage of days remaining. interval = $start to $end. Calculated percentage is in relation to $now.
So in my database i've got regdate (date type), but no matter what date it is, the code keeps returning 1.
<?php
$con = mysqli_connect("localhost","root","","login");
if (mysqli_connect_error()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM users");
$row = $result->fetch_array();
$date1 = new DateTime($row['regdate']);
$date2 = new DateTime("now");
$interval = $date1->diff($date2);
echo "It has been " .$interval->d." days ";
//$interval is supposed to be difference between regdate and todays date
I hope I'm not missing something stupid. Thank you for your anwers.
SOLVED
I belive this might be more easier.
SELECT DATEDIFF(NOW(),$row['regdate']);
and I think you need a while loop to find all the records.
This comes from my previous question on getting the average time interval over a specified data set, [located here][1]. I'll post the entire function again:
function getATBData($siteID, $fromDate, $toDate)
{
global $pdo;
$ATBarray = array();
$maxATB;
$minATB;
$avgATB;
$totalATB=new DateTime("#0");
$totalEvents=0;
$timetable;
$query = "SELECT id, siteID, start_time, end_time FROM atb_log WHERE siteID=:siteID AND (start_time BETWEEN :fromDate AND :toDate) AND (end_time BETWEEN :fromDate AND :toDate)";
$stmt = $pdo->prepare($query);
$stmt->bindParam(":siteID", $siteID);
$stmt->bindParam(":fromDate", $fromDate);
$stmt->bindParam(":toDate", $toDate);
$stmt->execute();
foreach ($stmt as $row)
{
$timeDiff = date_diff(new DateTime($row['start_time']),new DateTime($row['end_time']), true); //force absolute
if(!isset($maxATB) OR dateIntervalInSeconds($timeDiff) > dateIntervalInSeconds($maxATB))
$maxATB = $timeDiff;
if(!isset($minATB) OR dateIntervalInSeconds($timeDiff) < dateIntervalInSeconds($minATB))
$minATB = $timeDiff;
$totalATB->add($timeDiff);
echo "added " . $timeDiff->format("%H:%I:%S") . " total is now: " . $totalATB->format("H:i:s") . "<br />";
$totalEvents++;
}
if($totalEvents!=0)
{
$avgATB = average_time($totalATB->format("H:i:s"),$totalEvents,0);
}
else
{
$avgATB=0;
$maxATB=new DateInterval('PT0S');
$minATB=new DateInterval('PT0S');
}
//$avgSeconds = new DateInterval("PT" . $avgATB . "S");
$ATBarray['max'] = $maxATB->format("%H:%I:%S");
$ATBarray['min'] = $minATB->format("%H:%I:%S");
$ATBarray['avg'] = $avgATB;
$ATBarray['total'] = $totalATB->format("H:i:s");
$ATBarray['events'] = $totalEvents;
return $ATBarray;
}
Given this function, I have added an output statement to try to debug why I was getting such a large time interval for my total time (when most of the values are a small number of seconds) and this is what it's outputting:
added 00:00:02 total is now: 01:00:02
added 00:00:00 total is now: 02:00:02
added 00:00:01 total is now: 03:00:03
added 00:00:01 total is now: 04:00:04
added 00:00:00 total is now: 05:00:04
added 00:00:02 total is now: 06:00:06
added 00:00:00 total is now: 07:00:06
and so on. So it seems like, despite the time to be added only being a couple seconds, it adds an hour every time. The call to add() on $timeDiff above is how I'm adding.
So the question is - is there a different way to call the add() function such that it will only add the seconds? Am I calling it incorrectly?
Hm, average difference in seconds, why that PHP swath of code if your database can give it to you:
SELECT
SEC_TO_TIME(MAX(TIME_TO_SEC(TIMEDIFF(end_time,start_time)))) AS max_timediff,
SEC_TO_TIME(MIN(TIME_TO_SEC(TIMEDIFF(end_time,start_time)))) AS min_timediff,
SEC_TO_TIME(AVG(TIME_TO_SEC(TIMEDIFF(end_time,start_time)))) AS avg_timediff,
SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(end_time,start_time)))) AS sum_timediff,
COUNT(id) as total_events
FROM atb_log
WHERE
siteID=:siteID
AND start_time > :fromDate
AND end_time < :toDate
Format those min/max/avg/sum of seconds as you like.
As I wrote in the answer to your other question, this is a DST (Daylight Savings Time) problem. In the U.S., DST has already begun; in Europe not.
Try this code:
timecheck("Europe/Amsterdam");
timecheck("America/Los_Angeles");
function timecheck($timezone) {
date_default_timezone_set($timezone);
$totalATB=new DateTime("#0");
$t1 = "2014-01-01 17:30:00";
$t2 = "2014-01-01 17:35:00";
$dt1 = new DateTime($t1);
$dt2 = new DateTime($t2);
$timeDiff = date_diff($dt1, $dt2, true);
printf("[%s] Starting with with: %s\n", $timezone, $totalATB->format("H:i:s"));
$totalATB->add($timeDiff);
printf("[%s] added %s, total is now: %s\n", $timezone, $timeDiff->format("%H:%I:%S"), $totalATB->format("H:i:s"));
}
The output:
[Europe/Amsterdam] Starting with with: 00:00:00
[Europe/Amsterdam] added 00:05:00, total is now: 00:05:00
[America/Los_Angeles] Starting with with: 00:00:00
[America/Los_Angeles] added 00:05:00, total is now: 01:05:00