Check if any date is older than 5 years - laravel

I am trying to figure out the best way to achieve something. I am looping through some data that involves a group of dates
foreach ($fields['dates'] as $key => $dates) {
$fields['dates'][$key]['datestring'] = Carbon::createFromFormat(
'dmY',
$dates['datestring']
);
var_dump($fields['dates'][$key]['datestring']);
}
The var_dump above produces something like the following
object(Carbon\Carbon)#330 (3) { ["date"]=> string(26) "2019-08-08 12:41:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" } object(Carbon\Carbon)#328 (3) { ["date"]=> string(26) "1987-08-08 12:41:00.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(3) "UTC" }
So above this, I have created a variable to identify whether at least one of the dates is more than 5 years ago. I have also created a date object for today.
$moreThanFiveYears = false;
$now = Carbon::now();
Now what I am trying to figure out is how I perform the actual check? When I try the above, it complains because $now is not the same format as my other dates. I have tried adding a format to it, but it produces only something like 20190219 and not the additional data the original dates produce.
So how can I loop all my dates to ensure at least one is greater than 5 years?
Thanks

get five years ago by subYears() and compare them by greaterThan().
$fiveYearsAgo = Carbon::now()->subYears(5);
foreach ($fields['dates'] as $key => $dates) {
$fields['dates'][$key]['datestring'] = Carbon::createFromFormat(
'dmY',
$dates['datestring']
);
if ($fields['dates'][$key]['datestring']->greaterThan($fiveYearsAgo)) {
$moreThanFiveYears = false;
}
}

Try out this.
<?
$check_date = '2019-12-18 18:20:40';
if(strtotime($check_date) < strtotime('-5 year')){
echo "YES";
}else{
echo "NO";
}
?>

Since you are using Carbon, you can make use of the difference methods, which allow you to easily calculate the difference between two dates, in any unit:
diffInSeconds()
diffInMinutes()
diffInHours()
diffInDays()
diffInYears()
# existing date
$old = Carbon::parse("2010-01-20 12:00:00");
# current date
$now = Carbon::now();
# find the difference
$diff = $old->diffInYears($now);
# test your difference
if($diff > 5) {
echo "date is older than 5 years";
}
Note: since you are calculating difference, the order of the comparables does not matter - the answer would be the same in both cases:
$diff = $old->diffInYears($now);
$diff = $new->diffInYears($old);

Related

Laravel search system based on input values

