Get random number from array every 24 hours - php

I would like to know if it would be possible to retrieve a value from an array and use that value for the entire day without changing the value on refresh, it will be used for a discount section. So everyday one of the random values will be taken and that value will be applied as discount % for the next 24 hours. Tomorrow (24 hours later) it will take another value and use that value for the next 24 hours.
I created a logical statement below but isn't working. Any help will be gladly appreciated to complete below function.
//TIME VALUES
date_default_timezone_set('Asia/Dubai');
$currentTime = date('H:i');
$dayStartTime = '00:01';
$dayEndTime = '23:59';
if($currentTime >= $dayStartTime && $currentTime <= $dayEndTime) {
$items = Array("10","15","20");
echo $items[array_rand($items)];
}
Thank you for you time.
Dane

I think you'll want to store a discount somewhere. This will at minimum have 2 fields: amount and expiry.
On load, check if there's a valid discount:
SELECT * FROM discounts WHERE expiry > NOW() LIMIT 1;
If a result is returned, use it. If not, create a new discount with an expiry of 24 hours and use that.

Related

Building future date array

I am building an interactive web form where after user logs in, they can choose to pay toward their account...either every (n)th day of the month OR every 'n' number of days - and they will choose how many payments they'd like to do
They will use datepicker to choose their starting date (which can never be sooner than tomorrow)
I want to pass these parameters to a php script and then render a page that says they have agreed to make x number of payments on the following dates....
I'm having a problem getting the math right that I pass to this script.
i.e. if they choose to make 6 payments every 14 days starting on 6/25/2017 for example....how do I put this in an array and have the resulting page say: you've agreed to pay x amount on:
06/25/2017
07/09/2017
07/23/2017
08/06/2017
08/20/2017
09/03/2017
etc
They can choose a minimum of 1 payment date or up to a max of 12 payment dates. Can someone steer me in the right direction on building the array?
You should add x days to your inicial date, one way is:
$next = date("Y-m-d", strtotime('+ 14 days', strtotime($initialdate)));
Give this a shot...
<?php
// the date the user selected
$selectedPaymentDate = strtotime('2017-06-24');
// the frequency a user will pay
$freqNum = 14;
$freqType = 'days'; // days, months, years, whatever `strtotime` will handle
// the total number of payments a user must make
$totalPayments = 6;
// where we'll keep the dates
$paymentDates = [];
// build the dates array
for($i = 0; $i <= $totalPayments; $i++){
$next = ($freqNum * $i);
$paymentDates[]= date('Y-m-d', strtotime("+{$next} {$freqType}", $selectedPaymentDate));
}

Change date after 6 hrs in php variable

I need to change the shiftdate variable after 05:30 AM. Since i need to generate data from past 24 hrs starting 05:31 AM to Next day 05:30 AM. I tried like this, but its giving previous day every time. Please help.
I want $shiftdate to use in my sql query;
Code:
<?php
if(date('H:i')>="00:00" || date('H:i')<"05:30"){
$shiftdate= date('Y-m-d',strtotime(date('Y-m-d'))-24*60*60);
}
else if(date('H:i')>"05:30" || date('H:i')<"00:00")
{
$shiftdate=date('Y-m-d');
}
echo $shiftdate;
?>
You can't just compare string like "05:30" as a number and hope for the best. You need to compare numerical value of the hour and then numerical value of the minute.
You have a race in between the first if and the else if
Also the else if doesn't cover it completely, so if it hit's the sweetspot, you can end up with $shiftdate being NULL.
Make it a function with protoype shiftdate_type_whatever_it_is fn_name(int hour, int minute);. This way you can simply unit test the function for different (think boundary) values of the date("H:i");
You can use the DateTime classes for this and encapsulate your check into a function:-
/**
* #param DateTime $checkTime
* #return string
*/
function getShiftDate(DateTime $checkTime)
{
$shiftDate = (new DateTime())->setTimestamp($checkTime->getTimestamp());
$hours = (int)$checkTime->format('H');
$minutes = (int)$checkTime->format('i');
$totalMins = $hours * 60 + $minutes;
if($totalMins < 330){
$shiftDate->modify('yesterday');
}
return $shiftDate->format('Y-m-d');
}
var_dump(getShiftDate(new DateTime()));
Obviously the input to the function may need to be modified as I don't know how you get your date/time, but that won't be a problem. Post a comment if you need help with that.

