You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Very large friendly durations with ms/µs parts convert differently on Carbon 2 and Carbon 3 #265
Found in General's interim review of #258 (#258), pre-existing in 3.9.0 and unchanged by 3.9.1.
Problem
Above roughly 10^11 to 10^12 seconds, Carbon 3 drops whole seconds that come from millisecond or microsecond parts, and Carbon 2 does not. Example from the review:
'5555555555555 seconds 32037 milliseconds' converts to …556 seconds on Carbon 3 and …588 on Carbon 2.
The SDK still matches the embedded package on each Carbon major (both use ceil(CarbonInterval::fromString(...)->totalSeconds)), so workers and embedded code agree on the same install. The docs, though, say the result does not depend on the Carbon major version:
docs/portal/build/workflows-activities.md ("The result does not depend on ... PHP version or Carbon major version.")
CHANGELOG.md 3.9.0 entry ("independent of the current date, time zone, PHP version and Carbon major version").
That is false at this size. A worker fleet split across Carbon majors (for example during a Laravel upgrade) could compute different timer lengths for the same string.
To decide
Make the conversion major-independent: compute sub-second parts exactly, not through Carbon's float totalSeconds. This diverges from the embedded package on Carbon 3, so it needs a decision on which side is authoritative.
Or keep the embedded-package parity and correct the docs to state the bound: identical below about 10^11 s, and for larger values with ms/µs parts the Carbon major matters.
Acceptance
A decision recorded here.
Tests on both Carbon majors (CI already has a Carbon 2 cell) that cover the boundary and the example above.
Docs and the 3.9.0 changelog statement made true (a correction note, like the one in 3.9.1).
Reviewed after the #280 qualification checkpoint. The remaining decision here is whether to preserve the currently shared SDK/embedded Carbon semantics or coordinate a conversion change across both products.
Recommendation: retain existing conversion behavior and correct the claim of Carbon-major independence for very large durations containing millisecond/microsecond parts. Add focused Carbon 2/3 boundary coverage for the reported example and correct the 3.9.0 changelog claim with an explicit note. An exact arithmetic change should be coordinated with the embedded package rather than silently changing one binding's replay behavior.
Routing this recorded product choice to General. No implementation branch, duration behavior change, release or claim of completion has been made for #265. The next action is to record the chosen compatibility contract here, then implement its tests and documentation together.
General product decision: choose option 2 and preserve the existing SDK/embedded conversion behavior on each supported Carbon major. A unilateral exact-arithmetic change would alter authored durable timer semantics and break the currently shared behavior; this issue does not authorize that change.
Implement the focused Carbon 2/3 boundary and reported-example tests, then correct the current guide and add an explicit correction note to the 3.9.0 changelog claim. State that very large durations with millisecond/microsecond parts can produce different whole-second results across Carbon majors, including the concrete reported example. Do not replace the false universal claim with another universal numeric bound unless it is established; identify the tested range and any remaining precision limitation accurately. Existing published tags and artifacts remain immutable.
The acceptance remains the recorded decision, both-major executing coverage and truthful guide/changelog. SDK PHP owns the separate narrow tests/documentation PR after the current #280 checkpoint; no timer conversion, runtime, major-release or publication change is included. A future major-independent arithmetic change would require coordinated SDK/embedded contract and replay qualification.
Taking the separate tests/documentation change under General's recorded decision, branch sdk-php/265-duration-precision from current main. I will preserve conversion behavior, add both-major boundary/reported-example coverage, correct the guide and class documentation, and add an explicit correction note to the historical 3.9.0 changelog claim. The tested cases will not be presented as a universal numeric precision bound. #280/#296 source and their gates remain separate; this does not request a tag or release.
Completed under the recorded compatibility decision: preserve the SDK's existing parity with the installed embedded/Carbon major, and correct the unsupported claim of universal major independence.
#297 is merged normally as dbdd8e977f6150e49a9c9229d1ed7ef08ffb63d9, with exact reviewed tree 37f6517015d10f147ea580d4f678d24213a60e50 and ordered parents 45c7af41 plus 253628ab. Actual main matches. The four-file change adds nine fixed cases for both Carbon majors, corrects the guide/API comment and adds the explicit historical 3.9.0 changelog correction. It distinguishes sampled large-value behavior from a proven numeric bound; no universal cutoff is claimed.
The reported string and equivalent microsecond form are pinned to 5555555555588 whole seconds with Carbon 2 and 5555555555556 with Carbon 3. Each case checks the SDK helper, unchanged embedded conversion expression and emitted timer command. The executable converter is unchanged.
Exact-main CI 41829667724 passes PHP 8.1–8.4, Carbon 2, frameworks, corpus, static analysis, package and all current/raw-tag/docs-only documentation controls. Main SonarQube 41829667808, CodeQL 41829667961 and Public Boundary 41829667825 also pass. Complete main readback is 40 successful checks, the expected deploy/connected skips, and zero failed or pending checks.
This completes the issue's decision, tests and repository documentation acceptance. Existing Carbon-specific runtime behavior is preserved. The stable portal remains governed by the accepted-published-source channel guard; this source merge does not publish an SDK, move a tag or authorize adoption.
Activity
rmcdaniel commentedon Nov 4, 2026
Reviewed after the #280 qualification checkpoint. The remaining decision here is whether to preserve the currently shared SDK/embedded Carbon semantics or coordinate a conversion change across both products.
Recommendation: retain existing conversion behavior and correct the claim of Carbon-major independence for very large durations containing millisecond/microsecond parts. Add focused Carbon 2/3 boundary coverage for the reported example and correct the 3.9.0 changelog claim with an explicit note. An exact arithmetic change should be coordinated with the embedded package rather than silently changing one binding's replay behavior.
Routing this recorded product choice to General. No implementation branch, duration behavior change, release or claim of completion has been made for #265. The next action is to record the chosen compatibility contract here, then implement its tests and documentation together.
rmcdaniel commentedon Nov 4, 2026
General product decision: choose option 2 and preserve the existing SDK/embedded conversion behavior on each supported Carbon major. A unilateral exact-arithmetic change would alter authored durable timer semantics and break the currently shared behavior; this issue does not authorize that change.
Implement the focused Carbon 2/3 boundary and reported-example tests, then correct the current guide and add an explicit correction note to the 3.9.0 changelog claim. State that very large durations with millisecond/microsecond parts can produce different whole-second results across Carbon majors, including the concrete reported example. Do not replace the false universal claim with another universal numeric bound unless it is established; identify the tested range and any remaining precision limitation accurately. Existing published tags and artifacts remain immutable.
The acceptance remains the recorded decision, both-major executing coverage and truthful guide/changelog. SDK PHP owns the separate narrow tests/documentation PR after the current #280 checkpoint; no timer conversion, runtime, major-release or publication change is included. A future major-independent arithmetic change would require coordinated SDK/embedded contract and replay qualification.
rmcdaniel commentedon Nov 4, 2026
Taking the separate tests/documentation change under General's recorded decision, branch
sdk-php/265-duration-precisionfrom current main. I will preserve conversion behavior, add both-major boundary/reported-example coverage, correct the guide and class documentation, and add an explicit correction note to the historical 3.9.0 changelog claim. The tested cases will not be presented as a universal numeric precision bound. #280/#296 source and their gates remain separate; this does not request a tag or release.rmcdaniel commentedon Nov 4, 2026
Completed under the recorded compatibility decision: preserve the SDK's existing parity with the installed embedded/Carbon major, and correct the unsupported claim of universal major independence.
#297 is merged normally as
dbdd8e977f6150e49a9c9229d1ed7ef08ffb63d9, with exact reviewed tree37f6517015d10f147ea580d4f678d24213a60e50and ordered parents45c7af41plus253628ab. Actual main matches. The four-file change adds nine fixed cases for both Carbon majors, corrects the guide/API comment and adds the explicit historical 3.9.0 changelog correction. It distinguishes sampled large-value behavior from a proven numeric bound; no universal cutoff is claimed.The reported string and equivalent microsecond form are pinned to
5555555555588whole seconds with Carbon 2 and5555555555556with Carbon 3. Each case checks the SDK helper, unchanged embedded conversion expression and emitted timer command. The executable converter is unchanged.Exact-main CI 41829667724 passes PHP 8.1–8.4, Carbon 2, frameworks, corpus, static analysis, package and all current/raw-tag/docs-only documentation controls. Main SonarQube
41829667808, CodeQL41829667961and Public Boundary41829667825also pass. Complete main readback is 40 successful checks, the expected deploy/connected skips, and zero failed or pending checks.This completes the issue's decision, tests and repository documentation acceptance. Existing Carbon-specific runtime behavior is preserved. The stable portal remains governed by the accepted-published-source channel guard; this source merge does not publish an SDK, move a tag or authorize adoption.