-
Notifications
You must be signed in to change notification settings - Fork 69
Open
Milestone
Description
Summary
After a comprehensive comparison with Carbon, here are features that could be valuable additions to Chronos while maintaining its minimal, immutable-only philosophy.
So:
Which of the following are useful enough to warrant their implementation?
It helps to close the gap, but at the same time we only want to include actually useful things.
Very High Priority (Quick Wins)
These are small, high-value additions:
Factory Methods
-
createFromTimestampMs(int $timestamp)- Create from millisecond timestamp (JavaScript interop) -
createFromTimestampMsUTC(int $timestamp)- Create from ms timestamp in UTC
Validation
-
hasFormat(string $date, string $format): bool- Check if string matches a date format -
canBeCreatedFromFormat(string $date, string $format): bool- Validate format match without throwing
Serialization
-
toArray(): array- Convert to associative array (['year' => 2024, 'month' => 1, ...]) -
toIso8601ZuluString(): string- UTC ISO8601 withZsuffix (common for APIs) -
toDateTimeLocalString(): string- HTML5datetime-localinput format
Timezone
-
utc(): static- Convenience method for->setTimezone('UTC') -
shiftTimezone(DateTimeZone|string $tz): static- Change timezone keeping local time (different fromsetTimezonewhich converts)
Boundary Methods
-
startOfHour(): static- Reset to hour start (X:00:00) -
endOfHour(): static- Set to hour end (X:59:59.999999)
Comparison Methods
-
isStartOfDay(): bool- Check if time is 00:00:00 -
isEndOfDay(): bool- Check if time is 23:59:59 -
isMidnight(): bool- Alias for isStartOfDay -
isMidday(): bool- Check if time is 12:00:00
High Priority
Rounding Methods
-
round(string $unit, int $precision = 1): static- Round to nearest unit -
floor(string $unit, int $precision = 1): static- Floor to unit -
ceil(string $unit, int $precision = 1): static- Ceil to unit
Safe Creation
-
createSafe(int $year, int $month, int $day, ...): static- Throws on invalid dates instead of silent overflow (e.g., Feb 31 throws instead of becoming Mar 3)
Difference Methods
-
diffInMilliseconds(?DateTimeInterface $other = null, bool $absolute = true): int -
diffInMicroseconds(?DateTimeInterface $other = null, bool $absolute = true): int
DST-Safe Operations
-
addRealUnit(string $unit, int $value): static- Add without DST adjustment -
subRealUnit(string $unit, int $value): static- Subtract without DST adjustment
Navigation
-
nextWeekday(): static- Move to next Monday-Friday -
previousWeekday(): static- Move to previous Monday-Friday -
nextWeekendDay(): static- Move to next Saturday/Sunday -
previousWeekendDay(): static- Move to previous Saturday/Sunday
Generic Boundary Methods
-
startOf(string $unit): static- Generic start of any unit -
endOf(string $unit): static- Generic end of any unit -
isStartOf(string $unit): bool- Check if at start of unit -
isEndOf(string $unit): bool- Check if at end of unit
Medium Priority
Comparison Methods
-
isNowOrFuture(): bool- True if now or in the future -
isNowOrPast(): bool- True if now or in the past -
isLongYear(): bool- Check if year has 53 weeks -
isSameQuarter(DateTimeInterface $date, bool $ofSameYear = true): bool -
isSameUnit(string $unit, DateTimeInterface $date): bool- Generic same-unit check
Properties
-
$daysInYearproperty - Days in the year (365 or 366) -
$dayOfYearproperty - Day of year (1-366)
Serialization
-
getTimestampMs(): int- Millisecond timestamp -
valueOf(): int- JavaScript Date valueOf (ms timestamp) -
toObject(): stdClass- Convert to stdClass
Calendar Format
-
calendar(?DateTimeInterface $referenceTime = null): string- Calendar-relative format ("Today at 2:00 PM", "Yesterday at 3:00 PM", "Last Monday")
Lower Priority (Specialized)
Precision Support
-
toTimeString(string $precision = 'second'): string- Time with precision (minute/second/ms/us) -
toDateTimeString(string $precision = 'second'): string- DateTime with precision
Additional Boundaries
-
startOfMinute(): static/endOfMinute(): static -
startOfSecond(): static/endOfSecond(): static -
midDay(): static- Set to 12:00:00
Out of Scope (By Design)
These Carbon features are intentionally not planned for Chronos to maintain its minimal footprint:
- ❌ Macro system (
macro(),mixin()) - ❌ 824 locale files - Chronos has basic English only
- ❌ Mutable class - Chronos is immutable-only
- ❌ CarbonInterval - Chronos uses plain DateInterval
- ❌ Full localization with Symfony Translation
- ❌ PHP 8.1 Unit/WeekDay/Month enums
Related PRs
- Add withTestNow() for scoped time mocking #498 -
withTestNow()for scoped time mocking - Prevent infinite loops from zero-interval DatePeriods #499 - Zero interval validation for periods
- 4.x: Return 'just now' for zero-second differences #500 - "just now" for zero-second differences
References
- Carbon comparison analysis
- Carbon documentation
- briannesbitt/Carbon#3283 - withTestNow fix
- briannesbitt/Carbon#3259 - Zero interval issue
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels