For example, in my case, i already has this value of array.....
array(1) {
[1]=>
array(1120) {
["2006-02-25"]=>
array(1) {
[0]=>
int(33)
}
["2006-02-20"]=>
array(1) {
[0]=>
int(38)
}
["2006-02-28"]=>
array(1) {
[0]=>
int(46)
}
that result I've got this code
$explodeEndDate = explode(" ",$adEndDate);
$explodeStartDate = explode(" ", $adStartDate);
$StartDate = $explodeStartDate[0];
$NewStartDate = strtotime("$explodeStartDate[0]");
$NewEndDate = strtotime("$explodeEndDate[0]");
$timeDiff = abs($NewEndDate - $NewStartDate);
// 86400 seconds in one day
$NumberDays = $timeDiff/86400;
//convert into int
$NumberDays = intval($NumberDays);
if(array_key_exists($NumberDays, $array[$itemType]) == false){
$array[$itemType][$StartDate] =[$NumberDays];
}
}
what I wanted to achieve is, in the "$StartDate" value which is for example ["2006-02-28"] , I wanted to plus it with the value of it. If we referring back to the figure above for example is
["2006-02-25"]=>
array(1) {
[0]=>
int(33)
so 2006-02-25 is the plus by 33 and the result is 2006-04-01. and after that, i wanted to make the date within that range
If you want to add date so here you go:
Months:
<?php
$date = date('Y-m-d', strtotime("+33 months", strtotime('2006-02-25')));
var_dump($date)
?>
Demo.
Days:
<?php
$date = date('Y-m-d', strtotime("+33 days", strtotime('2006-02-25')));
var_dump($date)
?>
Demo
Related
I got something like this in MyBB and I want add 5 days to date ($datetime1) with one should be stored in $nowPlus5D.
Moreover display in $leeft variable how much days, hours, minutes left. difference between (day bought + 5days ) - datenow
define("IN_MYBB", 1);
require_once "global.php";
$data_zakupu = $db->query("
SELECT timestamp
FROM ".TABLE_PREFIX."subs
WHERE txn_id <> '' AND uid=".$mybb->user['uid']." ORDER BY lid DESC LIMIT 1;
");
$dat = $db->fetch_field($data_zakupu,"timestamp");
$date_buy = date('d-m-Y H:i:s', $dat); // added h:i:s
// Total bought
echo '<br><hr>';
echo 'Bought date - ' . $date_buy;
echo '<br>';
$datetime2 = new DateTime('now');
$datetime1 = new DateTime($date_buy);
$interval = $datetime1->diff($datetime2);
$nowPlus5D = $datetime1->add(new DateInterval('P5D'));
echo '<hr><br>';
echo 'Expiration date - ' . $nowPlus5D->format('%a days, %h hours, %i, minutes');
echo '<br>';
$leeft = $nowPlus5D->diff($datetime1);
var_dump($leeft);
echo '<br>';
echo $left->format('%a days, %h hours, %i, minutes');
and I got that
Bought date - 20-12-2018 18:20:48
Expiration date - %pm 25pm1848, %06 062018000000Tue, 25 Dec 2018 18:20:48 +010048, %20, 12201200000031Europe/Warsaw48
object(DateInterval)#14 (15) { ["y"]=> int(0) ["m"]=> int(0) ["d"]=> int(0) ["h"]=> int(0) ["i"]=> int(0) ["s"]=> int(0) ["weekday"]=> int(0) ["weekday_behavior"]=> int(0) ["first_last_day_of"]=> int(0) ["invert"]=> int(0) ["days"]=> int(0) ["special_type"]=> int(0) ["special_amount"]=> int(0) ["have_weekday_relative"]=> int(0) ["have_special_relative"]=> int(0) }
Fatal error: Call to a member function format() on integer in /stackoverflow.php on line 42
Your main issue is you are confusing a couple objects. Specifically DateInterval with DateTime. Formatting is one thing that differs.
<?php
$date_buy = '2018-12-15 10:05:22';
$datetime2 = new DateTime('now');
$datetime1 = new DateTime($date_buy);
$interval = $datetime1->diff($datetime2);
$nowPlus5D = $datetime1->add(new DateInterval('P5D'));
//THIS IS A DATETIME OBJECT, NOT AN INTERVAL! NOTE FORMAT `Y-m-d H:i:s`
echo 'Expiration date - ' . $nowPlus5D->format('d \d\a\y\s, H \h\o\u\r\s, i \m\i\n\u\t\e\s');
var_dump($nowPlus5D);
var_dump($datetime1);
// ^ Notice those are the same? A result of `$nowPlus5D = $datetime1->add(new DateInterval('P5D'));`
// and Intervals then are of course zeros...
$left = $nowPlus5D->diff($datetime1);
echo '<br>';
echo $left->format('%a days, %h hours, %i, minutes');
// could do this...
$left = $nowPlus5D->diff(new \DateTime);
echo $left->format('%a days, %h hours, %i, minutes');
Anyway, think your main confusion was over the two object types. Imagine you can take it from here.
Example :
00:00 22-03-2017, John Wilson
08:00 22-03-2017, Gemma Arterton
16:00 22-03-2017, Arnold Plank
00:00 22-03-2017, Timmy Brouwer
08:00 22-03-2017, John Wilson <- names repeating
16:00 22-03-2017, Gemma Arterton
I am building a shift system that generated a time and date for the next 30 days. I am trying to get different related names to getting echo'd behing the date but so far no luck.
The names are interactive meaning there could be only 1 aswell as 25 (so to speak).
This is my current call to function code:
$month = $shift->date_range(date("Y-m-d"), date('Y-m-d', strtotime("+30 days")), "+" . $shift_facility['facility_shift_duration'] . " hours", "Y/m/d H:i:s", $user_per_facility);
And this is my function itself:
public function date_range($first, $last, $step = '+1 day', $output_format = 'd/m/Y', $users)
{
$dates = array();
$current = strtotime($first);
$last = strtotime($last);
while ($current <= $last) {
// Add date and time to array $dates
$dates[] = date($output_format, $current) . ';' . $users[0]["user_id"];
//check if we are still in range between the two dates
$current = strtotime($step, $current);
}
return $dates;
}
$users contains all the user data e.g:
array(2) {
[0]=>
array(5) {
["user_id"]=>
string(1) "3"
["user_alias"]=>
string(7) "ND12345"
["user_facility"]=>
string(2) "29"
["user_phone"]=>
string(5) "12345"
["user_name"]=>
string(9) "Jan steen"
}
[1]=>
array(5) {
["user_id"]=>
string(1) "7"
["user_alias"]=>
string(7) "ND68596"
["user_facility"]=>
string(2) "29"
["user_phone"]=>
string(11) "31115648597"
["user_name"]=>
string(8) "John Doe"
}
}
$users[0]["user_id"];
Only outputs the first name but I need them to alternate (look at the first example).
Does anyone have any idea that could point me in the right direction or help me out a bit?
Thanks in advance ^^
EDIT: More details
My function call is in a foreach:
foreach ($facility->getfacilities() as $shift_facility) {
$user_per_facility = $user->getusersbyFacilityId($shift_facility['facility_id']);
if (isset($user_per_facility[0]["user_id"])) {
//if shift count > dan db results generate new day
$month = $shift->date_range(date("Y-m-d"), date('Y-m-d', strtotime("+30 days")),
"+" . $shift_facility['facility_shift_duration'] . " hours", "Y/m/d H:i:s", $user_per_facility);
}
}
You're sending an entire array of $users to the date_range() method, where you should only be sending one entity of that array (e.g. a single user) to that method.
You're calling $users[0] from within that method, which will always reference the first (zeroth) element from that array, not the specific one you're looking for.
The issue starts from this block:
if (isset($user_per_facility[0]["user_id"])) {
//if shift count > dan db results generate new day
$month = $shift->date_range(date("Y-m-d"), date('Y-m-d', strtotime("+30 days")),
"+" . $shift_facility['facility_shift_duration'] . " hours", "Y/m/d H:i:s", $user_per_facility);
}
That only checks if the user_id is set in the first array element. You need to loop through the users array as well:
foreach ($facility->getfacilities() as $shift_facility) {
$user_per_facility = $user->getusersbyFacilityId($shift_facility['facility_id']);
// Make sure $users_per_facility can be iterated over
if (count($users_per_facility) > 0 && is_array($users_per_facility))
foreach ($users_per_facility as $u) {
if (isset($u["user_id"])) {
//if shift count > dan db results generate new day
$month = $shift->date_range(date("Y-m-d"), date('Y-m-d', strtotime("+30 days")),
"+" . $shift_facility['facility_shift_duration'] . " hours", "Y/m/d H:i:s", $u);
}
}
}
}
Then modify your date_range() method to only take a single user element, not the entire array. For clarification, I changed $users to $user because there is only one "user" being sent to that method:
public function date_range($first, $last, $step = '+1 day', $output_format = 'd/m/Y', $user) {
$dates = array();
$current = strtotime($first);
$last = strtotime($last);
while ($current <= $last) {
// Add date and time to array $dates
$dates[] = date($output_format, $current) . ';' . $user["user_id"];
//check if we are still in range between the two dates
$current = strtotime($step, $current);
}
return $dates;
}
I would also suggest that you re-order the argument list for the date_range method. I'd suggest putting $user first:
public function date_range($user, $first, $last, $step = '+1 day', $output_format = 'd/m/Y')
Also, it's good convention to give your methods (functions) names with a verb, since they "do" something. In this case, make_date_range. Since I can see this is in a class (having the public keyword), it's a good habit to make your method names camelCase, e.g. makeDateRange(), while keeping your variables with underscores. Not required by any means, but it's good practice.
Hope this helps.
In case people stumble on the same issue:
I fixed this issue by creating an variable $i and if it exceeded the size of var $users had it set back to value 0.
(aswell as counting up for each succesfull row)
$i = 0;
if ($i > count($users)-1) {
$i = 0;
}
// Add date and time to array $dates
$dates[] = date($output_format, $current) . ';' . $users[$i]["user_id"];
//check if we are still in range between the two dates
$current = strtotime($step, $current);
$i++;
I writing a script where it will populate a series of dates based on the criteria set between a start and finish time.
I basically using the relative formats in php dates function (http://php.net/manual/en/datetime.formats.relative.php).
My script first get the intervals based on user's selection:
//first get the interval
$event_repeatmonth = $_POST['event_repeatmonth'];
if ($event_repeatmonth == 1){ $interval = 'first';}
if ($event_repeatmonth == 2){ $interval = 'second';}
if ($event_repeatmonth == 3){ $interval = 'third';}
if ($event_repeatmonth == 4){ $interval = 'fourth';}
if ($event_repeatmonth == 5){ $interval = 'fifth';}
if ($event_repeatmonth == 6){ $interval = 'last';}
$onthe_monday = $_POST['onthe_monday'];
$onthe_tuesday = $_POST['onthe_tuesday'];
$onthe_wednesday = $_POST['onthe_wednesday'];
$onthe_thursday = $_POST['onthe_thursday'];
$onthe_friday = $_POST['onthe_friday'];
$onthe_saturday = $_POST['onthe_saturday'];
$onthe_sunday = $_POST['onthe_sunday'];
if ($onthe_monday == 1){ $interval_period[] = $interval." Monday";}
if ($onthe_tuesday == 1){ $interval_period[] = $interval." Tuesday";}
if ($onthe_wednesday == 1){ $interval_period[] = $interval." Wednesday";}
if ($onthe_thursday == 1){ $interval_period[] = $interval. " Thursday";}
if ($onthe_friday == 1){ $interval_period[] = $interval. " Friday";}
if ($onthe_saturday == 1){ $interval_period[] = $interval. " Saturday";}
if ($onthe_sunday == 1){ $interval_period[] = $interval. " Sunday";}
Then it will loop through the dates within the start and finish date. It will grab the first date of the month as the reference date and find the corresponding 1st/2nd/3rd Monday/Tuesday... of the month:
//loop through to insert the array
while ($tmp <= $event_udate){
$tmpmonth = date("Y-m", strtotime($tmp))."-01";
//get proper date based on the intervals we are looking for
foreach ($interval_period AS $period){
$tmp = date("Y-m-d", strtotime($period, strtotime($tmpmonth)));
echo $period."--".$tmp."--".$tmpmonth."<br/>";
//sometimes the first interval will be before the start date, skip that
if ($tmp >= $event_sdate){
$event_datearray[] = $tmp;
}
}
//reset if reach end of the month
if ($repeat_every > 1){
//go to next month
$tmp = date('Y-m-d', strtotime('+'. $repeat_every.' month', strtotime($tmp)));
}else{
//go to next month
$tmp = date('Y-m-d', strtotime('+1 month', strtotime($tmp)));
}
}
For example, here I asked the program to get the second Wednesday and the second Sunday of the month for every 3 months between the time frame of 4/1/2015 - 8/30/2015.
The result should have returned: 4/8, 4/12, 7/8, and 7/12. However, it appears that since 4/1 and 7/1 are on Wednesday, it skipped the first week and grabbed the 3rd Wednesday instead.
My echo result looks like below, as you can see, it grabbed 4/15 as the 2nd Wednesday of 2015-04-01.... and grabbed 7/15 as the 2nd Wednesday of 2015-07-01...
second Wednesday--2015-04-15--2015-04-01
second Sunday--2015-04-12--2015-04-01
second Wednesday--2015-07-15--2015-07-01
second Sunday--2015-07-12--2015-07-01
array(4) { [0]=> string(10) "2015-04-15" [1]=> string(10) "2015-04-12" [2]=> string(10) "2015-07-15" [3]=> string(10) "2015-07-12" }
I am pretty lost here. This seems to be issue only when the first of the month matches one of the criteria. If I change it to 2nd Thursday and 2nd Sunday, then it will return properly:
second Thursday--2015-04-09--2015-04-01
second Sunday--2015-04-12--2015-04-01
second Thursday--2015-07-09--2015-07-01
second Sunday--2015-07-12--2015-07-01
array(4) { [0]=> string(10) "2015-04-09" [1]=> string(10) "2015-04-12" [2]=> string(10) "2015-07-09" [3]=> string(10) "2015-07-12" }
Does anyone have the same issue before???
I figured this out after I posted it....
It turns out the relative format in PHP date DOES NOT include the date it refers to. For example, if you are looking for the 2nd Monday of 2015-04-01, it will look for the first instance of the 2nd Monday after 2015-04-01...
So to fix this, I just check to see if the first of the month matches the criteria I am looking for, if it does, then change my reference day to the day before so it will include the original date into consideration.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
Is it possible to use DateTime to grab every date from now till one week ago and than make an array, for example
1-4-2014
1-3-2014
1-2-2014
And so on
Currently this is my code
<?php
$datetime = new DateTime();
$datetime->format('Y-m-d');
$arr = array(/* diverse dates */);
foreach ($to_remove as $item)
{
$is_smaller = ($to_remove->format('U') <= $datetime->format('U'));
if ($is_smaller)
{
$arr = array_filter($arr, function($item) use ($to_remove) {
return !preg_match("/$to_remove by /", $item);
});
}
}
Basically I need it to check the current date and the dates from one week ago and then remove the string from the array.
Yes, you can use DateTime class and DateInterval with DatePeriod:
$now = new DateTime( "now");
$yourInterval= new DateInterval( 'P1D'); //here you set interval per one day
$yourPeriodOfSevenDays= new DatePeriod( $now, $yourInterval, 7); // here you will set to what piriod of time get inerval
foreach($yourPeriodOfSevenDays as $day) {
$date = $day->format( 'd-m-Y');
$resultArray[] = $date ;
}
Now you will have all dates in array
array(8) { [0]=> string(10) "04-01-2014" [1]=> string(10) "05-01-2014" [2]=> string(10) "06-01-2014" [3]=> string(10) "07-01-2014" [4]=> string(10) "08-01-2014" [5]=> string(10) "09-01-2014" [6]=> string(10) "10-01-2014" [7]=> string(10) "11-01-2014" }
This is the simplest way I can think of:-
$lastWeek = new \DateTime('-7 days');
$interval = new \DateInterval('P1D');
$period = new \DatePeriod($lastWeek, $interval, new \DateTime());
var_dump(iterator_to_array($period));
See it working.
Even simpler, if you like one liners:-
$period = new \DatePeriod(new \DateTime('-7 days'), new \DateInterval('P1D'), new \DateTime());
var_dump(iterator_to_array($period));
See it working.
Then again, you can use a DatePeriod object in a foreach loop, so you may not need an array:-
$period = new \DatePeriod(new \DateTime('-7 days'), new \DateInterval('P1D'), new \DateTime());
foreach($period as $day){
echo $day->format('Y-m-d');
}
See it working
Reference http://php.net/datetime
You could use DateTime::add.
$dateTime = new DateTime("now");
$dateInterval = new DateInterval('P1D');
$days = 7;
$resultArray = array();
for($i=0 ; $i<$days ; $i++){
$dateTime->add($dateInterval);
$resultArray[] = $dateTime->format('d-m-Y');
}
Result:
array(7) {
[0]=> string(10) "05-01-2014"
[1]=> string(10) "06-01-2014"
[2]=> string(10) "07-01-2014"
[3]=> string(10) "08-01-2014"
[4]=> string(10) "09-01-2014"
[5]=> string(10) "10-01-2014"
[6]=> string(10) "11-01-2014"
}
Edit:
My fault, i overread the description "one week ago".
Also you can use DateTime::sub
I have 2 timestamps from 2 dates: 01/2012 and 02/2013. The difference between these timestamps is 31795200. The function i've used is:
function unixTimeStampInMonths($timestamp){
$elapsed_minutes = ($timestamp / 60);
$elapsed_hours = ($elapsed_minutes / 60);
$elapsed_days = ($elapsed_hours / 24);
$elapsed_months = floor($elapsed_days / 30);
return $elapsed_months;
}
But there is a problem, the months are rounded to 30 days. What's the best way of calculating the months difference between them?
LE:
The solution suggested by a friend is:
// arguments format: 05/2010
function monthDifferenceBetween2Dates($first, $second){
$expl1 = explode('/', $first);
$expl2 = explode('/', $second);
$months_in_years = ($expl2[1] - $expl1[1] - 1) * 12;
$first_months = 12 - $expl1[0];
$second_months = $expl2[0];
return $months_in_years + $first_months + $second_months;
}
i'm gonna use this. thanks #nickb
Use PHP's DateTime class instead of UNIX timestamps:
$start = DateTime::createFromFormat( 'm/d/Y', '01/01/2012');
$end = DateTime::createFromFormat( 'm/d/Y', '02/01/2013');
$diff = $start->diff( $end);
var_dump( $diff);
Will output:
object(DateInterval)#3 (8) {
["y"]=>
int(1)
["m"]=>
int(1)
["d"]=>
int(0)
["h"]=>
int(0)
["i"]=>
int(0)
["s"]=>
int(0)
["invert"]=>
int(0)
["days"]=>
int(397)
}
So, to calculate total months, we can do:
$months = $diff->y * 12 + $diff->m;
Which will print 13. Demo