File: DateTime.construct.phpt

package info (click to toggle)
php-nette-utils 4.1.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,460 kB
  • sloc: php: 4,146; xml: 9; makefile: 4
file content (121 lines) | stat: -rw-r--r-- 3,998 bytes parent folder | download
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'",
	);
});