I have a search form with 4 inputs such as username, text, fromDate, toDate, and users can search with just one field , the problem is i don't know how to build a query with inputs which have values, I can compare them if each one of them has value or not like this :
if ($request->input('fromdatepicker') && $request->input('todatepicker') && $request->input('search-text')){
$query = \App\InstaPost::WhereFullTextWithTimestamp($request->input('search-text'), $from_timestamp, $to_timestamp)->paginate(12);
}else if ($request->input('search-text') && empty($request->input('fromdatepicker')) && empty($request->input('todatepicker'))){
$query = \App\InstaPost::WhereFullText($request->input('search-text'))->paginate(12);
} else if(empty($request->input('search-text')) && $request->input('fromdatepicker') && $request->input('todatepicker')){
$query = InstaPost::WhereTimestamp($from_timestamp, $to_timestamp)->paginate(12);
}
i have different scenarios:
as you can see so many scenarios,
but as you know it'll be a huge mess ! these if's is just for 3 inputs! and i should compare them for each scenarios , hope you understand the problem and help me.
I'm using Laravel-Mongodb(jessengers) and i should find out which input has value and then make a query and add them to this code block :
public function scopeWhereFullTextWithTimestamp($query,$search,$from_timestamp , $to_timestamp)
{
$query->getQuery()->projections = ['score'=>['$meta'=>'textScore']];
$query->orderBy('post.taken_at_timestamp','DESC');
return $query->whereRaw([
'$text' => ['$search' => $search],
'post.taken_at_timestamp'=> [
'$gte' => $from_timestamp,
'$lte' => $to_timestamp
]
]);
this is for search-text , fromDate and toDate inputs,
You can concatenate queries based on the input, something in this direction should do the trick.
$base_query = App\InstaPost;
if(!is_null($request->input('search-text'))){
$base_query->WhereFullText($request->input('search-text'));
}
if...
if..
$result = $base_query->get(); //or paginate()

How to get last 7 days records with 0 counts

I have an eloquent query that gets the total count records (created_at) of the last 7 days. But the problem is if one of these days have 0 records, this doesn't appear in the final data.
My query:
$data = Data::whereBetween('created_at', [Carbon::now()->subDays(6)->format('Y-m-d')." 00:00:00", Carbon::now()->format('Y-m-d')." 23:59:59"])
->groupBy('date')
->orderBy('date')
->get([
DB::raw('DATE(created_at) as date'),
DB::raw('count(*) as total')
])
->pluck('total', 'date')->toArray();
What I get:
[
"2020-04-14" => 1
"2020-04-16" => 1
"2020-04-18" => 1
"2020-04-19" => 1
]
What I expected:
[
"2020-04-14" => 1
"2020-04-15" => 0
"2020-04-16" => 1
"2020-04-17" => 0
"2020-04-18" => 1
"2020-04-19" => 1
"2020-04-20" => 0
]
Any suggestions?
SOLUTION:
-Based on Gary Houbre's proposal:
$results = Data::whereBetween('created_at', [Carbon::now()->subDays(6)->format('Y-m-d')." 00:00:00", Carbon::now()->format('Y-m-d')." 23:59:59"])
->groupBy('date')
->orderBy('date')
->get([
DB::raw('DATE_FORMAT(created_at, "%Y-%m-%d") as date'),
DB::raw('count(*) as total')
])
->keyBy('date')
->map(function ($item) {
$item->date = Carbon::parse($item->date);
return $item;
});
$period = new DatePeriod(Carbon::now()->subDays(6), CarbonInterval::day(), Carbon::now()->addDay());
$graph = array_map(function ($datePeriod) use ($results) {
$date = $datePeriod->format('Y-m-d');
return $results->has($date) ? $results->get($date)->total : 0;
}, iterator_to_array($period));
Looking directly Sql : How to include "zero" / "0" results in COUNT aggregate?
Into a same table : How to get the record if Count is zero in Laravel
You need to add an outer join into your request with Eloquent.
My idea is to create a for loop to check the days.
If there is no record on a date then print 0
Loop Iteration:
Catch the first Day (Suppose 14)
Catch the last Day
Then check in every iteration it is greater than one or many
Thus, I hope you will get normally.
We had a similar problem while trying to put back-end data into the chart. Since some of the days were missing it didn't look well. Our solution was;
Create a function like this;
public function generateDates(Date $startDate, Date $endDate, $format = 'Y/m/d'): Collection
{
$dates = collect();
$startDate = $startDate->copy();
for ($date = $startDate; $date->lte($endDate); $date->addDay()) {
$dates->put($date->format($format), 0);
}
return $dates;
}
In your case it's going to be (today and today - six days) and you will union returning collection with your query collection. What it does is; it create a date range from the keys and fill them with zero. When your query collection has some value other than zero - it is going to overwrite it.

Display total days between two dates if status is completed

I am trying to count the number of days between two dates the carbon::now and $start_date and when the status == complete the counting of days stops then get the total number of days.
if ($this->status === 'COMPLETED') {
$now = Carbon::now();
$start_date = Carbon::createFromFormat('Y-m-d', $this->start_date);
$this->start_date_to_current_date = $start_date->diffInDays($now, true);
}
But the problem is, the days still continues to count even the status is completed like for example the total days is 3 then in the next day it becomes 4 then ive tried doing this:
if ($this->status == null && $this->status === 'COMPLETED') {
$now = Carbon::now();
$start_date = Carbon::createFromFormat('Y-m-d', $this->start_date);
$this->start_date_to_current_date = $start_date->diffInDays($now, true);
}
But the value becomes zero. why is that ? :/
You need to log the complete date somewhere, and use it instead of now().
For instance:
if ($this->status === 'COMPLETED') {
$start_date = Carbon::createFromFormat('Y-m-d', $this->start_date);
$start_date->diffInDays($this->completed_date); // completed_date should come from db.
}
The problem here is that you're using the current date as complete date which is obviously changing everyday, hence you get different result each day.
let it only do that when you not yet, and do not repeat do it.
`if ($this->status == null && $this->status !== 'COMPLETED') {`
`$now = Carbon::now();`
`$start_date = Carbon::createFromFormat('Y-m-d', $this->start_date);`
`$this->start_date_to_current_date = $start_date->diffInDays($now, true);`
}

