diff --git a/src/Internal/Support/DateInterval.php b/src/Internal/Support/DateInterval.php index a56d6e20..893f064f 100644 --- a/src/Internal/Support/DateInterval.php +++ b/src/Internal/Support/DateInterval.php @@ -60,7 +60,21 @@ public static function parse(mixed $interval, string $format = self::FORMAT_MILL { switch (true) { case \is_string($interval): - return CarbonInterval::fromString($interval); + $carbon = CarbonInterval::fromString($interval); + if (self::isIso8601DurationFormat($interval)) { + $builtin = new \DateInterval($interval); + $carbon->compare($builtin) === 0 or \trigger_error( + \sprintf( + 'Ambiguous duration "%s": Carbon and DateInterval parse it differently. ' . + 'Use new \DateInterval("%s") for ISO 8601 standard parsing or PT/P prefix to clarify intent.', + $interval, + $interval, + ), + \E_USER_WARNING, + ); + } + + return $carbon; case $interval instanceof \DateInterval: return CarbonInterval::instance($interval); @@ -180,4 +194,27 @@ private static function validateFormat(string $format): void throw new \InvalidArgumentException($message); } } + + /** + * Checks if a string matches the ISO 8601 duration format that PHP's DateInterval constructor accepts. + * + * Valid format: P[n]Y[n]M[n]W[n]D[T[n]H[n]M[n]S] + * - Must start with P (period) + * - Date elements (Y, M, W, D) come before T + * - Time elements (H, M, S) come after T + * - At least one date or time element must be present + * - Alternative datetime format PT