carbon start of week sunday and endOfWeek Saturday not working - laravel

I need to select a particular users weekly top score. I am using Carbon and I forced Carbon startofWeek to SUNDAY and endOfWeek to SATURDAY.
Here is my DB data
id user_id score created_at updated_at
43 33 88 2020-02-23 00:00:00 NULL
44 33 15 2020-02-24 00:00:00 NULL
45 33 42 2020-02-24 00:00:00 NULL
46 33 86 2020-02-25 00:00:00 NULL
47 33 100 2020-02-04 00:00:00 NULL
Here is my code
$week = GameScore::select(max('score')
->where('created_at', '>=', Carbon::now()->startOfWeek(Carbon::SUNDAY))
->where('created_at', '<=', Carbon::now()->endOfWeek(Carbon::SATURDAY))
->where('user_id', $user->id)
->get();
According to my data I need to get score 88 as result , because this score is obtained on 23rd Feb Sunday which is this weeks starting and till today all other scores are not greater than this.

In your code you need to specify the date format when comparing,
Carbon::now()->endOfWeek(Carbon::SATURDAY)->format('Y-m-d H:i:s');

$en = CarbonImmutable::now()->locale('en_US');
$ar = CarbonImmutable::now()->locale('ar');
// We still can force to use an other day as start/end of week
$start = $en->startOfWeek(Carbon::TUESDAY);
$end = $en->endOfWeek(Carbon::SATURDAY);
var_dump($ar->endOfWeek()->format('Y-m-d H:i'));
Is working for me

You can set the starting day of the week by using the Carbon static function setWeekStartsAt and also can use that to work out the end of week day.
public static function getWeekStartAndEndDates($date, $startDayIndex = Carbon::SATURDAY)
{
$date = Carbon::parse($date);
$date::setWeekStartsAt($startDayIndex);
$from = $date->startOfWeek();
$date::setWeekEndsAt($from->copy()->addDays(6)->dayOfWeek);
$to = $date->copy()->endOfWeek();
return ['from' => $from, 'to' => $to];
}

Related

DAX number of days

Can you please help how I can return the total number of days for each month in a given quarter?
For example, I already have 92 days for December 2025 but how can I show 92 days for October and November as well?
If you want only a count, you can use measure:
QuarterDays = calculate(countrows(VALUES('Calendar'[Date])), FILTER(ALL('Calendar'), selectedvalue('Calendar'[Year]) = 'Calendar'[Year] && selectedvalue('Calendar'[Quarter]) = 'Calendar'[Quarter] ))

Count next X days without Sunday using Laravel carbon

I am developing a subscription based application using Laravel. I want to change the state of the user to expire after 75 days of subscribing to the package. I want to exclude Sundays from these 75 days.
Consider a scenario where user's account is verified today and he has only access to the premium functionalities for 75 days(without Sundays). After the 75 days, the user needs to resubscribe to get access to the premium functionalities of the application.
I will then set up a middleware which will check if the user's subscription is expired or not.
I have two scenarios to check for expiration:
Save the expiration date column in the users table.
Verify each user's request based on verified_at (datetime) column and prevent premium access if the user subscription is over more than 75 days without Sundays.
I want to achieve this using Laravel Carbon or any other alternative library/functionality.
After 75 Days from Today(11 June) is August 25 🙅‍♂️
After 75 Days from Today(11 June - Excluding Sundays) is September 07 👈
Reference: https://getcalc.com/75business-days-after-today.htm
If 75 is fixed, than you could easily calculate the number of Sundays in the period, and so then you just need adding those days to the 75:
$period_in_days = 75;
if($user->verified_at->dayOfWeek > 2)
$period_in_days += 11;
else
$period_in_days += 10;
The point is, in 75 days there could either 10 or 11 Sundays, and so in order to decide whether there are 10 or 11, we need to check which day is the first day.
Let's say is Monday the first day, so the 75 days should looks like this
1 - Monday
2 - Tuesday
...
71 - Monday
72 - Tuesday
73 - Wednesday
74 - Thursday
75 - Friday
Let's say is Tuesday the first day, so the 75 days should looks like this
1 - Tuesday
2 - Wednesday
...
71 - Tuesday
72 - Wednesday
73 - Thursday
74 - Friday
75 - Saturday
Let's say is Wednesday the first day, so the 75 days should looks like this
1 - Wednesday
2 - Thursday
...
71 - Wednesday
72 - Thursday
73 - Friday
74 - Saturday
75 - Sunday
So if the first day is not neither Monday and Tuesday, then there will be 11 Sundays (10 + the 1 that appears in the [71- 75]), otherwise there will be only 10 Sundays
I can count next 75 days excluding Sundays using the following PHP function
function Next75Days($StartingDate){
// Count Next 75 Days excluding Sundays
$Days = 75;
$d = new DateTime($StartingDate);
$t = $d->getTimestamp();
// Loop for 75 days
for($i=0; $i<$Days; $i++){
// Add 1 day to timestamp
$addDay = 86400;
// Get date of next day
$nextDay = date('w', ($t+$addDay));
// if it's Sunday, do $i--1
if($nextDay == 0) {
$i--;
}
// modify timestamp, add 1 day
$t = $t+$addDay;
}
$d->setTimestamp($t);
return $d->format('d M Y');
}

I have 2 dates in Laravel, how can I run a auto generate post to go through between two dates with time period?

I want to create a Question (question table) that has startDate and endDate and period that is in hour (1-2-3-... hours) and user_id
Now I want to auto generate question rows in another table (Question_user) between two dates with period
ex:
startDate = 2019-11-01 00:00:00
endDate = 2019-11-20 12:00:00
period = 12
Now I want to create questions in (Question_user) at:
2019-11-01 00:00:00
2019-11-01 12:00:00
2019-11-02 00:00:00
...
How can I do this?
*Date format -->Year/Month/Day
in your controller , add below function :
protected function GenerateDateRange(Carbon $start_date, Carbon $end_date,$period)
{
$dates = [];
for($date = $start_date; $date->lte($end_date); $date->addHours($period)) {
$dates[] = $date->format('Y-m-d H:i:s');
}
return $dates;
}
and use it like this :
$dateRanges=$this->GenerateDateRange(Carbon::parse("2019-11-01 00:00:00"),Carbon::parse("2019-11-20 12:00:00"),12);
then for loop through $dateRanges and insert your data .

Using Featuretools to aggregate per time time of day

I'm wondering if there's any way to calculate all the same variables I already am using deep feature synthesis (ie counts, sums, mean, etc) for different time segments within a day?
I.e. count of morning events (hours 0-12) as a separate variable from evening events (13-24).
Also, within the same vein, what would be the easiest to get counts by day of week, day of month, day of year, etc. Custom aggregate primitives?
Yes, this is possible. First, let's generate some random data and then I'll walkthrough how
import featuretools as ft
import pandas as pd
import numpy as np
# make some random data
n = 100
events_df = pd.DataFrame({
"id" : range(n),
"customer_id": np.random.choice(["a", "b", "c"], n),
"timestamp": pd.date_range("Jan 1, 2019", freq="1h", periods=n),
"amount": np.random.rand(n) * 100
})
def to_part_of_day(x):
if x < 12:
return "morning"
elif x < 18:
return "afternoon"
else:
return "evening"
events_df["time_of_day"] = events_df["timestamp"].dt.hour.apply(to_part_of_day)
events_df
the first thing we want to do is add a new column for the segment we want to calculate features for
def to_part_of_day(x):
if x < 12:
return "morning"
elif x < 18:
return "afternoon"
else:
return "evening"
events_df["time_of_day"] = events_df["timestamp"].dt.hour.apply(to_part_of_day)
now we have a dataframe like this
id customer_id timestamp amount time_of_day
0 0 a 2019-01-01 00:00:00 44.713802 morning
1 1 c 2019-01-01 01:00:00 58.776476 morning
2 2 a 2019-01-01 02:00:00 94.671566 morning
3 3 a 2019-01-01 03:00:00 39.271852 morning
4 4 a 2019-01-01 04:00:00 40.773290 morning
5 5 c 2019-01-01 05:00:00 19.815855 morning
6 6 a 2019-01-01 06:00:00 62.457129 morning
7 7 b 2019-01-01 07:00:00 95.114636 morning
8 8 b 2019-01-01 08:00:00 37.824668 morning
9 9 a 2019-01-01 09:00:00 46.502904 morning
Next, let's load it into our entityset
es = ft.EntitySet()
es.entity_from_dataframe(entity_id="events",
time_index="timestamp",
dataframe=events_df)
es.normalize_entity(new_entity_id="customers", index="customer_id", base_entity_id="events")
es.plot()
Now, we are ready to set the segments we want to create aggregations for by using interesting_values
es["events"]["time_of_day"].interesting_values = ["morning", "afternoon", "evening"]
Then we can run DFS and place the aggregation primitives we want to do on a per segment basis in the where_primitives parameter
fm, fl = ft.dfs(target_entity="customers",
entityset=es,
agg_primitives=["count", "mean", "sum"],
trans_primitives=[],
where_primitives=["count", "mean", "sum"])
fm
In the resulting feature matrix, you can now see we have aggregations per morning, afternoon, and evening
COUNT(events) MEAN(events.amount) SUM(events.amount) COUNT(events WHERE time_of_day = afternoon) COUNT(events WHERE time_of_day = evening) COUNT(events WHERE time_of_day = morning) MEAN(events.amount WHERE time_of_day = afternoon) MEAN(events.amount WHERE time_of_day = evening) MEAN(events.amount WHERE time_of_day = morning) SUM(events.amount WHERE time_of_day = afternoon) SUM(events.amount WHERE time_of_day = evening) SUM(events.amount WHERE time_of_day = morning)
customer_id
a 37 49.753630 1840.884300 12 7 18 35.098923 45.861881 61.036892 421.187073 321.033164 1098.664063
b 30 51.241484 1537.244522 3 10 17 45.140800 46.170996 55.300715 135.422399 461.709963 940.112160
c 33 39.563222 1305.586314 9 7 17 50.129136 34.593936 36.015679 451.162220 242.157549 612.266545

Find the specific day of a given month and given year

is there a Perl module which could give me for input month and year, let say, 06-2005, what the last day of this month for this year is? For this example, it is easy, because June always has 30 days, so the last day will be 30-06-2005. But it is not the case for February. So, if I have 02-1997, I would like to know whether to return 28-02-1997 or 29-02-1997. Thanks in advance.
Yes, there is a subroutine Days_in_Month in the Date::Calc module.
use strict;
use warnings;
use Date::Calc qw/Days_in_Month/;
for my $m (1 .. 12) {
print Days_in_Month(2005, $m), "\n";
}
OUTPUT
31
28
31
30
31
30
31
31
30
31
30
31
The last day in a given month is the "0th" day of the following month. mktime() takes a 0-based month and 1900-based year number, and returns an epoch timestamp.
use POSIX qw( mktime strftime );
sub last_day {
my ( $year, $mon ) = #_;
return mktime(0,0,0, 0, $mon, $year-1900);
}
You can pass that to localtime or strftime.
say scalar localtime last_day(2005, 5)
'Tue May 31 00:00:00 2005'
say scalar localtime last_day(2005, 6)
'Thu Jun 30 00:00:00 2005'
say scalar localtime last_day(1997, 2)
'Fri Feb 28 00:00:00 1997'
say scalar localtime last_day(2012, 2)
'Wed Feb 29 00:00:00 2012'
say (localtime last_day(1997, 2))[3]
'28'
say strftime "%d", localtime last_day(1997, 2)
'28'
As others said, use DateTime:
use DateTime;
my $dt = DateTime->last_day_of_month('year'=>2000, 'month'=>2);
print $dt->ymd; # '2000-02-29'
While DateTime may not be the fastest module for handling dates/times, it's definitely the most complete one. It's also the only one that handles the various quirks of date/time math correctly.

Resources