Laravel carbon retrieve record even when it shouldn't

I am searching by start and end date or with a weekday, which kind of works fine however if weekday is equal to 'WE' and today's weekday is equal to 'WE' it still brings back results even when $today date is < than endate.
public function show($id)
{
$weekMap = [
0 => 'SU',
1 => 'MO',
2 => 'TU',
3 => 'WE',
4 => 'TH',
5 => 'FR',
6 => 'SA',
];
$todayWeek = Carbon::now()->dayOfWeek;
$today= Carbon::now();
$weekday = $weekMap[$todayWeek];
$event = Event::with('businesses')
->where('startdate', '<', $today->format('Y-m-d'))
->where('endate', '>', $today->format('Y-m-d'))
->orWhere('weekday', '=', $weekday)
->get();
dd($event);
return view('events.showEvent', compact('event'));
}
If I change orWhere to where, results are all good, however user not always enters a weekday so it can be empty. I want it to work like this:
output everything where startdate < today and where endate > today and if weekday is not empty, output everything where startdate < today, endate > today and weekday = $weekday. I hope that makes sense.
//edit
sample data:
data
So what I want is really search by frequency so it would look like this:
if frequency = daily
compare start and end with today's date.
if frequency = weekly
compare start and end with today's date and weekday.
bring back all results for frequency = daily+weekly
you can use if condition in query like this:
$query = Event::with('businesses')
->where('startdate', '<', $today->format('Y-m-d'))
->where('endate', '>', $today->format('Y-m-d'));
if ($weekday != '') {
$query->where('weekday', $weekday);
}
$event = $query->get();
also
condition if ($weekday != '') check $weekday isset or not you can use
if ( ! is_null($weekday )) instead

how to get all products between two dates?

how to get all products between two dates like last month products, this month products , last week products and this week products etc.
i tried with this:
// current day to start with
$start = mktime(0,0,0,date('m'), date('d'), date('Y'));;
// calculate the first day of last month
$first = date('YYYY-MM-DD',mktime(0,0,0,date('m',$start) - 1,1,date('Y',$start)));
// calculate the last day of last month
$last = date('YYYY-MM-DD',mktime(0, 0, 0, date('m') -1 + 1, 0, date('Y',$start)));
if($filter == "lastmonth"){
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('updated_at', array('gteq' =>$first));
$collection->addAttributeToFilter('updated_at', array('lteq' => $last));
}
but i am not able to get the result :( any help ?
Modified after Daniel response !
1) First of all you need to change you date formate from 'YYYY-MM-DD' to 'Y-m-d'. This will return a date formate which magento records have.
2) There is a special condition for date as bellow mention with your example.
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('updated_at', array('gteq' =>$first));
$collection->addAttributeToFilter('updated_at', array('lteq' => $last));
To.
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('updated_at', array(
'from' => $first,
'to' => $last,
'date' => true,
));
I tried your code and had to swap 'lteq' and 'gteq' to make it work. The $fromdate is the lower number so you are searching for dates greater than that number.
Also you must remember to format the dates as MySQL likes it; date('Y-m-d').
PS. See the comparison operators for a full list
There is one issue with your code:
$collection->addFieldToFilter()
should be:
$collection->addAttributeToFilter()
I know that the question is little bit old but as it is quite well ranked in search engine results, I will correct the date() function that better take as arguments something like : Y-m-d H:i:s.
I hope it will help !

Resources