1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
<?php
/**
* Test: Nette\Utils\DateTime constructor __construct() method.
*/
declare(strict_types=1);
use Nette\Utils\DateTime;
use Tester\Assert;
require __DIR__ . '/../bootstrap.php';
date_default_timezone_set('Europe/Prague');
test('Absolute date/time strings', function () {
$dt = new DateTime('2024-08-20 14:30:00');
Assert::same('2024-08-20 14:30:00 CEST (+02:00)', $dt->format('Y-m-d H:i:s T (P)'));
// Absolute format that might look relative
$dt = new DateTime('2 january 2005');
Assert::same('2005-01-02 00:00:00 CET (+01:00)', $dt->format('Y-m-d H:i:s T (P)'));
});
test('now', function () {
$now = new DateTimeImmutable('now');
$dt = new DateTime('');
Assert::true(abs($dt->getTimestamp() - $now->getTimestamp()) <= 1);
$dt = new DateTime('now');
Assert::true(abs($dt->getTimestamp() - $now->getTimestamp()) <= 1);
});
test('Numeric relative strings (should use corrected modify logic)', function () {
$nowTs = time();
$dt = new DateTime('+1 hour');
// Expect time approximately one hour later than $nowTs
Assert::true(abs($dt->getTimestamp() - ($nowTs + 3600)) <= 1);
$dt = new DateTime('- 2 days');
// Allow slightly larger tolerance due to potential DST changes within the 2 days
Assert::true(abs($dt->getTimestamp() - ($nowTs - 2 * 86400)) <= 2);
$dt = new DateTime(' +10 minutes '); // With spaces
Assert::true(abs($dt->getTimestamp() - ($nowTs + 600)) <= 1);
});
test('Textual relative strings', function () {
$dt = new DateTime('yesterday');
$yesterdayRef = new DateTimeImmutable('yesterday');
Assert::same($yesterdayRef->format('Y-m-d'), $dt->format('Y-m-d'));
$dt = new DateTime('next monday');
$nextMondayRef = new DateTimeImmutable('next monday');
Assert::same($nextMondayRef->format('Y-m-d'), $dt->format('Y-m-d'));
$dt = new DateTime('first day of next month');
$firstNextRef = new DateTimeImmutable('first day of next month');
Assert::same($firstNextRef->format('Y-m-d H:i:s'), $dt->format('Y-m-d H:i:s'));
});
test('Timezone handling', function () {
$defaultTz = (new DateTime)->getTimezone();
$utcTz = new DateTimeZone('UTC');
// 1. No timezone provided -> should use default
$dt = new DateTime('2024-09-01 10:00:00');
Assert::same($defaultTz->getName(), $dt->getTimezone()->getName(), 'Uses default timezone when null');
// 2. Explicit timezone provided -> should use provided
$dt = new DateTime('2024-09-01 10:00:00', $utcTz);
Assert::same($utcTz->getName(), $dt->getTimezone()->getName(), 'Uses provided timezone (UTC)');
Assert::same('2024-09-01 10:00:00 UTC (+00:00)', $dt->format('Y-m-d H:i:s T (P)'));
// 3. Relative string, no timezone -> should use default
$dt = new DateTime('+3 hours');
Assert::same($defaultTz->getName(), $dt->getTimezone()->getName(), 'Relative string uses default timezone when null');
// 4. Relative string, explicit timezone -> should use provided
$dt = new DateTime('+3 hours', $utcTz);
Assert::same($utcTz->getName(), $dt->getTimezone()->getName(), 'Relative string uses provided timezone (UTC)');
// 5. Absolute string (date only), explicit timezone -> should use provided
$dt = new DateTime('2024-11-11', $utcTz);
Assert::same($utcTz->getName(), $dt->getTimezone()->getName(), 'Absolute date string uses provided timezone (UTC)');
Assert::same('2024-11-11 00:00:00 UTC (+00:00)', $dt->format('Y-m-d H:i:s T (P)'));
});
test('Exception handling for invalid input', function () {
Assert::exception(
fn() => new DateTime('invalid date format'),
Throwable::class,
'%a%invalid date format%a%',
);
Assert::exception(
fn() => new DateTime('0000-00-00'),
Throwable::class,
"The parsed date was invalid '0000-00-00'",
);
Assert::exception(
fn() => new DateTime('2024-02-31 10:00:00'), // Invalid day for February
Throwable::class,
"The parsed date was invalid '2024-02-31 10:00:00'",
);
Assert::exception(
fn() => new DateTime('1978-01-23 23:00:60'),
Throwable::class,
"The parsed time was invalid '1978-01-23 23:00:60'",
);
});
|