I've got the following function on my website:
function Active()
{
............
$num_rows = $db->doQuery('SELECT PremiumDays, PremiumStartTime FROM Premium WHERE AccountID = ?', $_SESSION['AccountID']);
if ($num_rows == -1)
{
$this->Error('ERROR');
$db->getError();
return;
}
$data = $db->doRead();
$data['Status'] = $num_rows == 0 ? '<:SHOW_PREMIUM_STATUS:>' : '<b><font size="2" color="red">Premium is active - <%Days_Remaining%> days remaining.</font></b>';
$replace = array
(
'account_status' => $data['Status'],
'days_remaining' => number_format($data['PremiumDays'])
);
$this->content = Template::Load('account-template', $replace);
}
PremiumDays column contains numbers like 10,15,30 etc.
PremiumStartTime contains a date in this format 2018-12-17 21:13:00
What I am trying to achieve is to show the actual days of premium remaining with days_remaining. So, I believe I need to substract from PremiumDays the days that passed since the premium started based on the second column PremiumStartTime.
Something like this:
days_remaining = PremiumDays - (NumberOfDaysSincePremiumStarted(DateToday - PremiumStartTime))
I will greatly appreciate if you can help me out with this. Thank you in advance!
Related
This is my function below:
function Active()
{
............
$num_rows = $db->doQuery('SELECT PremiumDays, PremiumStartTime FROM Premium WHERE AccountID = ?', $_SESSION['AccountID']);
if ($num_rows == -1)
{
$this->Error('ERROR');
$db->getError();
return;
}
$data = $db->doRead();
$data['Status'] = $num_rows == 0 ? '<:SHOW_PREMIUM_STATUS:>' : '<b><font size="2" color="red">Premium is active - <%Days_Remaining%> days remaining.</font></b>';
$replace = array
(
'account_status' => $data['Status'],
'days_remaining' => number_format($data['PremiumDays'])
);
$this->content = Template::Load('account-template', $replace);
}
PremiumDays column contains numbers like 10,15,30 etc.
PremiumStartTime contains a date in this format 2018-12-17 21:13:00
What I am trying to achieve is to show the actual days of premium remaining with days_remaining. So, I believe I need to substract from PremiumDays the days that passed since the premium started based on the second column PremiumStartTime.
Something like that I believe, however, I am not sure how to implement it correctly in PHP. Any help is greatly appreciated. Thank you in advance!
days_remaining = PremiumDays - (NumberOfDaysSincePremiumStarted(DateToday - PremiumStartTime))
To get the difference in PHP, you can create a DateInterval object using DateTime::diff between the current time (output of date_create()) and a DateTime object created from your PremiumStartTime variable. You can then access the days value of this object to get the total number of days from the PremiumStartTime to the current time. For example:
$data['PremiumStartTime'] = '2018-12-12 21:13:00';
$data['PremiumDays'] = 20;
$days_remaining = $data['PremiumDays'] - date_create($data['PremiumStartTime'])->diff(date_create())->days;
echo number_format($days_remaining);
Output:
13
Demo on 3v4l.org
Do it in the DB as follows:
//SQL Server
$num_rows = $db->doQuery('SELECT PremiumDays, PremiumStartTime,
(PremiumDays - datediff(day,PremiumStartTime,getdate())) DaysRemaining
FROM Premium WHERE AccountID = ?', $_SESSION['AccountID']);
//MySQL
$num_rows = $db->doQuery('SELECT PremiumDays, PremiumStartTime,
(PremiumDays - datediff(now(),PremiumStartTime)) DaysRemaining
FROM Premium WHERE AccountID = ?', $_SESSION['AccountID']);
Then:
$replace = array
(
'account_status' => $data['Status'],
'days_remaining' => $data['DaysRemaining']
);
Proof here: https://www.db-fiddle.com/f/xzuc89C9gQUHpdTTy9M4vf/0
Or if you really want to do it in PHP:
$replace = array
(
'account_status' => $data['Status'],
'days_remaining' => $data['PremiumDays'] - date_diff(date_create(), date_create($data['PremiumStartTime']))->days
);
I am trying to calculate price for number of days from 1-21 based on date.
HomeController
$Sql = ' SELECT DISTINCT
a.property_id, a.date, a.minimum_stay,
a.maximum_stay,a.quantity,
a.arrival_allowed,a.departure_allowed,
p.duration, p.persons, p.amount,
p.extra_person_price, p.minimum_stay AS price_minimum_stay,
p.maximum_stay AS price_maximum_stay, p.weekdays,
p.period_till, p.period_from,
datediff(p.period_till, p.period_from) AS number_of_days
FROM availabilities AS a
JOIN prices AS p
ON a.property_id=p.property_id
WHERE a.minimum_stay >0
AND a.maximum_stay < 22
AND a.date >= p.period_from
AND a.date <= p.period_till
';
$Stm = $this->getEntityManager()->getConnection()->prepare($Sql);
$Stm->execute();
return $Stm->fetchAll(PDOConnection::FETCH_ASSOC);
public function CalculatePrice($persons, $extra_person_price, $date, $amount, $duration, $period_till, $period_from)
{
//loop through persons
foreach ($persons as $person) {
//calculate price for persons
if ($person > 1) {
$amount += $person * $extra_person_price;
}
//array to link parameters with database fields
$tmp = array(
"date" => $date,
"person" => $person,
"price_person" => number_format($amount / 100, 2, '.', ',')
);
//loop through $tmp an add value from 2 to 21 to day an add this to $tmp array with calculated value
//$x=$number_of_days;
//$days = (strtotime($period_till) - strtotime($period_from)) / (60 * 60 * 24);
for ($x = 1; $x <= 21; ++$x) {
if ($x >1) {
$tmp["day$x"] = $tmp["day".($x-1)] + number_format($amount / 100, 2, '.', ',');
//number_format(($amount * $x) / 100, 2, '.', ',');
} else {
$tmp["day$x"] = "0.00";
}
$price_per_person[] = $tmp;
}
return $price_per_person;
}
I am also calculating price for number of persons but that part is good. Right now I have made a for loop and stored numbers from 1 to 21 for number of days see my second for loop in function CalculatePrice. But this part not good I need to calculate this based on date. for example:
Regularly price for most of days is 123 Euro. let say on 3 September a day cost 250 euro and on 7 September it cost 300 Euro. So let say A person want to stay for 5 days and he arrives at 3 September so the calculation will be: 250 + 123 + 123 + 123 + 300 = 919 Euro.
But I need this to be based on date. I have tried with period_from and period_til but so far no luck. Can someone give an example or some useful hints how I can do this in a for loop like my second for loop.
I have solved this question based on the theory T. Abdelmalek gave me. I made an array and stored date and price of each date in and loped through. The answer has been deleted somehow I don't know how to mark as solved
You can use date_diff like that:
First date = $leave->getLeaveFrom();
Second date = $leave->getLeaveTo();
$diff = date_diff($leave->getLeaveFrom(),$leave->getLeaveTo());
Results = var_dump($diff);
I have a varchar typed field which stores strings in this format HH:MM:SS i.e. 01:25:59 (and sometimes without HH part e.g. 25:59).
I want to have a descending order of results based on this time and for that I came with [str_to_date()][1] function and currently I'm using str_to_date($field_value,'%l:%i:%s') DESC to achieve this kind of sorting.
The odd thing is by using this format %l:%i:%s all posts having this field in MM:SS format are ordered correctly but those in HH:MM:SS aren't.
1-So if I have these values:
11:35
15:20
48:00
01:57:47
01:20:26
2-They are sorted as:
48:00
01:20:26
15:20
11:35
01:57:47
3-Which is wrong and should be:
01:57:47
01:20:26
48:00
15:20
11:35
As you see in (2) only times in format of HH:MM:SS are not placed correctly (DESC)
How can I have the right sorting?
What about this?
SELECT * FROM tbl
ORDER BY TIME_TO_SEC(IF(LENGTH(str_time)<6,CONCAT("00:",str_time),str_time)) DESC
fiddle demo: http://sqlfiddle.com/#!9/4b5da/3
This is your query:
SELECT IF(LENGTH( columnName ) >5, STR_TO_DATE(columnName, '%h:%i:%s'), STR_TO_DATE(columnName, '%i:%s')) as modDate
FROM `tableName` WHERE 1 order by modDate desc
SQL Fiddle: http://sqlfiddle.com/#!9/b6a52/1
wanna do something at application side ??? bit lengthy, but it works.
$tim_arr = array ('11:35', '15:20', '48:00', '01:57:47', '01:20:26');
$new_arr = array();
foreach ($tim_arr AS $tim){
$tim_chk = $key = '' ; $ntim_arr =array();
$tim_chk = substr_count($tim, ":");
$ntim_arr = explode(':',$tim);
if($tim_chk == 2){
$ntim = ( (int)$ntim_arr[0]*60 + (int)$ntim_arr[1] ).':'.$ntim_arr[2];
$key = ( (int)$ntim_arr[0]*60 + (int)$ntim_arr[1] );
}
else{
$ntim = $tim;
$key = $ntim_arr[0];
}
$new_arr[$key] = $ntim ;
}
krsort($new_arr);
foreach ($new_arr AS $tim)
{
$ntim_arr = explode(':',$tim);
if((int)$ntim_arr[0] >= 60){
echo str_pad(floor($ntim_arr[0] /60),2,"0",STR_PAD_LEFT).":".
str_pad($ntim_arr[0] %60,2,"0",STR_PAD_LEFT).":".$ntim_arr[1]."<br/>";
}
else{
echo $tim."<br/>";
}
}
UPDATE
I edited my code, so now the time is checked correctly:
while($row = mysqli_fetch_array($result)){
$rid = $row['roomid'];
$begin = $row['start'];
$bval = strtotime($begin);
$einde = $row['end'];
$eval = strtotime($einde);
$staco = strtotime($start); //starttime posted from form
$endco = strtotime($end); //stoptime posted from form
$abegin = array(sta => $bval);
$aeinde = array(sto => $eval);
// print_r($abegin);
// print_r($aeinde);
foreach($aeinde as $sto) {
if($staco <= $sto) {$checksto = 1;}
else {$checksto = 0;}
}
foreach($abegin as $sta) {
if($endco <= $sta) {$checksta = 1;}
else {$checksta = 0;}
}
if($checksta == $checksto) {$ok = 1;} else {$ok = 0;}
print_r($ok);
}
}
}
So now: how do I check if $ok contains one or more 0's (don't book the room) or all 1's (book the room).
$roomstate = array(state => $ok) results in more than one array:
Array ( [state] => 0 ) Array ( [state] => 1 ) Array ( [state] => 1 )
I'm doing something wrong, because I think it should be possible to get all the different $ok's in one array and then
if(in_array(0,$roomstate)) { echo "Do not book";} else {$bookitsql = "INSERT INTO reservations ...";}
UPDATE: There is a flaw in my original logic to check availabilty with the rooms that needs to be solved first: now the rooms are not checked correct, so it is impossible to answer this question since the correct data is not displayed. My apologies.
For a system that books rooms I need to check with a new booking if the room is already is booked at the moment. The booking works with a form, and then it compares the results from the form with the content in the database for that room on that date.
while($row = mysqli_fetch_array($result)){
$rid = $row['roomid'];
$begin = $row['start'];
$bval = strtotime($begin);
$staco = strtotime($start);
$einde = $row['end'];
$eval = strtotime($einde);
$endco = strtotime($end);
$abegin = array(sta => $bval);
$aeinde = array(sto => $eval);
foreach($abegin as $sta) {
if($staco $checksta,checkstop => $checksto);
print_r($meh);
}
BetterQuestion:
Now I get `$staco` and `$endco`, which are the start and stoptime from the form.
I also get `$sta` and `$sto`, which are multiple start and stoptimes from the database.
Example:
existing reservations:
sta sto
1: 0800 0959
2: 1130 1259
So now when I get `$staco = 1000` and `$endco = 1114` it doesn't check right.
It only works if the new reservation is later than all the other reservations in the database. How can I solve this?
Your Target Pseudocode shows that you want it all be 0. $meh is an Array.
So what you do now is using a foreach on $meh and then Mark it as Occupied as soon as 1 appears. if this doesnt happen, you can assume that $meh is free, and do you Booking.
$roomState = 0;
foreach($meh as $mehValue){
if($mehValue == 1){
$roomState = 1;
}
}
if($roomState == 1){
print_r("room is occupied");
} else {
//insert stuff
}
Took a different approach, by checking date in my sql-statement.
So, the form posts $start and $end (when the users wants to make a reservation).
Now my code looks like this (and it looks ok, I think):
//form and other errormessages like username==0; $start>$end etcetera
else {
$reservationsql = "SELECT * FROM reservations WHERE roomid = '$roomid' AND ('$start' between start AND end) OR ('$end' between start AND end) OR ('$start' >= start AND '$end' <= end) OR ('$start' <= start AND '$end' >= end)";
$result = mysqli_query($link,$reservationsql) or die(mysql_error());
$num = mysqli_num_rows($result);
if($num>0) {"Error: room already booked at that moment";}
else {//$query = "INSERT INTO ..."}
}
}mysqli_close();
Thanks for all the help here and to think along with me.
The snippet below print out a query that fetches users from a DB who's DOB are in a certain age range. In this case, users that are either between 11 and 12 or 17 and 18 years old. I'm trying to dynamically create this query in CodeIgniter Active Record syntax.
This snippet
$age_count = 0;
foreach( $range as $r )
{
$start_date = strtotime($r[0] . "years ago");
$stop_date = strtotime($r[1] . "years ago");
$range = array('dob <' => $start_date, 'dob >' => $stop_date);
( $age_count == "0" || $age_count%1 ) ? $this->db->where($range) : $this->db->or_where($range);
$age_count++;
}
$users = $this->db->get("users")->result_array();
produces this query
SELECT * FROM (`users`) WHERE `dob` < 956351611 AND `dob` > 924729211 OR `dob` < 766962811 OR `dob` > 735426811
The last OR should of course be AND. How can I achieve this? It comes down to knowing when to use or_where() or simply where(). I thought every odd pass through the foreach should be an OR but I'm not quite there yet.
This function might just receive one range (11-12) or several ones.
With the database API, you can use multiple where() to get a WHERE … AND ….
$this->db->where('name', $name);
$this->db->where('title', $title);
$this->db->where('status', $status);
// WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
(tied from the documentation)