I have an array which each element contains a startdate and enddate formated in 'dd.mm.yy'.
Array
(
[0] =
(
[date_start] = 23.07.2014
[date_end] = 02.08.2014
)
)
Now i need to build an array that will contain every day between date_start and date_end to validate them later.
Now my question is how can i calculate every day between those dates and save it to an array ?
IF YOU JUST WANT DATE DIFFERENCE
<?php
$arr=array
(
array
(
'date_start' =>'23.07.2014',
'date_end' =>'02.08.2014'
),
array
(
'date_start' =>'15.07.2014',
'date_end' =>'02.08.2014'
)
);
foreach($arr as $key=>$val){
$diff=strtotime($val['date_end'])-strtotime($val['date_start']);
$new_arr[]=array(
'day_start'=>$val['date_start'],
'day_end'=>$val['date_end'],
'difference'=>$diff/(24*60*60)-1
);
}
print_r($new_arr);
?>
OUTPUT
Array
(
[0] => Array
(
[day_start] => 23.07.2014
[day_end] => 02.08.2014
[difference] => 9
)
[1] => Array
(
[day_start] => 15.07.2014
[day_end] => 02.08.2014
[difference] => 17
)
)
IF YOU WANT ALL DATE BETWEEN ARRAYS
<?php
$arr=array
(
array
(
'date_start' =>'23.07.2014',
'date_end' =>'02.08.2014'
),
array
(
'date_start' =>'15.07.2014',
'date_end' =>'02.08.2014'
)
);
foreach($arr as $key=>$val){
$diff=strtotime($val['date_end'])-strtotime($val['date_start']);
$day_diff=$diff/(24*60*60);
$alldiff=array();
for($i=1;$i<=$day_diff-1;$i++){
$alldiff[]=date('d.m.Y',(strtotime($val['date_start'])+$i*24*60*60));
}
$new_arr[]=array(
'day_start'=>$val['date_start'],
'day_end'=>$val['date_end'],
'difference'=>$alldiff
);
}
echo "<pre>";
print_r($new_arr);
?>
OUTPUT
Array
(
[0] => Array
(
[day_start] => 23.07.2014
[day_end] => 02.08.2014
[difference] => Array
(
[0] => 24.07.2014
[1] => 25.07.2014
[2] => 26.07.2014
[3] => 27.07.2014
[4] => 28.07.2014
[5] => 29.07.2014
[6] => 30.07.2014
[7] => 31.07.2014
[8] => 01.08.2014
)
)
[1] => Array
(
[day_start] => 15.07.2014
[day_end] => 02.08.2014
[difference] => Array
(
[0] => 16.07.2014
[1] => 17.07.2014
[2] => 18.07.2014
[3] => 19.07.2014
[4] => 20.07.2014
[5] => 21.07.2014
[6] => 22.07.2014
[7] => 23.07.2014
[8] => 24.07.2014
[9] => 25.07.2014
[10] => 26.07.2014
[11] => 27.07.2014
[12] => 28.07.2014
[13] => 29.07.2014
[14] => 30.07.2014
[15] => 31.07.2014
[16] => 01.08.2014
)
)
)
This should work:
$startDate = new DateTime('2014-05-01');
$endDate = new DateTime('2014-06-02');
// calculate diff
$diff = $startDate->diff($endDate);
$daysDiff = $diff->days;
for ($i = 0; $i < $daysDiff; $i++) {
// clone so the original date will not be changed
$currentDate = clone $startDate;
$currentDate->modify('+'.$i.' days');
echo $currentDate->format('Y-m-d H:i:s')."\n";
}
Now you only have to make this for every array entry and save it to an array
Why don't you convert dates into timestamp, then you loop from the timestamp_start until timestamp_end , by day amount of seconds, then you convert each steps into a new date to check later.
Something like this?
// Convert start and end dates to unix timestamp
$start = strptime($date_array[0]['date_start'], '%d.%m.%Y');
$end = strptime($date_array[0]['date_end'], '%d.%m.%Y');
$dates = array();
while ($start < $end){
$dates[] = date('d.m.Y', $start);
$start += 86400 // One day equals 86400 seconds
}
Try this as it is working for me
function getDates($startTime, $endTime) {
$day = 86400;
$format = 'd.m.Y';
$startTime = strtotime($startTime);
$endTime = strtotime($endTime);
$numDays = round(($endTime - $startTime) / $day);
$days = array();
for ($i = 1; $i < $numDays; $i++) {
$days[] = date($format, ($startTime + ($i * $day)));
}
return $days;
}
$days = getDates('23.07.2014', '02.08.2014');
Related
I need to buildup a graph with total sales for each day for last week, I did not get all 7 days data, rather getting 3 days data from database, I need to push rest of the 4days with total sales 0,
I have the following array of 3 days
Array
(
[0] => Array
(
[SalesDate] => Jun09
[total] => 4
)
[1] => Array
(
[SalesDate] => Jun11
[total] => 2
)
[2] => Array
(
[SalesDate] => Jun14
[total] => 1
)
)
but I need all 7days data from Jun09 to Jun15 like this
Array
(
[0] => Array
(
[SalesDate] => Jun09
[total] => 4
)
[1] => Array
(
[SalesDate] => Jun10
[total] => 0
)
[2] => Array
(
[SalesDate] => Jun11
[total] => 2
)
[3] => Array
(
[SalesDate] => Jun12
[total] => 0
)
[4] => Array
(
[SalesDate] => Jun13
[total] => 0
)
[5] => Array
(
[SalesDate] => Jun14
[total] => 1
)
[6] => Array
(
[SalesDate] => Jun15
[total] => 0
)
)
I have tried with following code, but not getting the required data.
<?php
$sales =array(array('SalesDate' => 'Jun09',
'total' => 4
),
array
(
'SalesDate' => 'Jun11',
'total' => 2
),
array
(
'SalesDate' => 'Jun14',
'total' => 1
)
);
$final_array = array();
foreach($sales as $sale)
{
for($i=7;$i>0;$i--)
{
$current_weeks =[];
if($sale['SalesDate'] ==date('Md', strtotime("-".$i." days")))
{
$week_days['SalesDate'] = $sale['SalesDate'];
$week_days['total'] = $sale['total'];
}
else
{
$week_days['SalesDate'] = date('Md', strtotime("-".$i." days"));
$week_days['total'] = 0;
}
$final_array[] =$week_days;
}
}
You could first create a 'skeleton' array that matches your source array $arr, but with all the previous seven days $prevSevenDays. The date format matches the source array's, the totals are all set to 0.
// build empty skeleton
$prevSevenDays = [];
for ($i = 7; $i > 0; $i--) {
$prevSevenDays[$i]['SalesDate'] = date('Md', strtotime("-$i days"));
$prevSevenDays[$i]['Total'] = 0;
}
All you have to do is cycle through this array to replace the entries with available data in your source array $arr.
foreach ($arr as $sales) {
foreach ($prevSevenDays as $key => $day) {
if ($sales['SalesDate'] === $day['SalesDate']) $prevSevenDays[$key]['Total'] = $sales['Total'];
}
}
demo
Following is my code to bring all the latest dates in a month from dates array
$dates = Array
(
"2017/03/05",
"2017/03/06",
"2017/04/01",
"2017/04/16",
"2017/06/16",
"2017/06/19",
"2017/07/07",
"2017/08/19",
);
$curr_val = '';
$years = Array();
$months = Array();
foreach($dates as $d) {
list($y,$m) = explode("/",$d);
$years[$y][] = $d;
if ($m != $curr_val){
$months[$y."/".$m][] = $d;
$curr_val = $m ;
}
}
$years = array_values($years);
$months = array_values($months);
print_r($months);
Above code is printing values of first occurance date in a month. But i want the latest date from month.
Above code gives following output
Array ( [0] => Array ( [0] => 2017/03/05 ) [1] => Array ( [0] => 2017/04/01 ) [2] => Array ( [0] => 2017/06/16 ) [3] => Array ( [0] => 2017/07/07 ) [4] => Array ( [0] => 2017/08/19 ) )
But expected code is
Array ( [0] => Array ( [0] => 2017/03/06 ) [1] => Array ( [0] => 2017/04/16 ) [2] => Array ( [0] => 2017/06/19 ) [3] => Array ( [0] => 2017/07/07 ) [4] => Array ( [0] => 2017/08/19 ) )
Instead of printing first date in month, i want last date of month to be printed. how can i get that??
Your code could be reduced a lot. Here's what I could do:
$dates = Array
(
"2017/03/05",
"2017/03/06",
"2017/04/01",
"2017/04/16",
"2017/06/16",
"2017/06/19",
"2017/07/07",
"2017/08/19",
);
$array = [];
foreach($dates as $d) {
$date = \DateTime::createFromFormat('Y/m/d' , $d);
if (
!isset($array[$date->format('Y')][$date->format('m')])
|| $array[$date->format('Y')][$date->format('m')] < $date
) {
$array[$date->format('Y')][$date->format('m')] = $date;
}
}
print_r($array);
It's a simple logic that will check if the value is higher inside the same year/month and replace if it is.
Result:
Array (
[2017] => Array
(
[03] => DateTime Object
(
[date] => 2017-03-06 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
[04] => DateTime Object
(
[date] => 2017-04-16 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
[06] => DateTime Object
(
[date] => 2017-06-19 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
[07] => DateTime Object
(
[date] => 2017-07-07 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
[08] => DateTime Object
(
[date] => 2017-08-19 22:18:42.000000
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
)
)
Like this:
foreach($dates as $d) {
list($y,$m) = explode("/",$d);
$years[$y][] = $d;
$months[$y."/".$m] = [$d];
}
Don't worry about keeping track of the current value. Just keep overwriting $months[$y."/".$m] as you go, and you'll end up with the last date for each month.
If you want to get the most recent date from each month, rather than just the last one in the input array, make sure $dates is sorted before you start the loop. Since they're in year/month/day format, a simple sort($dates); should work. (In the case of your example, $dates is already sorted so this won't make any difference.)
This seems simplest to me:
Code: (Demo)
$dates[
"2017/03/05",
"2017/03/06",
"2017/04/01",
"2017/04/16",
"2017/06/16",
"2017/06/19",
"2017/07/07",
"2017/08/19"
];
foreach($dates as $d){
$result[substr($d,0,7)]=$d; // extract unique key from values
}
$result=array_values($result); // reindex array
var_export($result);
Output:
array (
0 => '2017/03/06',
1 => '2017/04/16',
2 => '2017/06/19',
3 => '2017/07/07',
4 => '2017/08/19',
)
I found some solutions on google but they are not fulfilling my requirement.
I have an array,
$current_week = self::CurrentWeekDateRange($s_date, $e_date);
it is giving me result:
[0] => 2016-09-06
[1] => 2016-09-07
[2] => 2016-09-08
[3] => 2016-09-09
[4] => 2016-09-10
[5] => 2016-09-11
[6] => 2016-09-12
[7] => 2016-09-13
[8] => 2016-09-14
[9] => 2016-09-15
[10] => 2016-09-16
[11] => 2016-09-17
[12] => 2016-09-18
now My Next array is like this: user log $return a array
[0] => Array
(
[date_log] => 2016-09-08
[total] => 15
)
[1] => Array
(
[date_log] => 2016-09-13
[total] => 30
)
[2] => Array
(
[date_log] => 2016-09-14
[total] => 400
)
No i have , 3 user means it print 3 times user log.
So what i want is i want to match date_log to above my first array,
If its matches it will give it will get store in another array and if not match then it will store 0.
My problem i am using two loops ant it is printing loop1 * loop2 times value but i want only $current_week times values
I tried like this:
$current_week = self::CurrentWeekDateRange($s_date, $e_date);
$i = 0;
foreach ($current_week as $day){
foreach ($returns as $return) {
if($day == $return['date_log']){
$array_total_hours[$i]['total'] = $return['total'];
$array_total_hours[$i]['date_log'] = $return['date_log'];
}
else {
$array_total_hours[$i]['date_log'] = $return['date_log'];
$array_total_hours[$i]['total'] = 0;
}
$i++;
}
}
print( $array_total_hours);
I want my result like this:
[2016-09-06] => Array
(
[date_log] => 2016-09-06
[total] => 0
)
[2016-09-07] => Array
(
[date_log] => 2016-09-07
[total] => 30
)
[2016-09-08] => Array
(
[date_log] => 2016-09-08
[total] => 400
)
[2016-09-09] => Array
(
[date_log] => 2016-09-09
[total] => 0
)
.
.
.
.
.
.
.
[2016-09-18] => Array
(
[date_log] => 2016-09-18
[total] => 0
)
This one should do the job.
$current_week = self::CurrentWeekDateRange($s_date, $e_date);
$finalResult = array();
foreach ($current_week as $date) {
$finalResult[$date] = array('date_log' => $date, 'total' => 0);
}
$dates = array_keys($finalResult);
// not sure where this one comes from
$nextArray = array(
array('date_log' => '2016-09-08', 'total' => 15),
array('date_log' => '2016-09-13', 'total' => 30)
);
foreach ($nextArray as $return) {
$record = array('date' => '', 'total' => 0);
if (in_array($return['date'], $dates)) {
$finalResult[$return['date']]['total'] = $return['total'];
}
}
okey working with your solution it will work like this:
$current_week = self::CurrentWeekDateRange($s_date, $e_date);
$i = 0;
foreach ($current_week as $day){
$value = 0;
$date = $return
foreach ($returns as $return) {
if($day == $return['date_log']){
$value = $return['total'];
break;
}
}
$array_total_hours[$i]['total'] = $value;
$array_total_hours[$i]['date_log'] = $date;
$i++;
}
print( $array_total_hours);
You only have to assing the total value once per $current_week, not for every possible log.
I'm using DateInterval and DatePeriod to generate shifts in a medical application
$begin = new DateTime('2012-08-01 08:00');
$end = new DateTime('2012-08-01 12:00');
$interval = new DateInterval('PT45M');
$daterange = new DatePeriod($begin, $interval ,$end);
Those functions allow me to generate the following array
Array
(
[0] => 08:00
[1] => 08:45
[2] => 09:30
[3] => 10:15
[4] => 11:00
[5] => 11:45
)
Which functions and how could I do so the final array gets completed and chunked as this?
Array
(
[0] => Array
(
[0] => 08:00
[1] => 08:45
)
[1] => Array
(
[0] => 08:45
[1] => 09:30
)
[2] => Array
(
[0] => 09:30
[1] => 10:15
)
[3] => Array
(
[0] => 10:15
[1] => 11:00
)
[4] => Array
(
[0] => 11:00
[1] => 11:45
)
)
Thanks
$previous = null;
$dates = array();
foreach ($period as $dt) {
$current = $dt->format("H:i");
if (!empty($previous)) {
$show = new DateTime($current);
$dates[] = array($previous, $show->format('H:i'));
}
$previous = $current;
}
After retrieve your array using DateTime function. Just Plug n Play with the code. :)
$retrieveArray = array('08:00','08:45','09:30','10:15','11:00','11:45'); // Sample Array, Assumed mentioned in Question.
$final = array();
for ($i=0; $i < count($retrieveArray)-1; $i++) {
$j = $i+1;
$final[$i] = array($retrieveArray[$i], $retrieveArray[$j]);
}
Use var_dump($final); to check array result.
Desired Output
Array
(
[0] => Array
(
[0] => 08:00
[1] => 08:45
)
[1] => Array
(
[0] => 08:45
[1] => 09:30
)
[2] => Array
(
[0] => 09:30
[1] => 10:15
)
[3] => Array
(
[0] => 10:15
[1] => 11:00
)
[4] => Array
(
[0] => 11:00
[1] => 11:45
)
)
Edit:
To Add Last Shift
#jhon is right. It skips the last boundary value if it matches exactly the length of the interval.
As you need it, I suggest to ADD +1 min to your end time. It's a tweak/fix but server the purpose.
$begin = new DateTime('2012-08-01 08:00');
$end = new DateTime('2012-08-01 10:00');
$end = $end->modify( '+1 minute' ); // Tweak, to add last shift value.
$interval = new DateInterval('PT30M');
$daterange = new DatePeriod($begin, $interval ,$end);
To Check Output
foreach ( $daterange as $dt ){
echo '<pre>';
echo $dt->format( "H:i" );
echo '</pre>';
}
It is including last boundary value if it matches exactly the length of the interval.
I have two dates (start and end), for example:
$date['start'] = '2012-07-11';
$date['end'] = '2012-07-13';
i would like generate -4 and +4 days interval for this. So i would like receive for example array with:
$date['start'] = '2012-07-07';
$date['end'] = '2012-07-09';
$date['start'] = '2012-07-08';
$date['end'] = '2012-07-10';
$date['start'] = '2012-07-09';
$date['end'] = '2012-07-11';
$date['start'] = '2012-07-10';
$date['end'] = '2012-07-12';
$date['start'] = '2012-07-11';
$date['end'] = '2012-07-13';
$date['start'] = '2012-07-12';
$date['end'] = '2012-07-14';
$date['start'] = '2012-07-13';
$date['end'] = '2012-07-15';
$date['start'] = '2012-07-14';
$date['end'] = '2012-07-16';
$date['start'] = '2012-07-15';
$date['end'] = '2012-07-17';
How is the best way for this?
This code does the trick:
$date['start'] = '2012-07-11';
$date['end'] = '2012-07-13';
$dates=array();
for ($i=-4; $i<=4; $i++){
$startDate=strtotime($date['start'] );
$endDate=strtotime($date['end'] );
$startDate=$startDate+($i*60*60*24); //60*60*24 equal to one day
$endDate=$endDate+($i*60*60*24);
array_push($dates, array('start'=>date('Y-m-d', $startDate), 'end'=> date('Y-m-d',$endDate)));
}
print_r($dates);
Output:
Array(
[0] => Array
(
[start] => 2012-07-07
[end] => 2012-07-09
)
[1] => Array
(
[start] => 2012-07-08
[end] => 2012-07-10
)
[2] => Array
(
[start] => 2012-07-09
[end] => 2012-07-11
)
[3] => Array
(
[start] => 2012-07-10
[end] => 2012-07-12
)
[4] => Array
(
[start] => 2012-07-11
[end] => 2012-07-13
)
[5] => Array
(
[start] => 2012-07-12
[end] => 2012-07-14
)
[6] => Array
(
[start] => 2012-07-13
[end] => 2012-07-15
)
[7] => Array
(
[start] => 2012-07-14
[end] => 2012-07-16
)
[8] => Array
(
[start] => 2012-07-15
[end] => 2012-07-17
)
)
range(date('Y-m-d', strtotime('-4 days'), date('Y-m-d', strtotime('+4 days'))),
You want 9 pairs of dates starting from -4 days of the supplied range, upto +4 days?
Assuming that your dates will be after 1970:
<?php
$start=strtotime($date['start']);
$end=strtotime($date['end']);
for($loop=-4;$loop<=4;$loop++)
{
$loop_str='';
if($loop>=0) $loop_str.='+';
$loop_str.=$loop.' days';
$date['start']=strtotime($loop_str, $start);
$date['end']=strtotime($loop_str, $end);
print_r($date);
}
?>