In my project i need time intervals by 15 minutes in my database such as "06.00", "06:15"..
There is a time_id and time_interval column in my time table. I want to keep the time intervals as strings in my database and give everyone of them an id.
I wrote the query below:
mysql_query("INSERT INTO time(time_interval) VALUES('06:00'),('06:15'),('06:30') ...");
and i though there should be a easy way. I googled it a lot bu nothing seem to work. So how do i do this in a short way ?
You can use DateTime to get all times between 2 times:
$dt1 = new DateTime('06:00 UTC');
$dt2 = new DateTime('16:00 UTC');
$values = array();
while ($dt1 <= $dt2) {
$values[] = $dt1->format("('H:i')");
$dt1->modify('+15 minute');
}
And then you can use that array to build your query:
$sql = "INSERT INTO time(time_interval) VALUES " . implode(', ', $values);
print_r($sql);
Demo.
Related
I asked a question yesterday in adding together datetime intervals and was pointed to this thread - How we can add two date intervals in PHP
This is great and makes sense. However, when I try to do what the submitted answer says in a foreach loop, I'm ending up with an incorrect result.
This is a function I have made that gets all the clock in times and out times of staff, they are stored in the db and are created using PHP's date(H:i:s).
My function gets all the in and out times of any given employee, and my reporting feature I'm working on needs to display the total amount of hours they have worked.
I tried to achieve this by converting the times to datetime objects and using ->diff to get the intervals and thus calculating that days hours, I am then trying use a foreach loop to add the intervals together thus giving me a sum total of the hours worked in any given date range.
The whole function together is this:
function getTotalHours($staff_id,$from_date,$to_date){
$sql = "SELECT * FROM oc_staff_times WHERE date BETWEEN '$from_date' AND '$to_date' AND staff_id = '$staff_id'";
$result = $this->conn->query($sql);
if ($result->num_rows > 0) {
while ($row = mysqli_fetch_assoc($result)) {
$data[] = $row;
}
$base_time = new DateTime('00:00');
$total = new DateTime('00:00');
foreach ($data as $time) {
$in = new DateTime($time['clock_in_time']);
$out = new DateTime($time['clock_out_time']);
$interval = $in->diff($out);
$base_time->add($interval);
}
return $total->diff($base_time)->format("%H:%I");
}
}
I was hoping to get a monthly total, however it seems I'm only getting one days total as my final result. Here is a screen shot of the UI (the total hours are crudely circled) this also shows the time stamps my function should be adding together.
You can do this in a single query instead. Use TIMEDIFF() to get the difference for each row, then convert those to seconds by using TIME_TO_SEC(), SUM() those up and put it back into time-format with SEC_TO_TIME() - all in MySQL!
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(`clock_out_time`, `clock_in_time`))))
FROM `oc_staff_times`
WHERE `staff_id` = ?
AND `date` BETWEEN ? AND ?
Making your function with a prepared statement..
function getTotalHours($staff_id, $from_date, $to_date){
$sql = "SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(`clock_out_time`, `clock_in_time`))))
FROM `oc_staff_times`
WHERE `staff_id` = ?
AND `date` BETWEEN ? AND ?";
$stmt = $this->conn->prepare($sql);
$stmt->bind_param("sss", $staff_id, $from_date, $to_date);
$stmt->execute();
$stmt->bind_result($totalTime);
$stmt->fetch();
$stmt->close();
return $totalTime;
}
SQL fiddle showing the query in action http://sqlfiddle.com/#!9/525b83/7
The answer from Qirel offers a nice way to do this in SQL, however if you want to understand why your code didn't work:
$base_time = new DateTime('00:00'); does not create an interval, it's a date. It means that if you add 24 hours to it and ask only the time part, it will show '00:00' because you end up the day after.
One solution would have been to declare $base_time as an interval, for example like this:
$base_time = new DateInterval('PT0S');
And at the end output directly like this:
$base_time->format("%H:%I");
I need to search a row between 2 times in one day
for example
current time is 13.30 O'clock
The first time is 13.00 O'clock
The second time is 14.00 O'clock
If the current time is between the first time and the second time, return true, else return false
i make some code like this :
$today = date("Y-m-d");
$this->db->query("select date, in, out from absent where date='$today' and id_user='120'")->result();
/*
the result is 3 rows
2019-3-7, 13:00, 14:00
2019-3-7, 09.00, 12.00
2019-3-7, 15:00, 17:00
*/
I just need one row which the current time is between the first and second time
Like this (if you have a single date time field):
$firstTime = (new DateTime)->format('H:i:s');
$secondTime = (new DateTime)->modify('+1 hours +2 minutes +3 seconds')->format('H:i:s');
$this->db->query("SELECT `date`, in, out FROM absent WHERE TIME(`date`) >= '$firstTime' AND TIME(`date`) <= '$secondTime' AND id_user='120'");
Date is a reserved word in MySQL so you have to escape it. You can do this for any part of a datetime field, MONTH(), DAY(), YEAR(), TIME(), HOUR() etc..
Then you just match your date format in this case just the time H:i:s and a bit of logic.
It's not clear but you may need something like this as it looks like you have a date field and two fields with Hour and Minutes?
$today = new DateTime;
$date = $today->format('Y-m-d');
$in = $today->format('H:i');
$out = $today->modify('+2 hours')->format('H:i');
$this->db->query("SELECT `date`, in, out FROM absent WHERE `date` = '$date' AND in >= '$in' AND out <= '$out' AND id_user='120'");
Personally in this case I would make in and out be full datetime fields, then you can use the date functions like above, and you can eliminate one column, and handle in and out values that bridge a date.
You can use below code:
$this->db->select('date, in, out');
$this->db->from('absent');
$this->db->where('date', $today);
$this->db->where('user_id', '120');
$this->db->where('in >='. $currentTime);
$this->db->where('out <='. $currentTime);
return $this->db->get()->result_array();
Hope it helps you.
Try like this
First, convert all three times into strtotime()
Second, result() will always give you more than one row if it will retrieve. Use row() to get only one record
$current = strtotime('time-one');
$first_time = strtotime('time-two');
$second_time = strtotime('time-three');
$date = date('Y-m-d');
Query
$this->db->select('*');
$this->db->from('table');
$this->db->where('date', $date);
$this->db->where('user_id', '120');
$this->db->where('time >='. $first_time);
$this->db->where('time <='. $second_time);
return $this->db->get()->row();
I have been trying to figure this out for a week now. My wife has started a new taxi-company and she asked me to code a simple webpage for here where she could press a button to save a timestamp, then the press is again when she gets off work, it then creates a second timestamp
I have an MYSQL database with rows containing the start time and stop time. I have managed to use the diff function to see how much time it is between the two timestamps but now comes the tricky part.
Since it's different payments at different times of the day I need to divide the time at a shortened time.
Up to 19:00 she works "daytime" and after that, she works "nighttime" until 06:00 the other day, then there is "weekend daytime" and "weekend nighttime" as well.
So if she creates a timestamp whit the date and time: 2018-08-08 06:30 and then another timestamp at 2018-08-08 21:00, then I need a script that puts these data in ex "$daytimehours = 12" "$daytimeminutes = 30" and "$nighttimehours = 3" "$nighttimeminutes = 0"
I have managed to create a script that almost works, but it is several pages long, and it contains one if-statement for each different scenario daytime-nighttime, nighttime-daytime etc.
So do anyone has a good idea on how to solve this? or maybe just point me in the right direction. I would be happy to pay some money to get this to work.
My solution is
<?php
date_default_timezone_set('Asia/Almaty');
$endDate = '2018-08-08 21:00';
$startDate = '2018-08-08 06:30';
$nightmare = date('Y-m-d 19:00');
$startDay = date('Y-m-d 06:00');
$diffMorning = strtotime($nightmare) - strtotime($startDate);
$diffNight = strtotime($endDate) - strtotime($nightmare);
echo gmdate('H:i', $diffMorning) . "\n"; // this is the difference from start day till 19:00
echo gmdate('H:i', $diffNight); // this is the difference on nightmare
$total = $diffMorning + $diffNight;
echo intval($total/3600) . " hours \n";
echo $total%3600/60 . " minutes \n";
echo $total%3600%60 . ' seconds';
You can check via online compiler
given two dates stated as:
$endDate = '2018-08-08 21:00';
$startDate = '2018-08-08 06:30';
you can use the PHP Date extension to achieve the difference like this:
$start = date_create($startDate);
$end = date_create($endDate);
$boundnight = clone($end);
$boundnight->setTime(19,00);
$total_duration = date_diff($end,$start);//total duration from start to end
$day_duration = date_diff($boundnight,$start);//daytime duration
$night_duration = date_diff($end,$boundnight);// nighttime duration
you can use the format method to print a human readable string this way:
$total_duration=$total_duration->format('%H:%I');
$day_duration=$day_duration->format('%H:%I');
$night_duration=$night_duration->format('%H:%I');
At this step there is nothing left but you say you want to convert each duration in minutes.So let's build a function :
function toMinute($duration){
return (count($x=explode(':',$duration))==2?($x[0]*60+$x[1]):false);
}
Then you can use it this way:
$total_duration = toMinute($total_duration);
$day_duration = toMinute($day_duration);
$night_duration = toMinute($night_duration);
The output of
var_dump($total_duration,$day_duration,$night_duration) at this step is:
int(870)
int(750)
int(120)
I am building a script to display some 24 hour charts. I am attempting to make 12 charts. One 24 hour (last hour) chart for each five minute data set i have collected. I am running accross an issue where my mysql command will not update the $hour_position. I've read many while loop inside while loop questions and have tried to construct a foreach alternative, and also tried to reset the query array, but none of this has worked. Any comments or links to another thread that can solve this problem would be appreciated.
Thanks in advance.
$hour_position = 00;
$htime = -1;
$date = date('Y-m-d H:i:s');
$date = strtotime($date);
$date = strtotime($htime." day", $date);
$date = date('Y-m-d H:i:s',$date);
while($hour_position < 60){
$price_history_qry = mysqli_query($con,"SELECT * FROM `dbTable` WHERE `server_time` > '$date' AND EXTRACT(MINUTE FROM `server_time`) like $hour_position ORDER BY `server_time` ASC");
while($result = mysqli_fetch_array($price_history_qry)){
//Create a couple of arrays to build a chart.
}
//Build chart here
echo $chart;
$hour_position = $hour_position +05;
}
Try putting $hour_position in quote like
' $hour_position '
or you can use
". $hour_position ."
Your query has a small mistake. The variable inside single quotes will not be evaluated as variable. Check this. you need to change the select query like below.
$price_history_qry = mysqli_query($con,"SELECT * FROM `dbTable` WHERE `server_time` > '".$date."' AND EXTRACT(MINUTE FROM `server_time`) like ".$hour_position." ORDER BY `server_time` ASC");
And i haven't find any update query in your code. As you said you are using the update query inside while loop. So first check whether the variable has the value and then check whether it entering to while loop like below.
$result = mysqli_fetch_array($price_history_qry)
var_dump($result);
while($result){
//Create a couple of arrays to build a chart.
var_dump("entered");
}
Try to use var_dump() function to debug.
Hope it helps you.
this is my events script that pulls out appointments for the next 7 days, it appears to work ok, but only under one condition........The dates and times are held in the mysql db in datetime format so 2013-12-23 08:30:00 . My script prints out each day and finds appointments for that day for customers that are dropping off or picking up things. The mysql looks through the db and matches the customers with the dropping off or picking up fields to the date being printed and adds them in the div below the date.
The problem I am having is that if the time is set to anything other than 00:00:00 it doesn't pickup that customer for that day. How do I get the comparison to ignore the time and only use the date ?.
// Date box container
echo '<div class="dateboxcontainer">';
// Loop through and create a date for the next 7 days
$days = new DatePeriod(new DateTime, new DateInterval('P1D'), 7);
foreach ($days as $day) {
echo '<div class="datebox">';
echo '<div class="topdate">';
echo strtoupper($day->format('D d')) . PHP_EOL;
echo '</div>';
// Get the names for each day
$theday = strtoupper($day->format('Y-m-d'));
$sqldate = <<<SQL
SELECT *
FROM `jobdetails`
WHERE datedroppingoff = '$theday' OR datepickingup = '$theday'
SQL;
if(!$resultdate = $db->query($sqldate)){
die('There was an error running the query [' . $db->error . ']');
}
while($rowdate = $resultdate->fetch_assoc()){
echo $rowdate['name'];
}
//
echo '</div>';
}
echo '</div>';
//
What you are doing right now is comparing date/time values to just date values. This comparison would fail if the time part is anything other than midnight.
You can fix the comparison by using the DATE() MySql function to compare apples with apples:
WHERE DATE(datedroppingoff) = '$theday' OR DATE(datepickingup) = '$theday'
There are other ways to do the same, for example
WHERE DATEDIFF(datedroppingoff, '$theday') = 0 OR ...
If you had a $nextday value at hand you could also do
WHERE (datedroppingoff >= '$theday' AND datedroppingoff < '$nextday') OR ...
You are storing a specific time and day in mySQL, but only search for a date in your SQL query. As mySQL does not understand the difference between you wanting to search for a complete day or a specific point in time, mySQL assumes you are looking for the day at time 0:00:00.
You have a few options, you could search for a time period (pseudo code, check the borders yourself):
WHERE datedroppingoff > '$theday' AND datedroppingoff < '$theday'+1
another option is to store the date and time in separate db fields. That way you can keep your SQL queries simpler.
Good luck.