Skip to content

Stringifying

stringify() converts an RRuleOptions object back to a canonical RRULE string. It always includes the RRULE: prefix and emits parts in a fixed canonical order.

function stringify(options: RRuleOptions): string

The output always:

  • Starts with RRULE: (or a DTSTART line followed by RRULE: when dtstart is set)
  • Emits RRULE parts in this fixed order: FREQ, UNTIL, COUNT, INTERVAL, WKST, BYSECOND, BYMINUTE, BYHOUR, BYDAY, BYMONTHDAY, BYYEARDAY, BYWEEKNO, BYMONTH, BYSETPOS
  • Omits any part whose value is undefined in the options object

Example:

import { stringify } from 'rrule-ts'
stringify({
freq: 'WEEKLY',
byDay: [
{ weekday: 'MO', ordinal: undefined },
{ weekday: 'WE', ordinal: undefined },
{ weekday: 'FR', ordinal: undefined },
],
count: 10,
})
// 'RRULE:FREQ=WEEKLY;COUNT=10;BYDAY=MO,WE,FR'

COUNT appears before BYDAY in the output regardless of the order the fields appear in the options object: stringify always uses the canonical order.

Plain weekdays (no ordinal) serialize as their two-letter abbreviation. Ordinal weekdays include the ordinal prefix:

stringify({
freq: 'MONTHLY',
byDay: [
{ weekday: 'MO', ordinal: 2 }, // 2nd Monday
{ weekday: 'FR', ordinal: -1 }, // last Friday
],
})
// 'RRULE:FREQ=MONTHLY;BYDAY=2MO,-1FR'

When dtstart is present in the options, stringify() prepends a DTSTART content line. The RRULE: line follows on the next line. This layout matches the iCalendar multiline format and ensures parse(stringify(x)) deep-equals x for all valid x.

import { getTemporal } from 'rrule-ts'
const T = getTemporal()
// Date-only DTSTART
stringify({
freq: 'DAILY',
count: 5,
dtstart: T.PlainDate.from('2024-01-01'),
})
// 'DTSTART:20240101\nRRULE:FREQ=DAILY;COUNT=5'
// UTC datetime DTSTART
stringify({
freq: 'WEEKLY',
dtstart: T.Instant.from('2024-01-01T09:00:00Z'),
})
// 'DTSTART:20240101T090000Z\nRRULE:FREQ=WEEKLY'

For timezone-aware starts, the TZID= parameter is included:

stringify({
freq: 'WEEKLY',
dtstart: T.ZonedDateTime.from('2024-01-01T09:00:00[America/New_York]'),
tzid: 'America/New_York',
})
// 'DTSTART;TZID=America/New_York:20240101T090000\nRRULE:FREQ=WEEKLY'

For all valid RRuleOptions:

parse(stringify(x)).value deep-equals x

And for all valid RRULE strings that parse() accepts:

stringify(parse(s).value!) === stringify(parse(stringify(parse(s).value!)).value!)

Stringifying is idempotent: once a value has been parsed and stringified, stringifying the result again produces the same string.

stringify()toText()
OutputRRULE:FREQ=WEEKLY;COUNT=10;BYDAY=MO,WE,FRevery week on Monday, Wednesday, and Friday, 10 times
PurposeStorage, wire format, iCalendarUser-facing display
Round-tripYesNo (natural language loses information)
Locale supportNoYes (EN and DE built in)

Use stringify() when storing or transmitting the RRULE. Use toText() when displaying it to a user. See the toText and fromText guide.