Calculating Total Overtime Working Hours using Condition

Need your help with my case.
How to make calculating total overtime working hours using condition ?
Example :
using input type,
OT From <input type="text" name="ot_from">
OT To <input type="text" name="ot_to">
Total Hours <input type="text" name="total_hours">
Working days : from 08.00 - 17.00 (normal working days)
If I working until 19.00, should be calculate that I do overtime for 2 hours.
In my rules, from 18.00 - 18.30 not calculate overtime because that's a break time.
So should be my total Overtime hours is 1.5 not 2 hours.
Someone can give me a solution ?
Appreciate your help.
Thank you.
David
Here is what you should do:
1 Split the hours and minutes into a total amount of minutes.
str = "1:23" or other time value
time = parseInt(str.split(":")[0], 10)*60+parseInt(str.split(":")[1], 10)
2 Subtract the finish time from the start time - this will give you the final time.
3 To convert from minutes to hours do the following:
minutes = time%60
hours = parseInt(time/60, 10)
You don't actually need PHP - this can all be done with Javascript, as long as you are not looking to store the data in a database or anything.
If you want to make sure the input of the user is always equal, you should replace the input fields with Select boxes. Then you can make one Select box for the hours and one for the minutes.
To calculate the working hours, you can do a basic calculation like this:
<?php
// Vars of the POST form
$otfrom_hours = $_POST['ot_from_hours'];
$otfrom_minutes = $_POST['ot_from_minutes'];
$otto_hours = $_POST['ot_to_hours'];
$otto_minutes = $_POST['ot_to_minutes'];
// Make a full string for strtotime
$otfrom_string = $otfrom_hours.":".$otfrom_minutes;
$otto_string = $otto_hours.":".$otto_minutes;
// Basic calculation
$start = strtotime($otfrom_string);
$end = strtotime($otto_string);
$elapsed = $end - $start;
echo date("H:i", $elapsed);
?>
Hope it will be usefull!

Working out which data point to increment PHP

I have created an array with 10 timestamps each 1 day apart:
$data_points = array();
$now = time();
$one_day = 60 * 60 * 24;
for($i = 1; $i <= 10; ++$i) {
$key = $now - ($one_day * $i);
$data_points[$key] = 0;
}
print_r($data_points);
Array
(
[1328642414] => 0
[1328556014] => 0
[1328469614] => 0
[1328383214] => 0
[1328296814] => 0
[1328210414] => 0
[1328124014] => 0
[1328037614] => 0
[1327951214] => 0
[1327864814] => 0
)
Now I have a array of tasks that have started at various times in the last 10 days, I want to see which day my task fell into.
I was going to loop through each $data_point and see if the start time is greater than the current day and less than the next, then increment that data point
is there a better way to do this?
Thanks
Well, to reduce your search time you could put your data into a binary search tree rather than a simple array.
Whether or not that's worth the trouble depends on how big your data set is. Of course, you'd also have to re-balance your tree every so often as you add new dates.
I think there's a better method.
Assuming you have task starting timestamps in an array, the algorithm will be something like :
for each task starting timestamp
timestamp <- $now - timestamp // you will obtain task age in seconds
timestamp <- timestamp / (60*60*24) // you will obtain task age in days
// round resulting timestamp with a precision of 0 if you want to obtain the task age in integer days.
end for each
In this way you will loop on only one array. This will be less expensive than your method.
Obviously, if your tasks come from a SQL database, there will be a greater solution in SQL.
You can use DateTime class
$now = new DateTime();
$task = new DateTime('2012-02-20');
$interval = $taks->diff($now);
echo 'Here is the position you need:' . $interval->format('%R%a days');
** Updated to avoid use of DateTime as asked in comment **
$now = date('Ymd');
$task = date('Ymd',$tasktime);
$interval = $task - $now;
The interval is the number you expect.
I know this question is old, but since there are no accepted answers, and it seems like a fun question to answer - here we go!
Based on your question, your algorithm has the Big O of O(10n) where n is the number of tasks. This means, that it is fairly efficient compared to a lot of things. As pointed out, a binary search tree would be faster having O(log(n)), however implementing it wouldn't really be worth the saved time during processing. Though, you can make it slightly more efficient and have a resulting O(n) by using something like:
$now = time();
$oneDay = 86400; //60 * 60 * 24
foreach($tasks as $task) {
//assuming now that $task is the timestamp of the task
//extra paranthesis added for easier reading
$dif = $now - ($oneDay * ceil(($now - $task) / $oneDay));
$data_points[$dif]++;
}
The math in the diff is as follows. $now-$task is the difference between the two timestamps in seconds, we divide by $oneDay to get the number of days in the past the task occurred. Now, assuming that $now is the start of a new day, and if an event happened just 12 hours ago it was 'yesterday', we use ceil to round it to the next integer so '.5' becomes '1'. From there, we multiply by $oneDay to get the number of seconds of the days that have passed - to work with the $data_points array that you previously created. We then take that result and subtract it from $now, again to work with your $data_points array. That result gives us a time stamp that we can use that matches those in the array you created, and we use it as the 'key' for it and increment accordingly.
This will prevent you from having to loop through the entire $data_points array for each task, and thus reducing its complexity from O(10n) to O(n).
Anyways, I hope that answer helps explain why your formula isn't that inefficient, but shows how to make it ever so slightly more efficient.

