Skip to content

Feature parity with Carbon: missing methods and utilities #501

@dereuromark

Description

@dereuromark

Summary

After a comprehensive comparison with Carbon, here are features that could be valuable additions to Chronos while maintaining its minimal, immutable-only philosophy.


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 with Z suffix (common for APIs)
  • toDateTimeLocalString(): string - HTML5 datetime-local input format

Timezone

  • utc(): static - Convenience method for ->setTimezone('UTC')
  • shiftTimezone(DateTimeZone|string $tz): static - Change timezone keeping local time (different from setTimezone which 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

  • $daysInYear property - Days in the year (365 or 366)
  • $dayOfYear property - 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


References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions