Feature parity with Carbon: missing methods and utilities
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 1.4k
- Forks
- 71
- Avg merge
- 1d 59m
- Merged PRs (30d)
- 2
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
- #498 -
withTestNow()for scoped time mocking - #499 - Zero interval validation for periods
- #500 - "just now" for zero-second differences
References
- Carbon comparison analysis
- Carbon documentation
- briannesbitt/Carbon#3283 - withTestNow fix
- briannesbitt/Carbon#3259 - Zero interval issue
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No implementation file, test, or entry point is named. Start by reviewing the Chronos API and the linked Carbon documentation, then narrow the wishlist to a specific method or coherent group. Done would require an agreed scope, implementation details, and tests for the selected additions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100