Repository: briannesbitt/Carbon (PHP)

Issue:
Locales with first_day_of_week > 0 seemingly makes weekday inaccurate
Hello, 
I think I might have encountered a small bug with the Norwegian Bokmål (nb) locale.



I encountered an issue with the following code:
```php
Carbon::setLocale('nb');
Carbon::setTestNowAndTimezone(Carbon::parse('2022-09-19 11:00:00'), 'Europe/Oslo');
echo Carbon::today()->weekday(CarbonInterface::TUESDAY) . "\r\n";
echo Carbon::getWeekStartsAt();
```

Carbon version: I tested version 2.58.0 and 2.62.1 
PHP version: 8.1.10

[Here is a link to PHP Sandbox](https://play.phpsandbox.io/nesbot/carbon?version=2.62.1.0&input=%3C%3Fphp%0D%0A%0D%0Ause%20Carbon%5CCarbon%3B%0D%0Ause%20Carbon%5CCarbonInterface%3B%0D%0A%0D%0ACarbon%3A%3AsetWeekStartsAt(CarbonInterface%3A%3AMONDAY)%3B%0D%0ACarbon%3A%3AsetTestNowAndTimezone(Carbon%3A%3Aparse(%272022-09-19%2011%3A00%3A00%27)%2C%20%27Europe%2FOslo%27)%3B%0D%0Aecho%20Carbon%3A%3Atoday()-%3Eweekday(CarbonInterface%3A%3ATUESDAY)%20.%20%22%5Cr%5Cn%22%3B%0D%0Aecho%20Carbon%3A%3AgetWeekStartsAt()%3B)

I expected to get:

```
2022-09-20 00:00:00
1
```

But I actually get:

```
2022-09-21 00:00:00
1
```

Dates are seemingly shifted n days equal to the value of `first_day_of_week` as `->weekday(CarbonInterface::TUESDAY)` changes the date to wednesday not tuesday, and in Bokmål the `first_day_of_week` is 1.

Thanks!



Discussion:
Hello, 👋 

Indeed, this is not expected.

Meanwhile, you can use:
```php
Carbon::setLocale('nb');
Carbon::setTestNowAndTimezone(Carbon::parse('2022-09-19 11:00:00'), 'Europe/Oslo');
echo Carbon::today()->modify('Tuesday') . "\r\n";
echo Carbon::getWeekStartsAt();
```
Thank you for the swift response and for the workaround!
It will be fixed in the next version (can be tried using `composer require "nesbot/carbon:dev-master as 2.63.0"`).

For the record, it will be slightly different than the work-around. `Carbon::today()->modify('Tuesday')` go to the next Tuesday. `Carbon::today()->weekday(CarbonInterface::TUESDAY)` will go to the Tuesday of the same week, here week is considered from Monday to Sunday since the locale is `nb`.

So it will be equivalent to:

```
Carbon::today()->startOfWeek()->modify('Tuesday')
```



Patch:
diff --git a/src/Carbon/Traits/Date.php b/src/Carbon/Traits/Date.php
index 7dc0b9bb69..0d9536c107 100644
--- a/src/Carbon/Traits/Date.php
+++ b/src/Carbon/Traits/Date.php
@@ -1354,9 +1354,14 @@ public function dayOfYear($value = null)
      */
     public function weekday($value = null)
     {
-        $dayOfWeek = ($this->dayOfWeek + 7 - (int) ($this->getTranslationMessage('first_day_of_week') ?? 0)) % 7;
+        if ($value === null) {
+            return $this->dayOfWeek;
+        }
+
+        $firstDay = (int) ($this->getTranslationMessage('first_day_of_week') ?? 0);
+        $dayOfWeek = ($this->dayOfWeek + 7 - $firstDay) % 7;
 
-        return $value === null ? $dayOfWeek : $this->addDays($value - $dayOfWeek);
+        return $this->addDays((($value + 7 - $firstDay) % 7) - $dayOfWeek);
     }
 
     /**


Test patch:
diff --git a/tests/Carbon/WeekTest.php b/tests/Carbon/WeekTest.php
index f1e85d1214..e512ba699b 100644
--- a/tests/Carbon/WeekTest.php
+++ b/tests/Carbon/WeekTest.php
@@ -5430,5 +5430,11 @@ public function testWeekday()
         $this->assertSame('08-06', $date->isoWeekday(CarbonInterface::MONDAY)->format('m-d'));
         $this->assertSame(CarbonInterface::MONDAY, $date->weekday());
         $this->assertSame(CarbonInterface::MONDAY, $date->isoWeekday());
+
+        Carbon::setLocale('nb');
+        Carbon::setTestNowAndTimezone(Carbon::parse('2022-09-19 11:00:00'), 'Europe/Oslo');
+        $this->assertSame('2022-09-20 00:00', Carbon::today()->weekday(CarbonInterface::TUESDAY)->format('Y-m-d H:i'));
+        Carbon::setTestNowAndTimezone(Carbon::parse('2022-10-21 16:00:00'), 'Europe/Oslo');
+        $this->assertSame('2022-10-18 00:00', Carbon::today()->weekday(CarbonInterface::TUESDAY)->format('Y-m-d H:i'));
     }
 }