Skip to content

Commit

Permalink
Add utc parameters only for methods needing it (units bigger than hour)
Browse files Browse the repository at this point in the history
  • Loading branch information
kylekatarnls committed Mar 26, 2024
1 parent a779d0d commit 48e4d73
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 25 deletions.
8 changes: 6 additions & 2 deletions src/Carbon/Traits/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -2613,8 +2613,12 @@ public function __call(string $method, array $parameters): mixed
);
}

$method = 'diffIn'.$match[3];
$parameters['utc'] = ($mode === 'UTC');
$unit = self::pluralUnit($match[3]);
$method = 'diffIn'.ucfirst($unit);

if (\in_array($unit, ['days', 'weeks', 'months', 'quarters', 'years'])) {
$parameters['utc'] = ($mode === 'UTC');
}

if (method_exists($this, $method)) {
return $this->$method(...$parameters);
Expand Down
93 changes: 81 additions & 12 deletions tests/Carbon/DiffTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,21 @@ public function testDiffInMonthsWithTimezone()

$this->assertSame(-1, (int) $first->diffInMonths($second, false));
$this->assertSame(1, (int) $second->diffInMonths($first, false));
$this->assertVeryClose(-(1 + 6 / 24 / 31 + 1 / 24 / 28), $first->diffInMonths($second));
$this->assertSame($first->utc()->diffInMonths($second->utc()), $first->diffInMonths($second));
$this->assertSame($second->utc()->diffInMonths($first->utc()), $second->diffInMonths($first));
$this->assertVeryClose(-(1 + 1 / 24 / 31 + 6 / 24 / 28), $first->diffInMonths($second));
// $second date in Toronto is 2021-12-31 18:00, so we have 6 hours in December (a 31 days month), and 1 hour in February (28 days month)
$this->assertVeryClose(1 + (7 / 24 / 28), $second->diffInMonths($first));
$this->assertVeryClose(1 + 1 / 24 / 31 + 6 / 24 / 28, $second->diffInMonths($first));
// Considered in Berlin timezone, the 7 extra hours are in February (28 days month)

$first = new Carbon('2022-02-01 01:00 Europe/Berlin');
$second = new Carbon('2022-01-01 00:00 America/Toronto');

$this->assertSame(0, (int) $first->diffInMonths($second, false));
$this->assertSame(0, (int) $second->diffInMonths($first, false));
$this->assertVeryClose(-(1 - 6 / 24 / 31 + 1 / 24 / 28), $first->diffInMonths($second));
$this->assertSame($first->utc()->diffInMonths($second->utc()), $first->diffInMonths($second));
$this->assertSame($second->utc()->diffInMonths($first->utc()), $second->diffInMonths($first));
$this->assertVeryClose(-(1 - 5 / 24 / 31), $first->diffInMonths($second));
$this->assertVeryClose(1 - 5 / 24 / 31, $second->diffInMonths($first));
}

Expand Down Expand Up @@ -1868,10 +1872,10 @@ public function testFloatDiffWithRealUnits()
date_default_timezone_set('UTC');
$this->assertVeryClose(1.0006944444444446, Carbon::parse('2018-12-01 00:00')->floatDiffInRealDays(Carbon::parse('2018-12-02 00:01'), true));

$this->assertSame(1.0, Carbon::parse('2021-03-27 20:00 Europe/Warsaw')->floatDiffInRealDays('2021-03-28 20:00'));
$this->assertSame(2.0, Carbon::parse('2021-03-26 20:00 Europe/Warsaw')->floatDiffInRealDays('2021-03-28 20:00'));
$this->assertSame(2.0, Carbon::parse('2021-03-27 20:00 Europe/Warsaw')->floatDiffInRealDays('2021-03-29 20:00'));
$this->assertSame(1.0, Carbon::parse('2021-10-30 20:00 Europe/Warsaw')->floatDiffInRealDays('2021-10-31 20:00'));
$this->assertVeryClose(0.9583333333333334, Carbon::parse('2021-03-27 20:00 Europe/Warsaw')->floatDiffInRealDays('2021-03-28 20:00'));
$this->assertVeryClose(1.9583333333333335, Carbon::parse('2021-03-26 20:00 Europe/Warsaw')->floatDiffInRealDays('2021-03-28 20:00'));
$this->assertVeryClose(1.9583333333333335, Carbon::parse('2021-03-27 20:00 Europe/Warsaw')->floatDiffInRealDays('2021-03-29 20:00'));
$this->assertVeryClose(1.0416666666666667, Carbon::parse('2021-10-30 20:00 Europe/Warsaw')->floatDiffInRealDays('2021-10-31 20:00'));
$this->assertVeryClose(1.0006944444444443, Carbon::parse('2018-12-01 00:00')->floatDiffInRealDays(Carbon::parse('2018-12-02 00:01')));

