Laravel - add new data into result - php

I have this function to get all max-offers from maxoffers table:
public function maxoffers($id)
{
$offers = Maxoffer::where('article_id', $id)->latest()->get(['id', 'price', 'start', 'user_id']);
return $offers;
}
and I get this:
[{"id":121,"price":67,"start":"Sat, 23 Apr 2016 00:00:00 +0000","user_id":8},{"id":114,"price":45,"start":"Sun, 08 May 2016 00:00:00 +0000","user_id":9},{"id":113,"price":53,"start":"Sun, 24 Apr 2016 00:00:00 +0000","user_id":8},{"id":111,"price":55,"start":"Wed, 01 Jun 2016 00:00:00 +0000","user_id":11},{"id":110,"price":53,"start":"Fri, 03 Jun 2016 00:00:00 +0000","user_id":8},{"id":107,"price":53,"start":"Wed, 03 Aug 2016 00:00:00 +0000","user_id":8},{"id":106,"price":53,"start":"Mon, 01 Aug 2016 00:00:00 +0000","user_id":8},{"id":105,"price":53,"start":"Tue, 16 Aug 2016 00:00:00 +0000","user_id":8},{"id":104,"price":55,"start":"Thu, 21 Apr 2016 00:00:00 +0000","user_id":11},{"id":101,"price":57,"start":"Wed, 17 Aug 2016 00:00:00 +0000","user_id":8}]
Now I have also:
$start = 'Sun, 03 Apr 2016 00:00:00';
$end = 'Sat, 23 Sep 2016 00:00:01';
I need to go through $maxoffers from $start date to $end date day by day. If there is no date for that day, I need to add a new object into $maxoffers with the following data:
{"title":,"price":100,"start":"DATE_WHICH_NOT_EXCIST INTO_OFFERS","user_id":8}
So how I can go through $maxoffers and if there is not some date in period from $start to $end then to add new data to result?
UPDATE:
I try:
public function maxoffers($id)
{
$start_date = ;
$end_date = ;
$offers = Maxoffer::where('article_id', $id)
->where('start', '>=', $start_date)
->where('start', '<=', $end_date)
->get(['id', 'price', 'start', 'user_id']);
$start_date = 'Sun, 03 Apr 2016 00:00:00';
$end_date = 'Sat, 23 Sep 2016 00:00:00';
while (strtotime($start_date) <= strtotime($end_date)) {
$start_date = date ("Y-m-d", strtotime("+1 day", strtotime($start_date)));
$count = 0;
foreach($offers as $offer) {
if(strtotime($offer->start) == strtotime($start_date)) {
$count++;
}
}
if($count == 0) {
Maxoffer::create(['title' => null, 'price' => '100', 'start' => $start_date, 'user_id' => 8 ]);
}
}
// do some code to update $offers variable before you return it
return $offers;
}
but give me this error:

It is ver simple. YOu just need to use Carbon for date manipulation.
$offers = []; //for example I am using an empty array
$start_date = \Carbon\Carbon::parse('Sun, 03 Apr 2016 00:00:00');
$end_date = \Carbon\Carbon::parse('Sat, 23 Sep 2016 00:00:00');
while(!$start_date->eq($end_date))
{
$flag = true;
foreach ($offers as $offer)
{
if ($offer['start'] == $start_date->toRfc2822String())
{
$flag = false;
break;
}
}
if($flag)
{
$temp = [];
$temp['title'] = "Title ";
$temp['price'] = "100";
$temp['start'] = $start_date->toDateString();
$temp['user_id'] = 8;
array_push($offers,$temp);
}
$start_date->addDay();
}
Here Just Pass the valid format of date for $start_date and $end_date. In your case it is valid so no problem there. Now use eq() method for date comparison and add one day for every iteration. I used $temp as an example. You can define this array's values and keys as you want. Since you are not using collection you need to iterate to each element in array to see if that date exists or not.

Related

Given start date get all the months name until current month?

