diff --git a/packages/@internationalized/date/docs/CalendarDate.mdx b/packages/@internationalized/date/docs/CalendarDate.mdx
index ab51b533a97..4b8c48e10de 100644
--- a/packages/@internationalized/date/docs/CalendarDate.mdx
+++ b/packages/@internationalized/date/docs/CalendarDate.mdx
@@ -142,6 +142,16 @@ parseDuration('-P3Y6M6W4D');
// => {years: -3, months: -6, weeks: -6, days: -4}
```
+A object can be converted back to a [ISO 8601 duration string](https://en.wikipedia.org/wiki/ISO_8601#Durations) by using .
+
+```tsx
+durationToString({years: 3, months: 6, weeks: 6, days: 4});
+// => 'P3Y6M6W4D'
+
+durationToString({years: -3, months: -6, weeks: -6, days: -4});
+// => '-P3Y6M6W4D'
+```
+
### Setting fields
`CalendarDate` objects are immutable, which means their properties cannot be set directly. Instead, use the `set` method, and pass the fields to be modified. This will return a new `CalendarDate` with the updated values.
diff --git a/packages/@internationalized/date/docs/CalendarDateTime.mdx b/packages/@internationalized/date/docs/CalendarDateTime.mdx
index 3796777ed49..195b47c6303 100644
--- a/packages/@internationalized/date/docs/CalendarDateTime.mdx
+++ b/packages/@internationalized/date/docs/CalendarDateTime.mdx
@@ -143,6 +143,19 @@ parseDuration('P3Y6M6W4DT12H30M5.5S');
// => {years: 3, months: 6, weeks: 6, days: 4, hours: 12, minutes: 30, seconds: 5.5}
```
+A object can be converted back to a [ISO 8601 duration string](https://en.wikipedia.org/wiki/ISO_8601#Durations) by using .
+
+```tsx
+durationToString({years: 3, months: 6, weeks: 6, days: 4, hours: 12, minutes: 30, seconds: 5});
+// => 'P3Y6M6W4DT12H30M5S'
+
+durationToString({years: -3, months: -6, weeks: -6, days: -4, hours: -12, minutes: -30, seconds: -5});
+// => '-P3Y6M6W4DT12H30M5S'
+
+durationToString({years: 3, months: 6, weeks: 6, days: 4, hours: 12, minutes: 30, seconds: 5.5});
+// => 'P3Y6M6W4DT12H30M5.5S'
+```
+
### Setting fields
`CalendarDateTime` objects are immutable, which means their properties cannot be set directly. Instead, use the `set` method, and pass the fields to be modified. This will return a new `CalendarDateTime` with the updated values.
diff --git a/packages/@internationalized/date/docs/Time.mdx b/packages/@internationalized/date/docs/Time.mdx
index 0a6d7f59e94..3e59b55a23f 100644
--- a/packages/@internationalized/date/docs/Time.mdx
+++ b/packages/@internationalized/date/docs/Time.mdx
@@ -89,6 +89,19 @@ parseDuration('PT20H35M15,75S')
// => {hours: 20, minutes: 35, seconds: 15.75}
```
+A object can be converted back to a [ISO 8601 duration string](https://en.wikipedia.org/wiki/ISO_8601#Durations) by using .
+
+```tsx
+durationToString({hours: 20, minutes: 35, seconds: 15})
+// => 'PT20H35M15S'
+
+durationToString({hours: -20, minutes: -35, seconds: -15})
+// => '-PT20H35M15S'
+
+durationToString({hours: 20, minutes: 35, seconds: 15.75})
+// => 'PT20H35M15,75S'
+```
+
### Setting fields
`Time` objects are immutable, which means their properties cannot be set directly. Instead, use the `set` method, and pass the fields to be modified. This will return a new `Time` with the updated values.
diff --git a/packages/@internationalized/date/docs/ZonedDateTime.mdx b/packages/@internationalized/date/docs/ZonedDateTime.mdx
index 543f89db6dd..e4ab716dd8f 100644
--- a/packages/@internationalized/date/docs/ZonedDateTime.mdx
+++ b/packages/@internationalized/date/docs/ZonedDateTime.mdx
@@ -213,6 +213,19 @@ parseDuration('P3Y6M6W4DT12H30M5.5S');
// => {years: 3, months: 6, weeks: 6, days: 4, hours: 12, minutes: 30, seconds: 5.5}
```
+A object can be converted back to a [ISO 8601 duration string](https://en.wikipedia.org/wiki/ISO_8601#Durations) by using .
+
+```tsx
+durationToString({years: 3, months: 6, weeks: 6, days: 4, hours: 12, minutes: 30, seconds: 5});
+// => 'P3Y6M6W4DT12H30M5S'
+
+durationToString({years: -3, months: -6, weeks: -6, days: -4, hours: -12, minutes: -30, seconds: -5});
+// => '-P3Y6M6W4DT12H30M5S'
+
+durationToString({years: 3, months: 6, weeks: 6, days: 4, hours: 12, minutes: 30, seconds: 5.5});
+// => 'P3Y6M6W4DT12H30M5.5S'
+```
+
### Setting fields
`ZonedDateTime` objects are immutable, which means their properties cannot be set directly. Instead, use the `set` method, and pass the fields to be modified. This will return a new `ZonedDateTime` with the updated values.
diff --git a/packages/@internationalized/date/src/index.ts b/packages/@internationalized/date/src/index.ts
index 9fed618bc02..248470c3496 100644
--- a/packages/@internationalized/date/src/index.ts
+++ b/packages/@internationalized/date/src/index.ts
@@ -83,6 +83,7 @@ export {
parseAbsolute,
parseAbsoluteToLocal,
parseZonedDateTime,
- parseDuration
+ parseDuration,
+ durationToString
} from './string';
export {DateFormatter} from './DateFormatter';
diff --git a/packages/@internationalized/date/src/string.ts b/packages/@internationalized/date/src/string.ts
index 04a7d3d8b40..804ff7d4798 100644
--- a/packages/@internationalized/date/src/string.ts
+++ b/packages/@internationalized/date/src/string.ts
@@ -23,7 +23,7 @@ const DATE_TIME_RE = /^([+-]\d{6}|\d{4})-(\d{2})-(\d{2})(?:T(\d{2}))?(?::(\d{2})
const ZONED_DATE_TIME_RE = /^([+-]\d{6}|\d{4})-(\d{2})-(\d{2})(?:T(\d{2}))?(?::(\d{2}))?(?::(\d{2}))?(\.\d+)?(?:([+-]\d{2})(?::?(\d{2}))?)?\[(.*?)\]$/;
const ABSOLUTE_RE = /^([+-]\d{6}|\d{4})-(\d{2})-(\d{2})(?:T(\d{2}))?(?::(\d{2}))?(?::(\d{2}))?(\.\d+)?(?:(?:([+-]\d{2})(?::?(\d{2}))?)|Z)$/;
const DATE_TIME_DURATION_RE =
- /^((?-)|\+)?P((?\d*)Y)?((?\d*)M)?((?\d*)W)?((?\d*)D)?((?