Skip to content

Commit bb2ba13

Browse files
authored
Merge pull request #1 from GeorgII-web/date_time
Date time
2 parents c463e1e + 8c36375 commit bb2ba13

38 files changed

+654
-177
lines changed

docs/INSTALL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ Create a quick test script (e.g., demo.php):
3131
<?php
3232
require __DIR__ . '/vendor/autoload.php';
3333

34-
use PhpTypedValues\Integer\PositiveInt;
34+
use PhpTypedValues\Integer\IntegerPositive;
3535

36-
echo PositiveInt::fromString('21')->value(); // 21
36+
echo IntegerPositive::fromString('21')->value(); // 21
3737
```
3838

3939
Run it:

docs/USAGE.md

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,25 @@ Static usage examples
4141
---------------------
4242

4343
```php
44-
use PhpTypedValues\DateTime\DateTimeAtom;use PhpTypedValues\DateTime\Timestamp\TimestampSeconds;use PhpTypedValues\Float\FloatBasic;use PhpTypedValues\Float\NonNegativeFloat;use PhpTypedValues\Integer\IntegerBasic;use PhpTypedValues\Integer\NonNegativeInt;use PhpTypedValues\Integer\PositiveInt;use PhpTypedValues\Integer\WeekDayInt;use PhpTypedValues\String\NonEmptyStr;use PhpTypedValues\String\StringBasic;
44+
use PhpTypedValues\DateTime\DateTimeAtom;use PhpTypedValues\DateTime\Timestamp\TimestampSeconds;use PhpTypedValues\Float\FloatStandard;use PhpTypedValues\Float\FloatNonNegative;use PhpTypedValues\Integer\IntegerStandard;use PhpTypedValues\Integer\IntegerNonNegative;use PhpTypedValues\Integer\IntegerPositive;use PhpTypedValues\Integer\IntegerWeekDay;use PhpTypedValues\String\StringNonEmpty;use PhpTypedValues\String\StringStandard;
4545

4646
// Integers
47-
$any = IntegerBasic::fromInt(-10);
48-
$pos = PositiveInt::fromInt(1);
49-
$nn = NonNegativeInt::fromInt(0);
50-
$wd = WeekDayInt::fromInt(7); // 1..7
47+
$any = IntegerStandard::fromInt(-10);
48+
$pos = IntegerPositive::fromInt(1);
49+
$nn = IntegerNonNegative::fromInt(0);
50+
$wd = IntegerWeekDay::fromInt(7); // 1..7
5151

5252
// From string (integers)
53-
$posFromString = PositiveInt::fromString('123');
54-
$wdFromString = WeekDayInt::fromString('5');
53+
$posFromString = IntegerPositive::fromString('123');
54+
$wdFromString = IntegerWeekDay::fromString('5');
5555

5656
// Strings
57-
$greeting = StringBasic::fromString('hello');
58-
$name = NonEmptyStr::fromString('Alice');
57+
$greeting = StringStandard::fromString('hello');
58+
$name = StringNonEmpty::fromString('Alice');
5959

6060
// Floats
61-
$price = FloatBasic::fromString('19.99');
62-
$ratio = NonNegativeFloat::fromFloat(0.5); // >= 0
61+
$price = FloatStandard::fromString('19.99');
62+
$ratio = FloatNonNegative::fromFloat(0.5); // >= 0
6363

6464
// DateTime (RFC 3339 / ATOM)
6565
$dt = DateTimeAtom::fromString('2025-01-02T03:04:05+00:00');
@@ -81,20 +81,20 @@ Validation errors (static constructors)
8181
Invalid input throws an exception with a helpful message.
8282

8383
```php
84-
use PhpTypedValues\Integer\PositiveInt;
85-
use PhpTypedValues\Integer\WeekDayInt;
86-
use PhpTypedValues\String\NonEmptyStr;
87-
use PhpTypedValues\Float\NonNegativeFloat;
84+
use PhpTypedValues\Integer\IntegerPositive;
85+
use PhpTypedValues\Integer\IntegerWeekDay;
86+
use PhpTypedValues\String\StringNonEmpty;
87+
use PhpTypedValues\Float\FloatNonNegative;
8888
use PhpTypedValues\DateTime\DateTimeAtom;
8989

90-
PositiveInt::fromInt(0); // throws: must be > 0
91-
PositiveInt::fromString('12.3'); // throws: String has no valid integer
90+
IntegerPositive::fromInt(0); // throws: must be > 0
91+
IntegerPositive::fromString('12.3'); // throws: String has no valid integer
9292

93-
WeekDayInt::fromInt(0); // throws: Value must be between 1 and 7
93+
IntegerWeekDay::fromInt(0); // throws: Value must be between 1 and 7
9494

95-
NonEmptyStr::fromString(''); // throws: Value must be a non-empty string
95+
StringNonEmpty::fromString(''); // throws: Value must be a non-empty string
9696

97-
NonNegativeFloat::fromString('abc'); // throws: String has no valid float
97+
FloatNonNegative::fromString('abc'); // throws: String has no valid float
9898

9999
DateTimeAtom::fromString('not-a-date'); // throws: String has no valid datetime
100100
```
@@ -110,9 +110,9 @@ declare(strict_types=1);
110110

111111
namespace App\Domain;
112112

113-
use PhpTypedValues\Integer\PositiveInt;
113+
use PhpTypedValues\Integer\IntegerPositive;
114114

115-
final class UserId extends PositiveInt {}
115+
final class UserId extends IntegerPositive {}
116116