Given start date how to get all the months until current month?
For eg. If given date is 1st Jan 2019
output should be:
Jan 2019
Feb 2019
Mar 2019
Apr 2019
May 2019
Jun 2019
Jul 2019
Aug 2019
Sep 2019
Oct 2019
Nov 2019
Dec 2019
Jan 2020
Feb 2020
Mar 2020
Solved it with slightly different approach. Thank you all for hints and answers.
<?php
$startTime = strtotime("1 January 2019");
$startYear = date("Y", $startTime);
$currentYear = date("Y");
$yearDiff = $currentYear - $startYear;
$currentMonth = date("m", time());
for($i=0; $i < intval($currentMonth) + ($yearDiff * 12) ; $i++)
{
$t = strtotime("+". $i . " months", $startTime);
$monthName = date("M", $t) ." ". date('Y', $t);
echo $monthName . "<br/>\n";
}
?>
here you go , hope this work
$start = new DateTime('2019-01-01');
$end = new DateTime('2020-03-02');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("F Y") . "<br>\n";
}

datetime: split a month 10-day periods

I send a earlier date and it returns me the periods between the earlier date and today cut by tens of days.
Example with 14/01/2016
I need the result to be exactly as below:
11 Jan 2016 to 20 Jan 2016
21 Jan 2016 to 31 Jan 2016
01 Feb 2016 to 10 Feb 2016
11 Feb 2016 to 20 Feb 2016
21 Feb 2016 to 29 Feb 2016
01 Mar 2016 to 10 Mar 2016
11 Mar 2016 to 20 Mar 2016
21 Mar 2016 to 31 Mar 2016
01 Apr 2016 to 10 Apr 2016
11 Apr 2016 to 20 Apr 2016
Here my code:
function date_interval($startTime = false){
if( ! $startTime){
return array();
} else {
if(date('d',$startTime) < 10){
$actual = mktime(0, 0, 0, date('m',$startTime), 1, date('Y',$startTime));
} elseif(date('d',$startTime) < 20){
$actual = mktime(0, 0, 0, date('m',$startTime), 10, date('Y',$startTime));
} else {
$actual = mktime(0, 0, 0, date('m',$startTime), 20, date('Y',$startTime));
}
if(date('d',time()) < 10) {
$target = mktime(0, 0, 0, date('m',time()), 10, date('Y',time()));
} elseif(date('d',time()) < 20) {
$target = mktime(0, 0, 0, date('m',time()), 20, date('Y',time()));
} else {
$target = mktime(0, 0, 0, date('m',time())+1, 1, date('Y',time()));
}
$current = $actual;
$last = $actual;
while($current < $target) {
if(date('d',$current) < 10){
$current = mktime(0, 0, 0, date('m',$current), 10, date('Y',$current));
} elseif(date('d',$current) < 20){
$current = mktime(0, 0, 0, date('m',$current), 20, date('Y',$current));
} else {
$current = mktime(0, 0, 0, date('m',$current)+1, 1, date('Y',$current));
}
$dateTime[date("Y-m-d", $last) .'~'. date("Y-m-d", $current)] = date('d M Y',$last) . ' - ' . date('d M Y',$current));
$last = $current;
}
}
return $dateTime;
}
Datetime is the darling class from php that solves this type of problem nicely.
Here you feed the startdate to the function as DATETIME object and the function throws back a stack of list tags.
In the loop startDay is beeing modyfied first by adding 10 days to make the jump and then by one to avoid the overlap.
If you want a final line with the (less then ten days) time period from last startDay till today you can add something like:
$return .= '<li>From '.$startDay->format('d M Y').' to '.$today->format('d M Y').'</li>';
after the loop
function date_interval(DATETIME $startDay = NULL)
{
if( NULL == $startDay){
return array(); }
$return = '';
$today = new DATETIME('now');
while( $today->diff( $startDay )->format('%a%') > 10 )
{
$return .= '<li>From '.$startDay->format('d M Y').' to ';
$startDay->modify('+10 days');
$return .= $startDay->format('d M Y').'</li>
';
$startDay->modify('+1 day');
}
return $return;
}
I altered the above more general solution to do exactly what you describe:
<?php
function date_interval(DATETIME $startDay = NULL)
{
if( NULL == $startDay){
return array(); }
$return = '';
$today = new DATETIME('now');
$startMonth = new DateTime('first day of '.$startDay->format('M Y') );
$firstRun = TRUE;
while( $today > $startDay )
{
$return .= '<li>From '.$startDay->format('d M Y').' to ';
if( $firstRun == TRUE ){
if( (int)$startDay->format('d') > 10 )
$startMonth->modify('+10 days');
if( (int)$startDay->format('d') > 20 )
$startMonth->modify('+10 days');
$startDay = $startMonth;
$firstRun = FALSE;
}
$lastOfMonth = new DateTime('last day of '.$startDay->format('M Y') );
if( $lastOfMonth->diff( $startDay )->format('%a%') > 10 )
$startDay->modify('+9 days');
else
$startDay = $lastOfMonth;
$return .= $startDay->format('d M Y').'</li>
';
$startDay->modify('+1 day');
}
return $return;
}
echo date_interval( date_create_from_format('Y-m-d','2016-01-21') )."\n";
?>
See this function using DateTime:
function date_interval( $start = Null )
{
if( !$start ) return array();
$cur = new DateTime( sprintf( '%s-%02d', $start->format('Y-m'), [1,11,21,21][ floor(($start->format('j')-1)/10) ] ) );
$end = new DateTime();
$retval = [];
while( $cur <= $end )
{
$key = $cur->format( 'Y-m-d~' );
$val = $cur->format( 'd M Y - ' );
if( $cur->format( 'j' ) > 20 ) $cur->modify( 'last day of this month' );
else $cur->modify( '+ 9 days' );
$retval[ $key.$cur->format( 'Y-m-d' ) ] = $val.$cur->format( 'd M Y' );
$cur->modify( '+ 1 days' );
}
return $retval;
}
Calling it in this way:
$startDate = '14/01/2016';
$array = date_interval( DateTime::createFromFormat( 'd/m/Y', $startDate ) );
print_r( $array );
According with your keys/values schema, the resulting array is:
Array
(
[2016-01-11~2016-01-20] => 11 Jan 2016 - 20 Jan 2016
[2016-01-21~2016-01-31] => 21 Jan 2016 - 31 Jan 2016
[2016-02-01~2016-02-10] => 01 Feb 2016 - 10 Feb 2016
[2016-02-11~2016-02-20] => 11 Feb 2016 - 20 Feb 2016
[2016-02-21~2016-02-29] => 21 Feb 2016 - 29 Feb 2016
[2016-03-01~2016-03-10] => 01 Mar 2016 - 10 Mar 2016
[2016-03-11~2016-03-20] => 11 Mar 2016 - 20 Mar 2016
[2016-03-21~2016-03-31] => 21 Mar 2016 - 31 Mar 2016
[2016-04-01~2016-04-10] => 01 Apr 2016 - 10 Apr 2016
[2016-04-11~2016-04-20] => 11 Apr 2016 - 20 Apr 2016
[2016-04-21~2016-04-30] => 21 Apr 2016 - 30 Apr 2016
)
We operate only on one date ($cur), initially created from passed argument; we set the day of month using array [1,11,21,21] and selecting key by the rounded down division by 10 of original day (in your example, (14-1)/10 = 1.3, rounded as 1, that is 11 in [1,11,21,21] array). This is a quick way to resolve the 31th day exception.
Then we perform a loop until $cur date is greater than today date: we create starting part of key and value, we modify $cur adding it nine days or selecting last month's day, we create complete key and value of returned array. At the end of each loop, we increment $cur by 1 day.

