From bee07217330b391601dde67ead27b0ae2f24be58 Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 27 Feb 2018 12:15:38 +0100 Subject: [PATCH] Fix #1073 Handle microseconds for locales with coma decimal separator (#1128) Work-around for bug https://bugs.php.net/bug.php?id=67127 --- src/Carbon/Carbon.php | 22 +++++++++++------ tests/Carbon/CreateFromTimestampTest.php | 30 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/Carbon/Carbon.php b/src/Carbon/Carbon.php index 280598aec3..4068ae811d 100644 --- a/src/Carbon/Carbon.php +++ b/src/Carbon/Carbon.php @@ -297,7 +297,15 @@ public function __construct($time = null, $tz = null) $time = $testInstance->format(static::MOCK_DATETIME_FORMAT); } + // Work-around for PHP bug https://bugs.php.net/bug.php?id=67127 + if (strpos((string) .1, '.') === false) { + $locale = setlocale(LC_NUMERIC, '0'); + setlocale(LC_NUMERIC, 'C'); + } parent::__construct($time, static::safeCreateDateTimeZone($tz)); + if (isset($locale)) { + setlocale(LC_NUMERIC, $locale); + } static::setLastErrors(parent::getLastErrors()); } @@ -639,7 +647,7 @@ public static function createFromTimestamp($timestamp, $tz = null) public static function createFromTimestampMs($timestamp, $tz = null) { return static::createFromFormat('U.u', sprintf('%F', $timestamp / 1000)) - ->setTimezone(static::safeCreateDateTimeZone($tz)); + ->setTimezone($tz); } /** @@ -2581,27 +2589,27 @@ public function addSecond($value = 1) } /** - * Remove a second from the instance + * Remove seconds from the instance * * @param int $value * * @return static */ - public function subSecond($value = 1) + public function subSeconds($value) { - return $this->subSeconds($value); + return $this->addSeconds(-1 * $value); } /** - * Remove seconds from the instance + * Remove a second from the instance * * @param int $value * * @return static */ - public function subSeconds($value) + public function subSecond($value = 1) { - return $this->addSeconds(-1 * $value); + return $this->subSeconds($value); } /////////////////////////////////////////////////////////////////// diff --git a/tests/Carbon/CreateFromTimestampTest.php b/tests/Carbon/CreateFromTimestampTest.php index fdf2446b68..ccf65a3495 100644 --- a/tests/Carbon/CreateFromTimestampTest.php +++ b/tests/Carbon/CreateFromTimestampTest.php @@ -30,6 +30,36 @@ public function testCreateFromTimestampMS() $this->assertCarbon($d, 1975, 5, 21, 22, 32, 5, 321000); } + public function testComaDecimalSeparatorLocale() + { + $date = new Carbon('2017-07-29T13:57:27.123456Z'); + $this->assertSame('2017-07-29 13:57:27.123456 Z', $date->format('Y-m-d H:i:s.u e')); + + $date = Carbon::createFromFormat('Y-m-d\TH:i:s.uT', '2017-07-29T13:57:27.123456Z'); + $this->assertSame('2017-07-29 13:57:27.123456 Z', $date->format('Y-m-d H:i:s.u e')); + $timestamp = Carbon::create(1975, 5, 21, 22, 32, 5)->timestamp * 1000 + 321; + $d = Carbon::createFromTimestampMs($timestamp); + $this->assertCarbon($d, 1975, 5, 21, 22, 32, 5, 321000); + + $locale = setlocale(LC_ALL, '0'); + setlocale(LC_ALL, 'fr_FR.UTF-8'); + + $timestamp = Carbon::create(1975, 5, 21, 22, 32, 5)->timestamp * 1000 + 321; + $d = Carbon::createFromTimestampMs($timestamp); + $this->assertCarbon($d, 1975, 5, 21, 22, 32, 5, 321000); + + $date = new Carbon('2017-07-29T13:57:27.123456Z'); + $this->assertSame('2017-07-29 13:57:27.123456 Z', $date->format('Y-m-d H:i:s.u e')); + + $date = Carbon::createFromFormat('Y-m-d\TH:i:s.uT', '2017-07-29T13:57:27.123456Z'); + $this->assertSame('2017-07-29 13:57:27.123456 Z', $date->format('Y-m-d H:i:s.u e')); + $timestamp = Carbon::create(1975, 5, 21, 22, 32, 5)->timestamp * 1000 + 321; + $d = Carbon::createFromTimestampMs($timestamp); + $this->assertCarbon($d, 1975, 5, 21, 22, 32, 5, 321000); + + setlocale(LC_ALL, $locale); + } + public function testCreateFromTimestampUsesDefaultTimezone() { $d = Carbon::createFromTimestamp(0);