Skip to content

Support casting strings to durations - #10516

Open
mayank172900 wants to merge 1 commit into
apache:mainfrom
mayank172900:parse-string-durations
Open

Support casting strings to durations#10516
mayank172900 wants to merge 1 commit into
apache:mainfrom
mayank172900:parse-string-durations

Conversation

@mayank172900

@mayank172900 mayank172900 commented Aug 2, 2026

Copy link
Copy Markdown

Which issue does this PR close?

Rationale for this change

arrow-cast can format durations as strings but does not currently support casting those strings back to duration arrays. This leaves duration casts asymmetric and prevents round-tripping formatted values.

What changes are included in this PR?

  • Allow Utf8, LargeUtf8, and Utf8View values to cast to all four duration units.
  • Parse human-readable interval-style durations and the ISO 8601 representation emitted by the duration formatter.
  • Treat unitless integers as values in the target duration unit.
  • Reject year and month fields because they do not have fixed durations.
  • Preserve safe-cast behavior by converting invalid inputs to nulls and returning errors for unsafe casts.

Are these changes tested?

Yes. Tests cover all duration units, all supported string representations, safe and unsafe behavior, invalid calendar units, and ISO 8601 and pretty-format round trips.

Validation performed:

  • cargo test -p arrow-cast --lib (363 passed)
  • cargo clippy -p arrow-cast --lib --tests -- -D warnings
  • cargo fmt --all -- --check

Are there any user-facing changes?

Yes. Users can now cast string arrays to duration arrays. This adds functionality without changing an existing public API.

Tooling disclosure

Generative tooling assisted with the parser implementation, cast dispatch arms, tests, and PR wording. The full patch was locally reviewed and verified with the checks above.

@github-actions github-actions Bot added arrow Changes to the arrow crate arrow-cast labels Aug 2, 2026
@mayank172900
mayank172900 marked this pull request as ready for review August 2, 2026 07:48
@mayank172900
mayank172900 force-pushed the parse-string-durations branch from ecf088d to a955790 Compare August 2, 2026 07:53
@Jefffrey Jefffrey added the enhancement Any new improvement worthy of a entry in the changelog label Aug 3, 2026
None,
];

macro_rules! test_duration {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this macro can probably be a generic

Comment thread arrow-cast/src/parse.rs
Comment on lines +1113 to +1116
// Preserve the full i64 range for the common case of a unitless integer.
if let Ok(value) = value.parse::<i64>() {
return Ok(value);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure about this behaviour as it does seem a bit implicit 🤔

Comment thread arrow-cast/src/parse.rs
Comment on lines +1118 to +1136
// Duration display currently emits ISO 8601 values as a number of seconds,
// for example `PT1.5S` or `-PT1.5S`. Convert this to the interval parser's
// human-readable syntax so both representations share the same validation.
let normalized;
let value = if let Some(seconds) = value
.strip_prefix("PT")
.and_then(|value| value.strip_suffix('S'))
{
normalized = format!("{seconds} seconds");
normalized.as_str()
} else if let Some(seconds) = value
.strip_prefix("-PT")
.and_then(|value| value.strip_suffix('S'))
{
normalized = format!("-{seconds} seconds");
normalized.as_str()
} else {
value
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to consider other designators such as hours, minutes, etc.?

also is this possible to parse directly without reconstructing a string to pass through the interval parser?

Comment thread arrow-cast/src/parse.rs
)
}) {
return Err(ArrowError::CastError(format!(
"Cannot cast {value} to {}. Year and month fields are not supported.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably need the error message to be more generic here, as it disallows century, decade, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrow Changes to the arrow crate arrow-cast enhancement Any new improvement worthy of a entry in the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parse Durations From String

2 participants