PHP Put a Date Stamp and a Time Stamp together

I got two different timestamps in milliseconds. One is for the chosen DATE. One for the chosen time. I need now to send this to an API and I have to put the DATE and the TIME together. How can I achieve this?
$time = $request -> newTime1; //newTime1 is 1452800524000 which is: Thu Jan 14 2016 20:42:04 GMT+0100 (CET)
$datum = $request -> newDate1; //newDate1 is 1453676400000 which is: Mon Jan 25 2016 00:00:00 GMT+0100 (CET)
$dateformatted = strtotime($datum);
$timeformatted = date ("H:i:s",strtotime($time));
$combinedDT = strtotime("$dateformatted $timeformatted");
$event_start = $combinedDT;
$event_end = $event_start + 3600;
//I want 25.1.2016 20:42
<?php
date_default_timezone_set('CET');
$time = 'Thu Jan 14 2016 20:42:04 GMT+0100 (CET)';
$datum = 'Mon Jan 25 2016 00:00:00 GMT+0100 (CET)';
$t = strtotime($time);
$d = strtotime($datum);
$combined = strftime('%d.', $d) . intval(strftime('%m', $d)) . strftime('.%Y', $d)
. strftime(' %H:%M', $t);
echo $combined;
output
25.1.2016 20:42
I think the main problem is that the time input is multiplied by 100 (not in seconds).
After you solve it the most simple way is too use two date functions
$time = 14528005240;
$datum = 1453676400;
echo $date = date('d.m.Y',$datum).' '.date('H:i',$time);