Insert weekly info from date and time php

I have a function that is accepting the date and time, and number of occurrences of an episode. I'm using a while loop to try and insert and episode every week on the same day and time. For example if the episode is monday at 7PM, i want to insert in for every monday at 7PM for the number of occurrences given.
Here's my code and while loop:
$sEpsAirDate = strtotime($aVars['air_date'].' '.$aVars['air_time'].$aVars['air_ampm']);
$i = 1;
while ($i <= $aVars['repeat_count']) {
$sEpsAirDate = // How can I alter this variable to change the date to every week?
db_res(
"INSERT INTO `hm_episodes_main` SET
`show_id` = '{$aVars['show_id']}',
`title` = '{$sEpsTitle}.{$i}',
`season` = '{$aVars['eps_season']}',
`uri` = '{$sUri}.{$i}',
`desc` = '{$sEpsDesc}',
`air_date` = '{$sEpsAirDate}'
");
$i++
}
How would I alter the $sEpsAirDate variable to be entered accurately on every day of the week on the given time?
Use mktime():
$next_ep_timestamp = mktime ($hour,$min,$sec, $first_ep_month, $first_ep_day + 7 * $weekcount, $first_ep_year);
"Init" this by setting the respective variables for the date, month and year of the first episode, then you can create new dates for following weeks by adding increments of 7 to the day-parameter in mktime (like shown above).
Then format for output to SQL like this:
$datetime_str = date("Y-m-d H:i:s", $next_ep_timestamp);
//gives a date-str like '2011-10-16 12:59:01'
The first idea that comes to my mind is just adding the seconds in a week to the sEpsAirDate with every iteration in the loop:
$sEpsAirDate += 604800;
If you needed to preserve the first air date you could copy it out into a separate variable and then do something like this (change the LCV $i to start at 0):
$sEpsAirDate = $sEpsFirstAirDate+(604800*$i);
But this method has the potential to create problems with Daylight Savings Time... so it might be safer to break the date into year, month and day variables and then recreate the $sEpsAirDate with every loop iteration by adding ($i*7) to day. ... So something like (again change the LCV $i to start at 0):
$sEpsAirDate = mktime($sEpsAirDateHour, $sEpsAirDateMinute, 0, $sEpsAirDateMonth, $sEpsAirDateDay+($i*7), $sEpsAirDateYear);

Categories