$this->assertVeryClose(1.0006944444444443, Carbon::parse('2018-12-01 00:00')->floatDiffInRealDays(Carbon::parse('2018-12-02 00:01')));
Expand Down Expand Up @@ -1909,16 +1913,81 @@ public function testFloatDiffWithRealUnits()
$this->assertVeryClose(5.325284965308378, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInRealYears(Carbon::parse('2023-06-12 14:24:58.987421')));
$this->assertVeryClose(-5.325284965308378, Carbon::parse('2023-06-12 14:24:58.987421')->floatDiffInRealYears(Carbon::parse('2018-02-13 20:55:12.321456')));

$this->assertSame(1.0, Carbon::parse('2018-10-01 00:00:00', 'Europe/Paris')->floatDiffInRealMonths(Carbon::parse('2018-11-01 00:00:00', 'Europe/Paris'), true));
$this->assertVeryClose(1.0336021505376345, Carbon::parse('2018-10-01 00:00:00', 'Europe/Paris')->floatDiffInRealMonths(Carbon::parse('2018-11-01 00:00:00', 'Europe/Paris'), true));
$this->assertSame(1.0, Carbon::parse('2018-10-28 00:00:00')->floatDiffInRealMonths(Carbon::parse('2018-11-28 00:00:00'), true));
$this->assertSame(1.0, Carbon::parse('2018-10-28 00:00:00', 'Europe/Paris')->floatDiffInRealMonths(Carbon::parse('2018-11-28 00:00:00', 'Europe/Paris'), true));
$this->assertVeryClose(1.0013888888888889, Carbon::parse('2018-10-28 00:00:00', 'Europe/Paris')->floatDiffInRealMonths(Carbon::parse('2018-11-28 00:00:00', 'Europe/Paris'), true));

$this->assertSame(-1.0, Carbon::parse('2018-11-01 00:00:00', 'Europe/Paris')->floatDiffInRealMonths(Carbon::parse('2018-10-01 00:00:00', 'Europe/Paris')));
$this->assertVeryClose(-1.0336021505376345, Carbon::parse('2018-11-01 00:00:00', 'Europe/Paris')->floatDiffInRealMonths(Carbon::parse('2018-10-01 00:00:00', 'Europe/Paris')));
$this->assertSame(-1.0, Carbon::parse('2018-11-28 00:00:00')->floatDiffInRealMonths(Carbon::parse('2018-10-28 00:00:00')));
$this->assertSame(-1.0, Carbon::parse('2018-11-28 00:00:00', 'Europe/Paris')->floatDiffInRealMonths(Carbon::parse('2018-10-28 00:00:00', 'Europe/Paris')));
$this->assertVeryClose(-1.0013888888888889, Carbon::parse('2018-11-28 00:00:00', 'Europe/Paris')->floatDiffInRealMonths(Carbon::parse('2018-10-28 00:00:00', 'Europe/Paris')));

Carbon::setTestNow('2021-03-28 20:00 Europe/Warsaw');
$this->assertSame(1.0, Carbon::parse('2021-03-27 20:00 Europe/Warsaw')->floatDiffInRealDays());
$this->assertSame(0.9583333333333334, Carbon::parse('2021-03-27 20:00 Europe/Warsaw')->floatDiffInRealDays());
}

