Ok so I am trying to schedule a campaign with mailchimp API and so far everything works fine except for the last else if that doesn't put 00 in my variable. I know php will put only 1 zero in the array and can't think of a work around for this. Help ! The code below is used to take a date, put it in iso 8601 format and then I use substr_replace() to schedule the campaign to the next time lapse available for mailchimp (15, 30, 45, 00).
I tried to change it for a string "00" instead but mailchimp does not schedule it.
$date_temp = new DateTime($date_debut);
$date_debut_iso = $date_temp->format('c');
$test = explode(':', $date_debut_iso);
//campaign has to be scheduled on :00, :15, :30, :45
if($test[1] >= 0 && $test[1] <= 15){
$test[1] = 15;
}else if($test[1] >= 16 && $test[1] <= 30){
$test[1] = 30;
}else if($test[1] >= 31 && $test[1] <= 45){
$test[1] = 45;
}else if($test[1] >= 46 && $test[1] <= 59){
$test[1] = 00;
}
$new_date = substr_replace($date_debut_iso, $test[1], 14, 2);
i need the last else if to store 00 in my array $test[1] instead of 0. String doesn't work.
My only guess as to why setting $test[1] = '00'; wouldn't have worked is that all the other cases increase the time (or leave it the same), while that case decreases it because you're setting the minute to zero without changing the hour.
You don't really need to do all the string manipulation though. You can just get the minutes from the DateTime object and do a little math, then output the final result with ->format().
$date_temp = new DateTime($date_debut);
if ($offset = $date_temp->format('i') % 15) {
$date_temp->modify('+' . (15 - $offset) . ' minutes');
};
$new_date = $date_temp->format('c');
The calculation is basically: if the remainder of the minutes divided by 15 is non-zero, increase the time by 15 - remainder minutes. This will also increment the hour appropriately for the > 45 case.
Related
I need to rotate 3 options based on the current week number; ie:
if($weekNumber == 42 || $weekNumber == 43){
$thisID = 1;
}
else if($weekNumber == 44 || $weekNumber == 45){
$thisID = 3;
}
else if($weekNumber == 46 || $weekNumber == 47){
$thisID = 2;
}
else if($weekNumber == 48 || $weekNumber == 49){
$thisID = 1;
}
I'd obviously prefer this to be less manual! I've considered placing the 3 ID's in an array and selecting based on the number of weeks that have passed since date X but I'm not sure how to implement that.
And additionally... the rollover needs to be at Midday on a Friday. I considered simply incrementing the week number in the above plan too, with additional adjustments for when we're rolling from week 52 to week 1, but there must be a more sensible approach!
Thanks
Why don't you take the rounded half of the week number? Then you only need a catalog holding 26 IDs and you can implement a direct lookup:
$catalog=[1,2,3,4,5,6,3,4,2,5,6,7,4,4,7,9,5,8,8,9,2,4,5,7,6,8,9];
$thisID = $catalog[floor($weekNumber/2)];
This should work:
$options = array(1,2,3);
$offset = 129600;
$twoWeeks = 1209600;
$idx = floor((time()-$offset)/$twoWeeks) % count($options);
$chosenOption = $options[$idx];
Some explanation:
0 Unix time was a Thursday at midnight, so the first Friday at midday was 129600 seconds later.
With time()-$offset we shift the time to set Friday at midday as the zero point of our time calculation.
Now as Friday at midday is the zero point, we can count the number of full two weeks from the first Friday at midday by simply dividing the passed seconds by 1209600.
Just wondering how I would select the closest variable.
I have a set list of military times, i.e:
0030
0100
0130
0200
etc...
All in half hour increments. How would I select the closest time to now.
For example.
User clicks on the button, php gets the time it is now, and selects the closest time variable. So if it's 0144, it would pick 0130. and if it's 0146, it would pick 0200.
Since you always store times at 30 minutes interval, subtract the last 2 digits (minutes) from the current time from 30.
For example:
If current time is 0146,
strip out 46 (minutes)
Take absolute difference from 30
If difference > 15, take the next available time slot for 0146
(which is 0200 here)
If difference <= 15, take the previous available time before 0146
(which is 0130 here)
Hope this helps.
I believe this should do it:
function military_time() {
$hour = (int) date('G');
$minute = (int) date('i');
$rounded_minute = round($minute / 30);
switch ($rounded_minute) {
case 0:
$minute = '00';
break;
case 1:
$minute = '30';
break;
case 2:
$minute = '00';
$hour = (int) $hour + 1;
break;
}
// 2400 should become 0000
if ($hour > 23) $hour = 0;
// leading zero
if ($hour < 10) $hour = '0' . $hour;
return $hour . $minute;
}
echo military_time();
Could probably be improved though.
For ease, in your calculations treat them as integers, ignoring the leading zeroes as they're not useful to your calculations.
You have 144 and you want to round down to 130, or 146, up to 200. Similarly 14 (0014) would go to 0 (0000) and 15 (0015) up to 30.
Simple if/thens would suffice to complete this.
You can try
$times = array("0030","0100","0130","0200");
echo "<pre>";
echo militaryTime($times, "0020"), PHP_EOL;
echo militaryTime($times, "0050"), PHP_EOL;
echo militaryTime($times, "0144"), PHP_EOL;
echo militaryTime($times, "0146"), PHP_EOL;
echo militaryTime($times, "0220"), PHP_EOL;
Output
0030
0100
0130
0200
0200
Function Used
function militaryTime($times, $selected) {
if (empty($times))
trigger_error("Empty array not supported ");
$times[] = $selected;
sort($times);
$position = array_search($selected, $times, true);
$current = DateTime::createFromFormat("Hi", $times[$position]);
$previous = isset($times[$position - 1]) ? DateTime::createFromFormat("Hi", $times[$position - 1]) : null;
$next = isset($times[$position + 1]) ? DateTime::createFromFormat("Hi", $times[$position + 1]) : null;
if ($previous != null && $next == null) {
return $previous->format("Hi");
}
if ($previous == null && $next != null) {
return $next->format("Hi");
}
$closest = ($current->diff($previous)->format("%i") - $current->diff($next)->format("%i") <= 0) ? $previous : $next;
return $closest->format("Hi");
}
I need to find date x such that it is n working days prior to date y.
I could use something like date("Y-m-d",$def_date." -5 days");, but in that case it wont take into consideration the weekend or off-date. Let's assume my working days would be Monday to Saturday, any idea how I can accomplish this?
Try this
<?php
function businessdays($begin, $end) {
$rbegin = is_string($begin) ? strtotime(strval($begin)) : $begin;
$rend = is_string($end) ? strtotime(strval($end)) : $end;
if ($rbegin < 0 || $rend < 0)
return 0;
$begin = workday($rbegin, TRUE);
$end = workday($rend, FALSE);
if ($end < $begin) {
$end = $begin;
$begin = $end;
}
$difftime = $end - $begin;
$diffdays = floor($difftime / (24 * 60 * 60)) + 1;
if ($diffdays < 7) {
$abegin = getdate($rbegin);
$aend = getdate($rend);
if ($diffdays == 1 && ($astart['wday'] == 0 || $astart['wday'] == 6) && ($aend['wday'] == 0 || $aend['wday'] == 6))
return 0;
$abegin = getdate($begin);
$aend = getdate($end);
$weekends = ($aend['wday'] < $abegin['wday']) ? 1 : 0;
} else
$weekends = floor($diffdays / 7);
return $diffdays - ($weekends * 2);
}
function workday($date, $begindate = TRUE) {
$adate = getdate($date);
$day = 24 * 60 * 60;
if ($adate['wday'] == 0) // Sunday
$date += $begindate ? $day : -($day * 2);
return $date;
}
$def_date="";//define your date here
$preDay='5 days';//no of previous days
date_sub($date, date_interval_create_from_date_string($preDay));
echo businessdays($date, $def_date); //date prior to another date
?>
Modified from PHP.net
Thanks for the help guys, but to solve this particular problem I wrote a simple code:
$sh_padding = 5; //No of working days to count backwards
$temp_sh_padding = 1; //A temporary holder
$end_stamp = strtotime(date("Y-m-d", strtotime($date_format)) . " -1 day"); //The date(timestamp) from which to count backwards
$start_stamp = $end_stamp; //start from same as end day
while($temp_sh_padding<$sh_padding)
{
$sh_day = date('w',$start_stamp);
if($sh_day==0){ //Skip if sunday
}
else
{
$temp_sh_padding++;
}
$start_stamp = strtotime(date("Y-m-d",$start_stamp)." -1 day");
}
$sh_st_dte = date("Y-m-d",$start_stamp); //The required start day
A quick bit of googling got me to this page, which includes a function for calculating the number of working days between two dates.
It should be fairly trivial to adjust that concept to suit your needs.
Your problem, however, is that the concept of "working days" being monday to friday is not universal. If your software is only ever being used in-house, then it's okay to make some assumptions, but if it's intended for use by third parties, then you can't assume that they'll have the same working week as you.
In addition, public holidays will throw a big spanner in the works, by removing arbitrary dates from various working weeks throughout the year.
If you want to cater for these, then the only sensible way of doing it is to store the dates of the year in a calendar (ie a big array), and mark them individually as working or non-working days. And if you're going to do that, then you may as well use the same mechanism for weekends too.
The down-side, of course, is that this would need to be kept up-to-date. But for weekends, at least, that would be trivial (loop through the calendar in advance and mark weekend days where date('w')==0 or date('w')==6).
I need to check in PHP if the current time is before 2pm that day.
I've done this with strtotime on dates before, however this time it's with a time only, so obviously at 0.00 each day the time will reset, and the boolean will reset from false to true.
if (current_time < 2pm) {
// do this
}
if (date('H') < 14) {
$pre2pm = true;
}
For more information about the date function please see the PHP manual. I have used the following time formatter:
H = 24-hour format of an hour (00 to 23)
Try:
if(date("Hi") < "1400") {
}
See: http://php.net/manual/en/function.date.php
H 24-hour format of an hour with leading zeros 00 through 23
i Minutes with leading zeros 00 to 59
You could just pass in the time
if (time() < strtotime('2 pm')) {
//not yet 2 pm
}
Or pass in the date explicitly as well
if (time() < strtotime('2 pm ' . date('d-m-Y'))) {
//not yet 2 pm
}
Use 24 hour time to get round the problem like so:
$time = 1400;
$current_time = (int) date('Hi');
if($current_time < $time) {
// do stuff
}
So 2PM equates to 14:00 in 24 hour time. If we remove the colon from the time then we can evaluate it as an integer in our comparison.
For more information about the date function please see the PHP manual. I have used the following time formatters:
H = 24-hour format of an hour (00 to 23)
i = Minutes with leading zeros (00 to 59)
You haven't told us which version of PHP you're running, although, assuming it's PHP 5.2.2+ than you should be able do it like:
$now = new DateTime();
$twoPm = new DateTime();
$twoPm->setTime(14,0); // 2:00 PM
then just ask:
if ( $now < $twoPm ){ // such comparison exists in PHP >= 5.2.2
// do this
}
otherwise, if you're using one of older version (say, 5.0) this should do the trick (and is much simplier):
$now = time();
$twoPm = mktime(14); // first argument is HOUR
if ( $now < $twoPm ){
// do this
}
If you want to check whether the time is before 2.30 pm ,you can try the following code segment .
if (date('H') < 14.30) {
$pre2pm = true;
}else{
$pre2pm = false;
}
Try with
if( time() < mktime(14, 0, 0, date("n"), date("j"), date("Y")) ) {
// do this
}
This function will check if it's between hours in EST by accepting 2 params, arrays with the hour and am/pm...
/**
* Check if between hours array(12,'pm'), array(2,'pm')
*/
function is_between_hours($h1 = array(), $h2 = array())
{
date_default_timezone_set('US/Eastern');
$est_hour = date('H');
$h1 = ($h1[1] == 'am') ? $h1[0] : $h1[0]+12;
$h1 = ($h1 === 24) ? 12 : $h1;
$h2 = ($h2[1] == 'am') ? $h2[0] : $h2[0]+12;
$h2 = ($h2 === 24) ? 12 : $h2;
if ( $est_hour >= $h1 && $est_hour <= ($h2-1) )
return true;
return false;
}
Use time(), date() and strtotime() functions:
if(time() > strtotime(date('Y-m-d').' 14:00') {
//...
}
I want to divide time to an integer value:
1-> 6.15AM till 7.00AM
2-> 7.00AM till 7.45AM
3-> 7.45AM till 8.30AM
4-> 8.30AM till 9.15AM
------BREAK----------- 15 minutes
5-> 9.30AM till 10.15AM
6-> 10.15AM till 11.00AM
7-> 11.00 till 11.45AM
-------BREAK---------- 15 minutes
8-> 12.00 till 12.45PM
9-> 12.45PM till 1.30PM
10-> 1.30PM till 02.15PM
Anyone can help me...?
thanks before..!
check out http://php.net/manual/en/function.mktime.php it might me able to help you, try converting the times into unix timestamps maybe?
Try, you might have to change the ranges a bit (i am too lazy to do the exact calculation)
$time = time(); // or if your time is in string format use $time = strtotime('10:15 AM');
$seconds_elapsed = $time % 86400; // Seconds since midnight
$mins_elapsed = $seconds_elapsed / 60;
$mins_split = floor($mins_elapsed / 15); // Split into 15 mins intervals
if ( $mins_split >= 25 && $mins_split <= 36) {
$index = ($mins_split - 25) / 3;
} elseif ($mins_split >= 38 << $mins_split <= 47) {
$index = ($mins_split - 38) / 3;
} else {
$index = ($mins_split - 48) / 3;
}