117117
// Usage
118118
$userId = UserId::fromInt(42);
@@ -190,20 +190,20 @@ declare(strict_types=1);
190190

191191
namespace App\Domain;
192192

193-
use PhpTypedValues\Integer\PositiveInt;
194-
use PhpTypedValues\String\NonEmptyStr;
195-
use PhpTypedValues\Float\NonNegativeFloat;
193+
use PhpTypedValues\Integer\IntegerPositive;
194+
use PhpTypedValues\String\StringNonEmpty;
195+
use PhpTypedValues\Float\FloatNonNegative;
196196
use PhpTypedValues\DateTime\DateTimeAtom;
197197

198198
final class Profile
199199
{
200200
public function __construct(
201-
public readonly PositiveInt $id,
202-
public readonly NonEmptyStr $firstName,
203-
public readonly NonEmptyStr $lastName,
204-
public readonly ?NonEmptyStr $middleName, // nullable field
201+
public readonly IntegerPositive $id,
202+
public readonly StringNonEmpty $firstName,
203+
public readonly StringNonEmpty $lastName,
204+
public readonly ?StringNonEmpty $middleName, // nullable field
205205
public readonly ?DateTimeAtom $birthDate, // nullable field
206-
public readonly ?NonNegativeFloat $heightM // nullable field
206+
public readonly ?FloatNonNegative $heightM // nullable field
207207
) {}
208208

209209
// Convenience named constructor that accepts raw scalars and builds primitives internally
@@ -216,12 +216,12 @@ final class Profile
216216
int|float|string|null $heightM
217217
): self {
218218
return new self(
219-
PositiveInt::fromInt($id),
220-
NonEmptyStr::fromString($firstName),
221-
NonEmptyStr::fromString($lastName),
222-
$middleName !== null ? NonEmptyStr::fromString($middleName) : null,
219+
IntegerPositive::fromInt($id),
220+
StringNonEmpty::fromString($firstName),
221+
StringNonEmpty::fromString($lastName),
222+
$middleName !== null ? StringNonEmpty::fromString($middleName) : null,
223223
$birthDateAtom !== null ? DateTimeAtom::fromString($birthDateAtom) : null,
224-
$heightM !== null ? NonNegativeFloat::fromString((string)$heightM) : null,
224+
$heightM !== null ? FloatNonNegative::fromString((string)$heightM) : null,
225225
);
226226
}
227227
}
@@ -237,10 +237,10 @@ $p1 = Profile::fromScalars(
237237
);
238238

239239
$p2 = new Profile(
240-
id: PositiveInt::fromInt(202),
241-
firstName: NonEmptyStr::fromString('Bob'),
242-
lastName: NonEmptyStr::fromString('Johnson'),
243-
middleName: NonEmptyStr::fromString('A.'),
240+
id: IntegerPositive::fromInt(202),
241+
firstName: StringNonEmpty::fromString('Bob'),
242+
lastName: StringNonEmpty::fromString('Johnson'),
243+
middleName: StringNonEmpty::fromString('A.'),
244244
birthDate: null,
245245
heightM: null,
246246
);

src/Code/Exception/ReasonableRangeDateTimeTypeException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44

55
namespace PhpTypedValues\Code\Exception;
66

7-
class ReasonableRangeDateTimeTypeException extends TypeException
7+
class ReasonableRangeDateTimeTypeException extends DateTimeTypeException
88
{
99
}

src/DateTime/Timestamp/TimestampMilliseconds.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ public function toString(): string
6666
$seconds = (int) $dt->format('U');
6767
$micros = (int) $dt->format('u');
6868

69-
$milliseconds = ($seconds * 1000) + intdiv($micros, 1000);
69+
// Using intdiv will throw a TypeError if $seconds is not an int, ensuring the cast is meaningful
70+
$milliseconds = (intdiv($seconds, 1) * 1000) + intdiv($micros, 1000);
7071

7172
return (string) $milliseconds;
7273
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Float\Alias;
6+
7+
use PhpTypedValues\Float\FloatNonNegative;
8+
9+
/**
10+
* @psalm-immutable
11+
*/
12+
readonly class NonNegativeFloat extends FloatNonNegative
13+
{
14+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/**
1313
* @psalm-immutable
1414
*/
15-
readonly class NonNegativeFloat extends FloatType
15+
readonly class FloatNonNegative extends FloatType
1616
{
1717
protected float $value;
1818

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*
1313
* @psalm-immutable
1414
*/
15-
readonly class FloatBasic extends FloatType
15+
readonly class FloatStandard extends FloatType
1616
{
1717
protected float $value;
1818

src/Integer/Alias/Id.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Integer\Alias;
6+
7+
use PhpTypedValues\Integer\IntegerPositive;
8+
9+
/**
10+
* @psalm-immutable
11+
*/
12+
readonly class Id extends IntegerPositive
13+
{
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Integer\Alias;
6+
7+
use PhpTypedValues\Integer\IntegerNonNegative;
8+
9+
/**
10+
* @psalm-immutable
11+
*/
12+
readonly class NonNegativeInt extends IntegerNonNegative
13+
{
14+
}

src/Integer/Alias/PositiveInt.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpTypedValues\Integer\Alias;
6+
7+
use PhpTypedValues\Integer\IntegerPositive;
8+
9+
/**
10+
* @psalm-immutable
11+
*/
12+
readonly class PositiveInt extends IntegerPositive
13+
{
14+
}

0 commit comments

Comments
 (0)