Skip to content

Commit e8ebba0

Browse files
authored
Release/3.2.0 (#23)
* feat: Introduce CountryTimezones class and update timezone handling in Country.
1 parent 1aeeed5 commit e8ebba0

7 files changed

Lines changed: 50 additions & 204 deletions

File tree

README.md

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
* [Alpha3Code](#alpha3code)
1010
* [Country](#country-1)
1111
* [Timezones](#timezones)
12-
* [Timezone](#timezone)
1312
* [License](#license)
1413
* [Contributing](#contributing)
1514

@@ -141,8 +140,8 @@ $country->alpha3->value; # USA
141140

142141
### Timezones
143142

144-
Every `Country` includes an immutable `Timezones` collection, built from the IANA timezone database (via PHP's ICU
145-
integration).
143+
Every `Country` includes an immutable `CountryTimezones` collection, built from the IANA timezone database (via PHP's
144+
ICU integration).
146145

147146
```php
148147
use TinyBlocks\Country\Country;
@@ -160,6 +159,11 @@ $country->timezones->toStrings(); # ["America/Noronha", "America/Belem", "Ameri
160159
Returns all `Timezone` objects for the country:
161160

162161
```php
162+
use TinyBlocks\Country\Country;
163+
use TinyBlocks\Country\Alpha2Code;
164+
165+
$country = Country::from(alphaCode: Alpha2Code::BRAZIL);
166+
163167
$country->timezones->all(); # [Timezone("America/Noronha"), Timezone("America/Belem"), ...]
164168
```
165169

@@ -178,18 +182,18 @@ $country = Country::from(alphaCode: Alpha2Code::BOUVET_ISLAND);
178182
$country->timezones->default(); # Timezone("UTC")
179183
```
180184

181-
#### Finding a timezone by identifier
185+
#### Finding a timezone by identifier with UTC fallback
182186

183-
Searches for a specific IANA identifier within the country's timezones:
187+
Searches for a specific IANA identifier within the country's timezones. Returns UTC if not found.
184188

185189
```php
186190
use TinyBlocks\Country\Country;
187191
use TinyBlocks\Country\Alpha2Code;
188192

189193
$country = Country::from(alphaCode: Alpha2Code::UNITED_STATES_OF_AMERICA);
190194

191-
$country->timezones->findByIdentifier(iana: 'America/New_York'); # Timezone("America/New_York")
192-
$country->timezones->findByIdentifier(iana: 'Asia/Tokyo'); # null
195+
$country->timezones->findByIdentifierOrUtc(iana: 'America/New_York'); # Timezone("America/New_York")
196+
$country->timezones->findByIdentifierOrUtc(iana: 'Asia/Tokyo'); # Timezone("UTC")
193197
```
194198

195199
#### Checking if a timezone belongs to the country
@@ -204,29 +208,6 @@ $country->timezones->contains(iana: 'Asia/Tokyo'); # true
204208
$country->timezones->contains(iana: 'America/New_York'); # false
205209
```
206210

207-
### Timezone
208-
209-
A `Timezone` is a Value Object representing a single valid IANA timezone identifier.
210-
211-
```php
212-
use TinyBlocks\Country\Timezone;
213-
214-
$timezone = Timezone::from(identifier: 'America/Sao_Paulo');
215-
216-
$timezone->value; # America/Sao_Paulo
217-
$timezone->toString(); # America/Sao_Paulo
218-
```
219-
220-
Creating a UTC timezone:
221-
222-
```php
223-
use TinyBlocks\Country\Timezone;
224-
225-
$timezone = Timezone::utc();
226-
227-
$timezone->value; # UTC
228-
```
229-
230211
<div id='license'></div>
231212

232213
## License

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
},
4545
"require": {
4646
"php": "^8.5",
47+
"tiny-blocks/time": "^1.1",
4748
"tiny-blocks/value-object": "^3.2"
4849
},
4950
"require-dev": {

src/Country.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ private function __construct(
2525
public readonly string $name,
2626
public readonly Alpha2Code $alpha2,
2727
public readonly Alpha3Code $alpha3,
28-
public readonly Timezones $timezones
28+
public readonly CountryTimezones $timezones
2929
) {
3030
}
3131

@@ -55,7 +55,7 @@ public static function from(AlphaCode $alphaCode, ?string $name = null): static
5555
name: $resolvedName,
5656
alpha2: $alpha2,
5757
alpha3: $alpha3,
58-
timezones: Timezones::fromAlpha2(alpha2: $alpha2)
58+
timezones: CountryTimezones::fromAlpha2(alpha2: $alpha2)
5959
);
6060
}
6161

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,37 +6,38 @@
66

77
use Countable;
88
use TinyBlocks\Country\Internal\TimezoneCatalog;
9+
use TinyBlocks\Time\Timezone;
10+
use TinyBlocks\Time\Timezones;
11+
use TinyBlocks\Vo\ValueObject;
12+
use TinyBlocks\Vo\ValueObjectBehavior;
913

1014
/**
1115
* Immutable collection of Timezone objects for a country.
1216
*
1317
* Built from PHP's ICU/IANA timezone database — the authoritative source for timezone data.
1418
* The first element is considered the default/primary timezone for the country.
1519
*/
16-
final readonly class Timezones implements Countable
20+
final readonly class CountryTimezones implements ValueObject, Countable
1721
{
18-
/**
19-
* @param list<Timezone> $items All timezone objects for the country.
20-
* @param Timezone $default The default/primary timezone (first in the IANA list, or UTC as fallback).
21-
*/
22-
private function __construct(private array $items, private Timezone $default)
22+
use ValueObjectBehavior;
23+
24+
private function __construct(private Timezones $timezones, private Timezone $default)
2325
{
2426
}
2527

2628
/**
27-
* Creates a Timezones collection from an Alpha-2 country code.
29+
* Creates a CountryTimezones instance from an Alpha-2 country code.
2830
*
29-
* @param Alpha2Code $alpha2 The two-letter country code.
30-
* @return Timezones The timezones collection for the given country.
31+
* @param Alpha2Code $alpha2 The Alpha-2 country code (e.g. "US" for United States).
32+
* @return CountryTimezones A new CountryTimezones instance containing the timezones for the specified country.
3133
*/
32-
public static function fromAlpha2(Alpha2Code $alpha2): Timezones
34+
public static function fromAlpha2(Alpha2Code $alpha2): CountryTimezones
3335
{
34-
$items = array_map(
35-
static fn(string $id): Timezone => Timezone::from(identifier: $id),
36-
TimezoneCatalog::forAlpha2(alpha2Value: $alpha2->value)
37-
);
36+
$identifiers = TimezoneCatalog::forAlpha2(alpha2Value: $alpha2->value);
37+
$timezones = Timezones::fromStrings(...$identifiers);
38+
$default = $timezones->all()[0] ?? Timezone::utc();
3839

39-
return new Timezones(items: $items, default: $items[0] ?? Timezone::utc());
40+
return new CountryTimezones(timezones: $timezones, default: $default);
4041
}
4142

4243
/**
@@ -46,7 +47,7 @@ public static function fromAlpha2(Alpha2Code $alpha2): Timezones
4647
*/
4748
public function all(): array
4849
{
49-
return $this->items;
50+
return $this->timezones->all();
5051
}
5152

5253
/**
@@ -56,7 +57,7 @@ public function all(): array
5657
*/
5758
public function count(): int
5859
{
59-
return count($this->items);
60+
return $this->timezones->count();
6061
}
6162

6263
/**
@@ -73,43 +74,34 @@ public function default(): Timezone
7374
}
7475

7576
/**
76-
* Checks whether the given IANA identifier belongs to this country's timezones.
77+
* Returns all timezone identifiers as plain strings.
7778
*
78-
* @param string $iana The IANA timezone identifier to check (e.g. America/New_York).
79-
* @return bool True if the identifier belongs to this country, false otherwise.
79+
* @return list<string> The list of IANA timezone identifier strings.
8080
*/
81-
public function contains(string $iana): bool
81+
public function toStrings(): array
8282
{
83-
return array_any(
84-
$this->items,
85-
static fn(Timezone $timezone): bool => $timezone->value === $iana
86-
);
83+
return $this->timezones->toStrings();
8784
}
8885

8986
/**
90-
* Finds a Timezone by its IANA identifier.
87+
* Checks whether the given IANA identifier belongs to this country's timezones.
9188
*
92-
* @param string $iana The IANA timezone identifier to search for (e.g. America/Sao_Paulo).
93-
* @return Timezone The matching Timezone, or UTC if not found in this country.
89+
* @param string $iana The IANA timezone identifier to check (e.g. America/New_York).
90+
* @return bool True if the identifier belongs to this country, false otherwise.
9491
*/
95-
public function findByIdentifier(string $iana): Timezone
92+
public function contains(string $iana): bool
9693
{
97-
return array_find(
98-
$this->items,
99-
static fn(Timezone $timezone): bool => $timezone->value === $iana
100-
) ?? Timezone::utc();
94+
return $this->timezones->contains(iana: $iana);
10195
}
10296

10397
/**
104-
* Returns all timezone identifiers as plain strings.
98+
* Finds a Timezone object by its IANA identifier.
10599
*
106-
* @return list<string> The list of IANA timezone identifier strings.
100+
* @param string $iana The IANA timezone identifier to find (e.g. America/New_York).
101+
* @return Timezone The corresponding Timezone object if found, or UTC if not found.
107102
*/
108-
public function toStrings(): array
103+
public function findByIdentifierOrUtc(string $iana): Timezone
109104
{
110-
return array_map(
111-
static fn(Timezone $timezone): string => $timezone->toString(),
112-
$this->items
113-
);
105+
return $this->timezones->findByIdentifierOrUtc(iana: $iana);
114106
}
115107
}

src/Internal/Exceptions/InvalidTimezone.php

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/Timezone.php

Lines changed: 0 additions & 74 deletions
This file was deleted.

0 commit comments

Comments
 (0)