I've opened an issue about this in stackoverflow: http://stackoverflow.com/questions/37965285/php-incorrect-first-day-of-the-week-for-my-timezone. The problem is that i can't seem to find where Carbon's weekStartsAt is being defined.
/**
* First day of week
*
* @var int
*/
protected static $weekStartsAt = self::MONDAY;
A user on stackoverflow has posted that there is a test for the getter/setter but that the value doesn't seem to be set from anywhere which i can confirm, i can't find any usage of $weekStartsAt anywhere in the project but in one method that resets the date to that and of course in the getter/setter methods.
This could be part of my problem although there is still the problem that the locale command on the command line still returns 1 (monday) in locales that should be 0 (sunday)
Here is a copy paste of my original question to save you from going to stackoverflow to read more about it.
I'm using Laravel but i'm pretty sure it has nothing to do with it per se, and my Carbon dates are always returning "monday" as the first day of the week. Problem is, i'm in a locale where it should be returning "Sunday".
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'America/Montreal',
Create a Carbon date and print it:
<?php
$date = Carbon::now();
var_dump($date);
Outputs
object(Carbon\Carbon)[278]
public 'date' => string '2016-06-22 06:05:18.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'America/Montreal' (length=16)
And if i print the first day of the week
<?php var_dump($date->getWeekStartsAt());
I get 1.
Strangely enough, if i go to my homestead console and type "locale", i get:
LANG=en_US.UTF-8
LANGUAGE=en_US:
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8
So my default locale should be USA right? According to Google, first day of the week in the USA, Canada and Japan is Sunday... Running "locale first_weekday" yields: 1 (Monday)
So i'm not sure what i should or can do to fix this as this is completely incorrect. I have a calendar being drawn based on machine locale and this is obviously wrong so it is showing my customers a calendar that doesn't fit their locale.
Thanks for sharing your thoughts!
up
Hi @crazycodr, not completely sure I understand what your issue is.
Can you reformulate maybe?
we need to have a config to set the start of week day or is that it can be corrected automatically with the local because its
because it causes a lot of problem with start of week and the transition between the weeks, months and years
Can we not already do so ?
Carbon::setWeekStartsAt(Carbon::WEDNESDAY);
It is a twofolds problem:
1) first we are never using the locale information to set that value but we should
2) the locale files used by PHP don't seem to have a proper value (this is an issue we have to report to the proper authorities)
The easy way out is managing this ourselves by calling:
Carbon::setWeekStartsAt(Carbon::WEDNESDAY);
It's wrong and imposes an additional layer on our application to track what is the right day the week starts at for each locale. That information is already available in the LOCALE system we should make good use of it. But, because it's flawed right now, then, we'd need to resort to that same mechanism we just talked to override it manually. Once the locale files are fixed and we are relying on it, then the override mechanism is only a per user preference override.
Just noticed the exact same problem. So I need to workaround that issue now.
Depending on how things go, I'll maybe target a PR on Carbon. Any hint on a standards based dynamic solution in general is very welcome.
I thought about the problem again from another perspective. Taking the system locale into account seems not to be the correct solution.
Imagine you're processing a date with a given timezone. I think the following expectation would be perfectly valid:
/** @test */
public function it_returns_the_correct_start_of_week_respecting_the_timezone()
{
$date = Carbon::parse('2016-01-02', 'America/Monterrey');
$actual = $date->startOfWeek();
// sunday, start of week in that timezone
$expected = Carbon::parse('2016-01-02', 'America/Monterrey');
// phpunit -> currently fails.
$this->assertTrue($expected->eq($actual),
sprintf("Failed asserting that %s equals %s",$expected,$actual));
// fails with 'Failed asserting that 2016-01-02 00:00:00 equals 2015-12-28 00:00:00'
// because the 28th is a monday.
}
However, that fails currently – and it would still fail if Carbon took the system locale into account and you would work on a system with any locale that has 'monday' set as the starting day of the week.
So the starting day of a week shouldn't be locale dependent, but timezone dependent, especially when working with different dates in different timezones (think about international users on the same system). (BTW: Carbon::$weekStartsAt should not be a static field then).
What do you think?
It may be too late for this, but I've also run into this problem on a project that had to do with payroll. Before the application starts, you have to set both the beginning and end of week:
Carbon::setWeekStartsAt(Carbon::SUNDAY);
Carbon::setWeekEndsAt(Carbon::SATURDAY);
If you only set the start of the week to Sunday, then you get Carbon all confused because the end of the week is also Sunday. I don't think this is a bug, it just needs to be documented somewhere.
It's now explained with examples in the documentation.
Most helpful comment
It may be too late for this, but I've also run into this problem on a project that had to do with payroll. Before the application starts, you have to set both the beginning and end of week:
If you only set the start of the week to Sunday, then you get Carbon all confused because the end of the week is also Sunday. I don't think this is a bug, it just needs to be documented somewhere.