public function testFloatDiffWithUTCUnits()
{
$from = Carbon::parse('2021-03-27 20:00 Europe/Warsaw');
$to = Carbon::parse('2021-03-27 20:00 Europe/London');
$from->floatDiffInUtcDays($to);

$this->assertSame('2021-03-27 20:00:00 Europe/Warsaw', $from->format('Y-m-d H:i:s e'));
$this->assertSame('2021-03-27 20:00:00 Europe/London', $to->format('Y-m-d H:i:s e'));

date_default_timezone_set('UTC');
$this->assertVeryClose(1.0006944444444446, Carbon::parse('2018-12-01 00:00')->floatDiffInUtcDays(Carbon::parse('2018-12-02 00:01'), true));

$this->assertVeryClose(0.9583333333333334, Carbon::parse('2021-03-27 20:00 Europe/Warsaw')->floatDiffInUtcDays('2021-03-28 20:00'));
$this->assertVeryClose(1.9583333333333335, Carbon::parse('2021-03-26 20:00 Europe/Warsaw')->floatDiffInUtcDays('2021-03-28 20:00'));
$this->assertVeryClose(1.9583333333333335, Carbon::parse('2021-03-27 20:00 Europe/Warsaw')->floatDiffInUtcDays('2021-03-29 20:00'));
$this->assertVeryClose(1.0416666666666667, Carbon::parse('2021-10-30 20:00 Europe/Warsaw')->floatDiffInUtcDays('2021-10-31 20:00'));
$this->assertVeryClose(1.0006944444444443, Carbon::parse('2018-12-01 00:00')->floatDiffInUtcDays(Carbon::parse('2018-12-02 00:01')));

$this->assertVeryClose(1.0006944444444443, Carbon::parse('2018-12-01 00:00')->floatDiffInUtcDays(Carbon::parse('2018-12-02 00:01')));
$this->assertVeryClose(1.0006944444444443 / 7, Carbon::parse('2018-12-01 00:00')->floatDiffInUtcWeeks(Carbon::parse('2018-12-02 00:01')));

$this->assertVeryClose(0.9714742503779745, Carbon::parse('2018-03-13 20:55:12.321456')->floatDiffInUtcMonths(Carbon::parse('2018-04-12 14:24:58.987421'), true));
$this->assertVeryClose(0.9714742503779745, Carbon::parse('2018-04-12 14:24:58.987421')->floatDiffInUtcMonths(Carbon::parse('2018-03-13 20:55:12.321456'), true));
$this->assertVeryClose(0.9714742503779745, Carbon::parse('2018-03-13 20:55:12.321456')->floatDiffInUtcMonths(Carbon::parse('2018-04-12 14:24:58.987421'), false));
$this->assertVeryClose(-0.9714742503779745, Carbon::parse('2018-04-12 14:24:58.987421')->floatDiffInUtcMonths(Carbon::parse('2018-03-13 20:55:12.321456'), false));

$this->assertVeryClose(1.0006944444444443 / 7, Carbon::parse('2018-12-01 00:00')->floatDiffInUtcWeeks(Carbon::parse('2018-12-02 00:01')));
$this->assertVeryClose(1.0006944444444443 / 7, Carbon::parse('2018-12-01 00:00')->floatDiffInUtcWeeks(Carbon::parse('2018-12-02 00:01'), true));

$this->assertVeryClose(0.9714742503779745, Carbon::parse('2018-03-13 20:55:12.321456')->floatDiffInUtcMonths(Carbon::parse('2018-04-12 14:24:58.987421')));
$this->assertVeryClose(-0.9714742503779745, Carbon::parse('2018-04-12 14:24:58.987421')->floatDiffInUtcMonths(Carbon::parse('2018-03-13 20:55:12.321456')));

$this->assertVeryClose(16.557633744585264, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcMonths(Carbon::parse('2019-06-30 14:24:58.987421'), true));

$this->assertVeryClose(15.971474250377973, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcMonths(Carbon::parse('2019-06-12 14:24:58.987421'), true));
$this->assertVeryClose(15.971474250377973, Carbon::parse('2019-06-12 14:24:58.987421')->floatDiffInUtcMonths(Carbon::parse('2018-02-13 20:55:12.321456'), true));
$this->assertVeryClose(15.971474250377973, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcMonths(Carbon::parse('2019-06-12 14:24:58.987421')));
$this->assertVeryClose(-15.971474250377973, Carbon::parse('2019-06-12 14:24:58.987421')->floatDiffInUtcMonths(Carbon::parse('2018-02-13 20:55:12.321456')));

$this->assertSame(1.0, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcYears(Carbon::parse('2019-02-13 20:55:12.321456'), true));
$this->assertVeryClose(1.3746000338015283, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcYears(Carbon::parse('2019-06-30 14:24:58.987421'), true));
$this->assertVeryClose(0.9609014036645421, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcYears(Carbon::parse('2019-01-30 14:24:58.987421'), true));

$this->assertVeryClose(1.3252849653083778, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcYears(Carbon::parse('2019-06-12 14:24:58.987421'), true));
$this->assertVeryClose(1.3252849653083778, Carbon::parse('2019-06-12 14:24:58.987421')->floatDiffInUtcYears(Carbon::parse('2018-02-13 20:55:12.321456'), true));
$this->assertVeryClose(1.3252849653083778, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcYears(Carbon::parse('2019-06-12 14:24:58.987421')));
$this->assertVeryClose(-1.3252849653083778, Carbon::parse('2019-06-12 14:24:58.987421')->floatDiffInUtcYears(Carbon::parse('2018-02-13 20:55:12.321456')));

$this->assertVeryClose(5.325284965308378, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcYears(Carbon::parse('2023-06-12 14:24:58.987421'), true));
$this->assertVeryClose(5.325284965308378, Carbon::parse('2023-06-12 14:24:58.987421')->floatDiffInUtcYears(Carbon::parse('2018-02-13 20:55:12.321456'), true));
$this->assertVeryClose(5.325284965308378, Carbon::parse('2018-02-13 20:55:12.321456')->floatDiffInUtcYears(Carbon::parse('2023-06-12 14:24:58.987421')));
$this->assertVeryClose(-5.325284965308378, Carbon::parse('2023-06-12 14:24:58.987421')->floatDiffInUtcYears(Carbon::parse('2018-02-13 20:55:12.321456')));

$this->assertVeryClose(1.0336021505376345, Carbon::parse('2018-10-01 00:00:00', 'Europe/Paris')->floatDiffInUtcMonths(Carbon::parse('2018-11-01 00:00:00', 'Europe/Paris'), true));
$this->assertSame(1.0, Carbon::parse('2018-10-28 00:00:00')->floatDiffInUtcMonths(Carbon::parse('2018-11-28 00:00:00'), true));
$this->assertVeryClose(1.0013888888888889, Carbon::parse('2018-10-28 00:00:00', 'Europe/Paris')->floatDiffInUtcMonths(Carbon::parse('2018-11-28 00:00:00', 'Europe/Paris'), true));

$this->assertVeryClose(-1.0336021505376345, Carbon::parse('2018-11-01 00:00:00', 'Europe/Paris')->floatDiffInUtcMonths(Carbon::parse('2018-10-01 00:00:00', 'Europe/Paris')));
$this->assertSame(-1.0, Carbon::parse('2018-11-28 00:00:00')->floatDiffInUtcMonths(Carbon::parse('2018-10-28 00:00:00')));
$this->assertVeryClose(-1.0013888888888889, Carbon::parse('2018-11-28 00:00:00', 'Europe/Paris')->floatDiffInUtcMonths(Carbon::parse('2018-10-28 00:00:00', 'Europe/Paris')));

Carbon::setTestNow('2021-03-28 20:00 Europe/Warsaw');
$this->assertSame(0.9583333333333334, Carbon::parse('2021-03-27 20:00 Europe/Warsaw')->floatDiffInUtcDays());
}

/**
Expand Down
Loading

0 comments on commit 48e4d73

Please sign in to comment.