For Chart - Trying to Get data for last 30 days and add "0" if data is not available in particular date - laravel

I am trying to draw chart for Last 30 days from Today showing total milk quantity. I get last 30 days using - [0 => "2022-02-07" ----- 30 => "2022-03-09"]
$olddate = Carbon::today()->subDays(30)->toDateString();
$todaydate = Carbon::today()->toDateString();
Also get the Data for Database as below [ date" => "2022-03-01" "totalmilk" => "24.10" "daykey" => "01"................."date" => "2022-02-16" "totalmilk" => "22.90" "daykey" => "16"]
$rahul = Buffalomilkrecord::select(DB::raw('date'), DB::raw('sum(totalmilk) as totalmilk, DATE_FORMAT(date,"%d") as "daykey"'))
->whereBetween('date', [$olddate, $todaydate] )
->groupBy(DB::raw('date'))
->orderBy('date', 'desc')
->get();
BY Below code, trying to put "0" if data is not Available
$ddtest = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
foreach($rahul as $order)
{
$ddtest[$order->daykey-1] = $order->date;
}
The code is working fine except the start date he is taking the database date which is (2022-03-01) where it should start with "2022-02-07".
I think i am making mistake while getting "daykey". It is assigning daykey "1" to first data available in database which start from date ""2022-03-01" (as No data available from 07-02-2022 to 28-02-2022 in the database and it start from 1 March 2022.) where as it should start from "$olddate" that is ""2022-02-07"..
where did i am making the mistake.....Thanks in Advance

Related

Trying to get Values between 2 dates but need start date and end date should be as given instead of as per database

I am trying to get data between "Start" and "End" dates from database which is working fine and query giving me the result, Say
Start = 09-02-2022.
End = 10-03-2022.
Database values start = "01-03-2022 to 09-03-2022" so i am getting result from date say 16-02 to 01-03.
But i want result should start with 09-02 and end with 10-03. If value is not present in database then it should give as "0"
Check attached Image for reference.
Code for Getting dates for last 30 days -
$getalldates = array();
for($d = (Carbon::today()->subDays(30)); $d->lte(carbon::today()); $d->addDay())
{ $getalldates[] = $d->format('Y-m-d');}
Code for Getting data from database
$rahul = Buffalomilkrecord::select(DB::raw('date'), DB::raw('sum(totalmilk) as totalmilk, DATE_FORMAT(date,"%d") as "daykey"'))
->whereBetween('date', [$olddate, $todaydate] )
->groupBy(DB::raw('date'))
->orderBy('date','asc')
->get()->pluck('date')->toArray();
Thanks in Advance.
This is what i tried
$result = array();
foreach($getalldates as $date){
$totalmilk= Buffalomilkrecord::select(DB::raw('sum(totalmilk) as totalmilk'))->whereDate('date',$date)->pluck('totalmilk');
if($totalmilk){
$result[] = array($date =>$totalmilk);
} else {
$result[] = array($date =>0);
}
}
I am expecting
This is my output 0 => array:1 [▼ "2022-02-09" => Illuminate\Support\Collection {#348 ▼ #items: array:1 [▼ 0 => null ] }
and i am expecting "2022-02-09" = "0"
Check Image

Very strange error with Carbon and Laravel

I'm using Laravel for one of my project. Everything is just fine, but I can't solve a strange error.
I'm sending duration in years from my front end (Vuejs).
If client is on any active plan then plan start should be the current plan end date else set to now().
Add years in start time and set as plan end.
Now when I do this in actual code, I see same start and end date generated according to plan end.
$start = Carbon::parse($client->plan_end) ?: Carbon::now();
$end = $start->addYears($request->planDetails['duration']);
return response([
'start' => $start,
'end' => $end,
]);
This is plan_end timestamp in database -- 2022-05-09 09:15:19
This is response I receive.
{
"start" : "2024-05-09T07:15:19.000000Z",
"end" : "2024-05-09T07:15:19.000000Z"
}
So carbon is mutable which means that when you do ->addYears() it will alter the original start date time. You can use the ->copy() function before adding the years so it would look like this.
$end = $start->copy()->addYears($request->planDetails['duration']);
Using ->copy() is fine, but using CarbonImmutable as default is likely better as it will avoid similar pain to happen again:
$start = CarbonImmutable::parse($client->plan_end) ?: CarbonImmutable::now();
$end = $start->addYears($request->planDetails['duration']);
return response([
'start' => $start,
'end' => $end,
]);

How to get difference bettwen 2 dates in weeks with Carbon

In laravel 6 app I want to get difference bettwen 2 dates in weeks: if dates break a week get value > 0
I see diffInWeeks method written here : https://carbon.nesbot.com/docs/#api-week
Having 2 dates I make :
$startDate = Carbon::createFromTimestamp(strtotime($eventItem['at_time']));//->format($date_format);
\Log::info('$startDate ::');
\Log::info(print_r($startDate, true));
$offset_x= $startDate->dayOfWeek;
$endDate = $startDate->add($eventItem['duration'] . ' minutes');
\Log::info('-1 $endDate::' . print_r($endDate, true));
$diff_in_weeks= $startDate->diffInWeeks($endDate);
\Log::info('-3 $diff_in_weeks ::' . print_r($diff_in_weeks, true));
In logs :
[2020-04-20 06:16:56] local.INFO: $startDate ::
[2020-04-20 06:16:56] local.INFO: Carbon\Carbon Object
(
[date] => 2018-02-01 09:08:39.000000
[timezone_type] => 3
[timezone] => UTC
)
[2020-04-20 06:16:56] local.INFO: -1 $endDate::Carbon\Carbon Object
(
[date] => 2018-02-22 04:28:39.000000
[timezone_type] => 3
[timezone] => UTC
)
[2020-04-20 06:16:56] local.INFO: -3 $diff_in_weeks ::0
But in output above I see that with 21 days difference $diff_in_weeks == 0
I tried to replace dates:
$diff_in_weeks= $endDate->diffInWeeks($startDate);
and got 0 anyway...
Which is the valid way ?
Thanks!
Since a week is 7 days, so instead you can use Carbon's diffInDays() method (to see how many days are in the period) and divide the result by 7, then you can cast it to int
update:
it's as 'Mohammad Hosseini' said, so to avoid changing the original value you can use CarbonImmutable in your class like so:
use Carbon\CarbonImmutable;
instead of using:
use Carbon\Carbon;
and you won't have to change anything in your code
Because when you use $endDate = $startDate->add($eventItem['duration'] . ' minutes');
The start date ($startDate) also changes its value, and from that line, the start date has a new value, and in fact the start date is equal to the end date. So your solution is:
$startDate = Carbon::createFromTimestamp(strtotime($eventItem['at_time']));
$endDate = Carbon::createFromTimestamp(strtotime($eventItem['at_time']))->add($eventItem['duration'] . ' minutes');
$diff_in_weeks= $startDate->diffInWeeks($endDate);

Get the last and the previous "gold_id" of the previous day with mongo

I have this kind of data :
{"_id"=>BSON::ObjectId('560b5c5d80ec9700030035dc'), "active"=>true, "user_id"=>nil, "action"=>"connection", "shop_id"=>245929, "gold_id"=>23452349, "indexed"=>true, "created_at"=>2015-09-30 03:51:57 UTC}
I'm trying to get the first and last gold_id of the previous day. I'm getting arroung 10_000 logs per days.
I'm using the ruby driver
first_gold_in = Time.utc(Date.today.year, Date.today.month, (Date.today.day - 1), 00, 00)
first_gold_out = yesterday_o_clock + 5*60
first_gold_id = logs
.find("action" => "connection", "created_at" => {"$gte" => first_gold_in, "$lte" => first_gold_out} )
.first
.fetch("gold_id")
last_gold_in = Time.utc(Date.today.year, Date.today.month, (Date.today.day - 1), 23, 55)
last_gold_out = yesterday_o_clock + 5*60 - 1
last_gold_id = logs
.find("action" => "connection", "created_at" => {"$gte" => last_gold_in, "$lte" => last_gold_out} )
.first
.fetch("gold_id")
But It's very slow even with shorter date range. Is there a better way to do it?
Also is is possible to get the first and the last of the day in the same request?
Thanks

Using the betweenDate operation filter for the SoftLayer Ruby API includes values beyond my endDate

I'm trying to retrieve the invoices for a single month (beginning of one month and ending at the beginning of the next month). However, I get results for the first day of the ending month in my result set, which I'm not expecting.
Example, this will return invoices for December 1st:
account = SoftLayer::Service.new("...")
billing_invoice_service = softlayer_client.service_named("Billing_Invoice");
object_filter = SoftLayer::ObjectFilter.new
object_filter.set_criteria_for_key_path('invoices.createDate',
'operation' => 'betweenDate',
'options' => [{
'name' => 'startDate',
'value' => ["11/01/2015 00:00:00"]
},
{
'name' => 'endDate',
'value' => ["12/01/2015 00:00:00"]
}
]
)
invoices = account.result_limit(0,5000).object_filter(object_filter).object_mask("mask[id,closedDate,createDate]").getInvoices
If I run with the below filter I get no results for December 1st:
account = SoftLayer::Service.new("...")
billing_invoice_service = softlayer_client.service_named("Billing_Invoice");
object_filter = SoftLayer::ObjectFilter.new
object_filter.set_criteria_for_key_path('invoices.createDate',
'operation' => 'betweenDate',
'options' => [{
'name' => 'startDate',
'value' => ["12/01/2015 00:00:00"]
},
{
'name' => 'endDate',
'value' => ["12/01/2015 00:00:00"]
}
]
)
invoices = account.result_limit(0,5000).object_filter(object_filter).object_mask("mask[id,closedDate,createDate]").getInvoices
So I'm not sure why I get results for December 1st in my first filter when I specify an ending time of 00:00:00. Thank you.
Edit: Here is a tail of the results from the first filter above (minus the id):
...
{"closedDate"=>"2015-11-30T21:52:17+05:30",
"createDate"=>"2015-11-30T21:52:16+05:30"},
{"closedDate"=>"2015-11-30T23:22:14+05:30",
"createDate"=>"2015-11-30T23:22:13+05:30"},
{"closedDate"=>"2015-12-01T01:43:59+05:30",
"createDate"=>"2015-12-01T01:43:56+05:30"},
{"closedDate"=>"2015-12-01T01:45:36+05:30",
"createDate"=>"2015-12-01T01:45:34+05:30"},
{"closedDate"=>"2015-12-01T02:05:20+05:30",
"createDate"=>"2015-12-01T02:05:16+05:30"},
{"closedDate"=>"2015-12-01T02:12:22+05:30",
"createDate"=>"2015-12-01T02:12:22+05:30"},
{"closedDate"=>"2015-12-01T02:13:06+05:30",
"createDate"=>"2015-12-01T02:13:04+05:30"},
{"closedDate"=>"2015-12-01T02:13:07+05:30",
"createDate"=>"2015-12-01T02:13:04+05:30"},
{"closedDate"=>"2015-12-01T02:13:07+05:30",
"createDate"=>"2015-12-01T02:13:05+05:30"},
{"closedDate"=>"2015-12-01T02:13:08+05:30",
"createDate"=>"2015-12-01T02:13:06+05:30"},
{"closedDate"=>"2015-12-01T02:13:07+05:30",
"createDate"=>"2015-12-01T02:13:06+05:30"},
{"closedDate"=>"2015-12-01T02:21:34+05:30",
"createDate"=>"2015-12-01T02:21:32+05:30"},
{"closedDate"=>"2015-12-01T02:38:12+05:30",
"createDate"=>"2015-12-01T02:38:10+05:30"},
{"closedDate"=>"2015-12-01T03:36:07+05:30",
"createDate"=>"2015-12-01T03:36:06+05:30"},
{"closedDate"=>"2015-12-01T04:09:57+05:30",
"createDate"=>"2015-12-01T04:09:55+05:30"},
{"closedDate"=>"2015-12-01T04:37:45+05:30",
"createDate"=>"2015-12-01T04:37:43+05:30"},
{"closedDate"=>"2015-12-01T06:35:34+05:30",
"createDate"=>"2015-12-01T06:35:33+05:30"},
{"closedDate"=>"2015-12-01T07:00:09+05:30",
"createDate"=>"2015-12-01T07:00:06+05:30"},
{"closedDate"=>"2015-12-01T08:00:32+05:30",
"createDate"=>"2015-12-01T08:00:30+05:30"}]
The error might be due to the timezone, the filter does not take in account your current timezone, it only filters the data stored in the database, when the data is displayed it is converted to your current timezone. I suggest you change your end date value considering the timezone difference between the stored data in softlayer and your current timezone

Resources