Skip to content
This repository was archived by the owner on Nov 20, 2025. It is now read-only.

Commit 3c81454

Browse files
committed
Remove floating flag, use absense of timezone instead
1 parent e4b1533 commit 3c81454

10 files changed

Lines changed: 29 additions & 40 deletions

src/optionstostring.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ export function optionsToString (options: Partial<Options>) {
6868
break
6969

7070
case 'DTVALUE':
71-
case 'DTFLOATING':
7271
break
7372

7473
case 'UNTIL':
@@ -87,7 +86,7 @@ export function optionsToString (options: Partial<Options>) {
8786
if (options.dtvalue === DateTimeValue.DATE) {
8887
outValue = dateutil.toRfc5545Date(value)
8988
} else {
90-
outValue = dateutil.toRfc5545DateTime(value, !options.dtfloating)
89+
outValue = dateutil.toRfc5545DateTime(value, !!options.tzid)
9190
}
9291
break
9392

@@ -125,7 +124,7 @@ function formatDateTime (dt?: number, options: Partial<Options> = {}, prop = Dat
125124
if (options.dtvalue) {
126125
prefix += ';VALUE=' + options.dtvalue.toString()
127126
}
128-
if (options.dtfloating) {
127+
if (!options.tzid) {
129128
if (options.dtvalue === DateTimeValue.DATE) {
130129
return prefix + ':' + dateutil.toRfc5545Date(dt)
131130
} else {

src/parsestring.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,6 @@ export function parseString (rfcString: string): Partial<Options> {
4141
} else if (existing && acc.tzid !== cur.tzid) {
4242
// Different timezones.
4343
throw new Error('Invalid rule: DTSTART and DTEND must have the same timezone')
44-
} else if (existing && acc.dtfloating !== cur.dtfloating) {
45-
// Different floating types.
46-
throw new Error('Invalid rule: DTSTART and DTEND must both be floating')
4744
}
4845
return Object.assign(acc, cur)
4946
}, {}) || {}
@@ -78,7 +75,6 @@ export function parseDateTime (line: string, prop = DateTimeProperty.START): Par
7875
options.dtend = dateutil.fromRfc5545Date(dt)
7976
}
8077
options.dtvalue = DateTimeValue.DATE
81-
options.dtfloating = true
8278
if (options.tzid) {
8379
throw new Error(`Invalid date value with timezone: ${line}`)
8480
}
@@ -91,9 +87,6 @@ export function parseDateTime (line: string, prop = DateTimeProperty.START): Par
9187
if (dtvalue) {
9288
options.dtvalue = DateTimeValue.DATE_TIME
9389
}
94-
if (!tzid && !dt.endsWith('Z')) {
95-
options.dtfloating = true
96-
}
9790
}
9891

9992
return options
@@ -159,14 +152,11 @@ function parseRrule (line: string) {
159152
case 'DTSTART':
160153
case 'TZID':
161154
// for backwards compatibility
162-
const dtstart = parseDateTime(line)
163-
options.tzid = dtstart.tzid
164-
options.dtstart = dtstart.dtstart
165-
if (dtstart.dtvalue) {
166-
options.dtvalue = dtstart.dtvalue
167-
}
168-
if (dtstart.dtfloating) {
169-
options.dtfloating = dtstart.dtfloating
155+
const parsed = parseDateTime(line)
156+
options.tzid = parsed.tzid
157+
options.dtstart = parsed.dtstart
158+
if (parsed.dtvalue) {
159+
options.dtvalue = parsed.dtvalue
170160
}
171161
break
172162
case 'UNTIL':

src/rrule.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ export const DEFAULT_OPTIONS: Options = {
4545
dtstart: null,
4646
dtend: null,
4747
dtvalue: DateTimeValue.DATE_TIME,
48-
dtfloating: false,
4948
interval: 1,
5049
wkst: Days.MO,
5150
count: null,

src/rruleset.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,10 @@ export default class RRuleSet extends RRule {
142142
let result: string[] = []
143143

144144
if (!this._rrule.length && this._dtstart) {
145-
result = result.concat(optionsToString({ dtstart: this._dtstart }))
145+
result = result.concat(optionsToString({ dtstart: this._dtstart, tzid: this._tzid }))
146146
}
147147
if (!this._rrule.length && this._dtend) {
148-
result = result.concat(optionsToString({ dtend: this._dtend }))
148+
result = result.concat(optionsToString({ dtend: this._dtend, tzid: this._tzid }))
149149
}
150150

151151
this._rrule.forEach(function (rrule) {

src/rrulestr.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ export interface RRuleStrOptions {
99
dtstart: Date | null
1010
dtend: Date | null
1111
dtvalue: DateTimeValue | null
12-
dtfloating: boolean | null
1312
cache: boolean
1413
unfold: boolean
1514
forceset: boolean
@@ -25,7 +24,6 @@ const DEFAULT_OPTIONS: RRuleStrOptions = {
2524
dtstart: null,
2625
dtend: null,
2726
dtvalue: null,
28-
dtfloating: false,
2927
cache: false,
3028
unfold: false,
3129
forceset: false,
@@ -39,7 +37,7 @@ export function parseInput (s: string, options: Partial<RRuleStrOptions>) {
3937
let exrulevals: Partial<Options>[] = []
4038
let exdatevals: Date[] = []
4139

42-
let { dtstart, dtfloating, dtvalue, tzid } = parseDateTime(s)
40+
let { dtstart, dtvalue, tzid } = parseDateTime(s)
4341
let dtend: Date | null = null
4442

4543
const lines = splitIntoLines(s, options.unfold)
@@ -95,9 +93,6 @@ export function parseInput (s: string, options: Partial<RRuleStrOptions>) {
9593
} else if (dtstart && tzid !== parsed.tzid) {
9694
// Different timezones.
9795
throw new Error('Invalid rule: DTSTART and DTEND must have the same timezone')
98-
} else if (dtstart && dtfloating !== parsed.dtfloating) {
99-
// Different floating types.
100-
throw new Error('Invalid rule: DTSTART and DTEND must both be floating')
10196
}
10297
dtend = parsed.dtend
10398
}
@@ -112,7 +107,6 @@ export function parseInput (s: string, options: Partial<RRuleStrOptions>) {
112107
dtstart,
113108
dtend,
114109
dtvalue,
115-
dtfloating,
116110
tzid,
117111
rrulevals,
118112
rdatevals,
@@ -130,7 +124,6 @@ function buildRule (s: string, options: Partial<RRuleStrOptions>) {
130124
dtstart,
131125
dtend,
132126
dtvalue,
133-
dtfloating,
134127
tzid
135128
} = parseInput(s, options)
136129

@@ -157,7 +150,7 @@ function buildRule (s: string, options: Partial<RRuleStrOptions>) {
157150
rrulevals.forEach(val => {
158151
rset.rrule(
159152
new RRule(
160-
groomRruleOptions(val, dtstart, dtend, dtvalue, dtfloating, tzid),
153+
groomRruleOptions(val, dtstart, dtend, dtvalue, tzid),
161154
noCache
162155
)
163156
)
@@ -170,7 +163,7 @@ function buildRule (s: string, options: Partial<RRuleStrOptions>) {
170163
exrulevals.forEach(val => {
171164
rset.exrule(
172165
new RRule(
173-
groomRruleOptions(val, dtstart, dtend, dtvalue, dtfloating, tzid),
166+
groomRruleOptions(val, dtstart, dtend, dtvalue, tzid),
174167
noCache
175168
)
176169
)
@@ -190,7 +183,6 @@ function buildRule (s: string, options: Partial<RRuleStrOptions>) {
190183
val.dtstart || options.dtstart || dtstart,
191184
val.dtend || options.dtend || dtend,
192185
val.dtvalue || options.dtvalue || dtvalue,
193-
val.dtfloating || options.dtfloating || dtfloating,
194186
val.tzid || options.tzid || tzid
195187
), noCache)
196188
}
@@ -202,13 +194,12 @@ export function rrulestr (
202194
return buildRule(s, initializeOptions(options))
203195
}
204196

205-
function groomRruleOptions (val: Partial<Options>, dtstart?: Date | null, dtend?: Date | null, dtvalue?: DateTimeValue | null, dtfloating?: boolean | null, tzid?: string | null) {
197+
function groomRruleOptions (val: Partial<Options>, dtstart?: Date | null, dtend?: Date | null, dtvalue?: DateTimeValue | null, tzid?: string | null) {
206198
return {
207199
...val,
208200
dtstart,
209201
dtend,
210202
dtvalue,
211-
dtfloating,
212203
tzid
213204
}
214205
}

src/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export interface Options {
3939
dtstart: Date | null
4040
dtend: Date | null
4141
dtvalue: DateTimeValue | null
42-
dtfloating: boolean | null
4342
interval: number
4443
wkst: Weekday | number | null
4544
count: number | null

test/optionstostring.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,17 @@ import { expect } from "chai";
66
describe('optionsToString', () => {
77
it('serializes valid single lines of rrules', function () {
88
const expectations: ([ Partial<Options>, string ][]) = [
9-
[{ freq: RRule.WEEKLY, until: new Date(Date.UTC(2010, 0, 1, 0, 0, 0)) }, 'RRULE:FREQ=WEEKLY;UNTIL=20100101T000000Z' ],
9+
[{ freq: RRule.WEEKLY, until: new Date(Date.UTC(2010, 0, 1, 0, 0, 0)) }, 'RRULE:FREQ=WEEKLY;UNTIL=20100101T000000' ],
10+
[{ freq: RRule.WEEKLY, until: new Date(Date.UTC(2010, 0, 1, 0, 0, 0)), tzid: 'UTC' }, 'RRULE:FREQ=WEEKLY;UNTIL=20100101T000000Z' ],
11+
[{ dtstart: new Date(Date.UTC(1997, 8, 2, 9, 0, 0)) }, 'DTSTART:19970902T090000' ],
1012
[{ dtstart: new Date(Date.UTC(1997, 8, 2, 9, 0, 0)), tzid: 'America/New_York' }, 'DTSTART;TZID=America/New_York:19970902T090000' ],
1113
[
1214
{ dtstart: new Date(Date.UTC(1997, 8, 2, 9, 0, 0)), freq: RRule.WEEKLY },
15+
'DTSTART:19970902T090000\n' +
16+
'RRULE:FREQ=WEEKLY'
17+
],
18+
[
19+
{ dtstart: new Date(Date.UTC(1997, 8, 2, 9, 0, 0)), tzid: 'UTC', freq: RRule.WEEKLY },
1320
'DTSTART:19970902T090000Z\n' +
1421
'RRULE:FREQ=WEEKLY'
1522
],
@@ -19,7 +26,7 @@ describe('optionsToString', () => {
1926
'RRULE:FREQ=WEEKLY'
2027
],
2128
[
22-
{ dtstart: new Date(Date.UTC(1997, 8, 2, 9, 0, 0)), dtend: new Date(Date.UTC(1997, 8, 3, 9, 0, 0)), freq: RRule.WEEKLY },
29+
{ dtstart: new Date(Date.UTC(1997, 8, 2, 9, 0, 0)), dtend: new Date(Date.UTC(1997, 8, 3, 9, 0, 0)), tzid: 'UTC', freq: RRule.WEEKLY },
2330
'DTSTART:19970902T090000Z\n' +
2431
'DTEND:19970903T090000Z\n' +
2532
'RRULE:FREQ=WEEKLY'

test/rrule.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3505,6 +3505,7 @@ describe('RRule', function () {
35053505
[6, RRule.SU].forEach(function (wkst) {
35063506
const rr = new RRule({
35073507
dtstart: new Date(Date.UTC(2017, 9, 17, 0, 30, 0, 0)),
3508+
tzid: 'UTC',
35083509
until: new Date(Date.UTC(2017, 11, 22, 1, 30, 0, 0)),
35093510
freq: RRule.MONTHLY,
35103511
interval: 1,
@@ -3643,7 +3644,7 @@ describe('RRule', function () {
36433644
const ruleString = rrule.toString()
36443645
const rrule2 = RRule.fromString(ruleString)
36453646

3646-
expect(ruleString).to.equal('DTSTART:09900101T000000Z\nRRULE:COUNT=1')
3647+
expect(ruleString).to.equal('DTSTART:09900101T000000\nRRULE:COUNT=1')
36473648
expect(rrule2.count()).to.equal(1)
36483649
expect(rrule2.all()).to.deep.equal([
36493650
new Date(Date.UTC(990, 0, 1, 0, 0, 0))

test/rruleset.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,8 @@ describe('RRuleSet', function () {
366366
set.rrule(new RRule({
367367
freq: RRule.YEARLY,
368368
count: 2,
369-
dtstart: parse('19600101T090000')
369+
dtstart: parse('19600101T090000'),
370+
tzid: 'UTC'
370371
}))
371372

372373
expect(set.valueOf()).to.deep.equal([
@@ -381,7 +382,8 @@ describe('RRuleSet', function () {
381382
set.rrule(new RRule({
382383
freq: RRule.YEARLY,
383384
count: 2,
384-
dtstart: parse('19600101T090000')
385+
dtstart: parse('19600101T090000'),
386+
tzid: 'UTC'
385387
}))
386388

387389
set.rrule(new RRule({

test/rrulestr.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ describe('rrulestr', function () {
3131
const parsedRRuleSet = rrulestr(
3232
rRuleString, { forceset: true }
3333
) as RRuleSet;
34+
console.log(parsedRRuleSet)
3435
expect(parsedRRuleSet.toString()).to.be.equal(rRuleString);
3536

3637
const parsedRRule = rrulestr(rRuleString) as RRule;

0 commit comments

Comments
 (0)