How to show the past 24 months from now?

I need to write a simple loop routine to show 24 months back starting with today's month. How would I do that?
$start = date(M) - 24;
$end = date(M);
foreach() {
echo ''; // Dec, Jan...
}
Something like this should work:
for($i = 1; $i <= 24; $i++) {
echo date("M", strtotime("-$i months")) . "\n";
}
Result
Feb
Jan
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
Feb
Jan
Dec
Nov
Oct
Sep
Aug
Jul
Jun
May
Apr
Mar
See a demo
for ($i = 1; $i <= 24; $i++) {
$months[] = date("Y-m%", strtotime( date( 'Y-m-01' )." -$i months"));
}
or
for full textual representation of month you need to pass "F":
echo date("y:F:d");
for previous month you can use
echo date("y:F:d",strtotime("-24 Months"))

php strtotime() function returns blank/0

I have datetime data in string format like this:
Sat Mar 24 23:59:59 GMT 2012
I want to convert this into a UTC timestamp, but when I try it as follows:
function texttotime($texttime)
{
if(!$texttime || $texttime=="")
return NULL;
// Sat Mar 24 23:59:59 GMT 2012
$bits = preg_split('/\s/', $texttime);
// Mar 24 2012 23:59:59 GMT
return strtotime("$bits[1] $bits[2] $bits[5] $bits[3] bits[4]");
}
It outputs 0 (not NULL).
If I change the last line to:
// Mar 24 2012 23:59:59
return strtotime("$bits[1] $bits[2] $bits[5] $bits[3]");
It outputs something (but the wrong timestamp, off by -4 hours or so).
Not quite sure why you're re-organising the existing string, as...
echo $timestamp = strtotime('Sat Mar 24 23:59:59 GMT 2012');
...works correctly. (It returns 1332633599, which you can check via date('r', 1332633599); (This will result in "Sat, 24 Mar 2012 23:59:59 +0000", so all is well.)
That said, if you're going to extract all of the components of the string, you might as well use mktime. For example:
function texttotime($texttime) {
if(!$texttime || $texttime=="") return NULL;
list($junk, $month, $day, $time, $timezone, $year) = explode(' ', $texttime);
list($hour, $minute, $second) = explode(':', $time);
return mktime($hour, $minute, $second, $month, $day, $year);
}
The reason you have 4 hour difference is caused by server timezone which is -4 hours from GMT.
try to define your current timezone like this:
date_default_timezone_set('Europe/London');
$result = strtotime('Sat Mar 24 23:59:59 GMT 2012');
echo date('r', $result);//Sat, 24 Mar 2012 23:59:59 +0000

Categories