From fb2b996b15210f397a149d8ada0aee4ab2a908c4 Mon Sep 17 00:00:00 2001 From: Xuezheng Ma Date: Fri, 18 Mar 2016 16:56:10 -0500 Subject: [PATCH 1/4] added rules for weekday & month --- lib/parser.pegjs | 115 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 18 deletions(-) diff --git a/lib/parser.pegjs b/lib/parser.pegjs index c72ef8d..f6f6e39 100644 --- a/lib/parser.pegjs +++ b/lib/parser.pegjs @@ -135,11 +135,11 @@ DurationString DurationAbbrev = "ms" / "s" - / "m" + / "m" !"o" / "h" / "d" / "w" - + CalendarUnit = string:CalendarString "s" { return string; @@ -159,6 +159,33 @@ CalendarAbbrev / "M" / "y" +Weekday + = ( "monday" / "Monday" / "Mon" / "mon" ) { return 1 } + / ( "tuesday" / "Tuesday" / "Tue" / "tue") { return 2 } + / ( "wednesday"/ "Wednesday" / "Wed" / "wed") { return 3 } + / ( "thursday"/ "Thursday" / "Thu" / "thu") { return 4 } + / ( "friday"/ "Friday" / "Fri" / "fri") { return 5 } + / ( "saturday"/ "Saturday" / "Sat" / "sat") { return 6 } + / ( "sunday"/ "Sunday" / "Sun" / "sun") { return 7 } + +Month + = ( "january"/ "January"/ "jan"/ "Jan") { return 1 } + / ("february"/ "February"/ "feb"/ "Feb") { return 2 } + / ("march"/ "March"/ "mar"/ "Mar") { return 3 } + / ("april"/ "April"/ "apr"/ "Apr") { return 4 } + / ("may"/ "May") { return 5 } + / ("june"/ "June"/ "jun"/ "Jun") { return 6 } + / ("july"/ "July"/ "jul"/ "Jul") { return 7 } + / ("august"/ "August"/ "aug"/ "Aug") { return 8 } + / ("september"/ "September"/ "sep"/ "Sep") { return 9 } + / ("october"/ "October"/ "oct"/ "Oct") { return 10 } + / ("november"/ "November"/ "nov"/ "Nov") { return 11 } + / ("december"/ "December"/ "dec"/ "Dec") { return 12 } + + +Unit = CalendarUnit / DurationUnit + + HumanDuration = num:Integer? _ unit:CalendarUnit { return { @@ -246,26 +273,16 @@ CalendarExpression valueType: "moment" }; } - / "this" _ unit:( CalendarUnit / DurationUnit ) { + / "next" _ unit:Unit { + var wdawd return { type: "CalendarExpression", valueType: "moment", direction: "down", - unit: unit, - expression: { - type: "NowLiteral" - } - }; - } - / "last" _ unit:( CalendarUnit / DurationUnit ) { - return { - type: "CalendarExpression", - valueType: "moment", - direction: "down", - unit: unit, + unit: unit.unit, expression: { type: "BinaryExpression", - operator: "-", + operator: "+", left: { type: "NowLiteral" }, @@ -277,7 +294,67 @@ CalendarExpression } }; } - / "next" _ unit:( CalendarUnit / DurationUnit ) { + / month: Month { + return { + modifier: "", + type: "monthLiteration", + value: month + } + } + + / "next" _ month: Month { + return { + modifier: "next", + type: "monthLiteration", + value: month + } + } + + / "this" _ month: Month { + return { + modifier: "this", + type: "monthLiteration", + value: month + } + } + / weekday: Weekday { + return { + modifier: "", + type: "weekdayLiteration", + value: weekday + } + } + + / "next" _ weekday: Weekday { + return { + modifier: "next", + type: "weekdayLiteration", + value: weekday + } + } + + / "this" _ weekday: Weekday { + return { + modifier: "this", + type: "weekdayLiteration", + value: weekday + } + } + + + + / "this" _ unit:Unit { + return { + type: "CalendarExpression", + valueType: "moment", + direction: "down", + unit: unit, + expression: { + type: "NowLiteral" + } + }; + } + / "last" _ unit:Unit { return { type: "CalendarExpression", valueType: "moment", @@ -285,7 +362,7 @@ CalendarExpression unit: unit, expression: { type: "BinaryExpression", - operator: "+", + operator: "-", left: { type: "NowLiteral" }, @@ -297,6 +374,8 @@ CalendarExpression } }; } + + / unit:CalendarUnit _ "of" _ expr:MomentExpression { return { type: "CalendarExpression", From 610f93d93d1b7f9b8289fa1090881de87570ed34 Mon Sep 17 00:00:00 2001 From: Xuezheng Ma Date: Mon, 21 Mar 2016 18:42:52 -0500 Subject: [PATCH 2/4] added week and month literals parsing --- lib/moment-generator.js | 30 +++++++++++++++ lib/parser.pegjs | 69 ++++++++++++++++------------------- package.json | 2 +- test/month-literals.spec.js | 24 ++++++++++++ test/weekday-literals.spec.js | 24 ++++++++++++ 5 files changed, 110 insertions(+), 39 deletions(-) create mode 100644 test/month-literals.spec.js create mode 100644 test/weekday-literals.spec.js diff --git a/lib/moment-generator.js b/lib/moment-generator.js index 0cf29c1..2a5ad50 100644 --- a/lib/moment-generator.js +++ b/lib/moment-generator.js @@ -34,6 +34,36 @@ var MomentGenerator = ASTVisitor.extend({ return this.end.clone(); }, + visit_monthLiteration: function(node) { + if (this.now.clone().month() >= node.value) { + node.value += 12; + } + return this.now.clone().startOf('year').add(node.value - 1, 'month'); + }, + + visit_nextMonthLiteration: function(node) { + return this.now.clone().startOf('year').add(1, 'year').add(node.value - 1, 'month'); + }, + + visit_thisMonthLiteration: function(node) { + return this.now.clone().startOf('year').add(node.value - 1, 'month'); + }, + + visit_weekdayLiteration: function(node) { + if (this.now.clone().weekday() >= node.value) { + node.value += 7; + } + return this.now.clone().startOf('week').add(node.value, 'day'); + }, + + visit_nextWeekdayLiteration: function(node) { + return this.now.clone().startOf('week').add(1, 'week').add(node.value, 'day'); + }, + + visit_thisWeekdayLiteration: function(node) { + return this.now.clone().startOf('week').add(node.value, 'day'); + }, + visit_YesterdayLiteral: function(node) { return this.now.clone().startOf('day').subtract(1, 'day'); }, diff --git a/lib/parser.pegjs b/lib/parser.pegjs index f6f6e39..76e8162 100644 --- a/lib/parser.pegjs +++ b/lib/parser.pegjs @@ -134,12 +134,12 @@ DurationString DurationAbbrev = "ms" - / "s" - / "m" !"o" + / "s" ! ("a"/"e"/"u") { return "s"; } + / "m" ! ("a"/"o") { return "m"; } / "h" - / "d" - / "w" - + / "d" ! "e" { return "d"; } + / "w" ! "e" { return "w"; } + CalendarUnit = string:CalendarString "s" { return string; @@ -154,13 +154,13 @@ CalendarString / "year" CalendarAbbrev - = "d" - / "w" - / "M" + = "d" ! "e" { return "d"; } + / "w" ! "e" { return "w"; } + / "M" ! ("a"/"o") { return "M"; } / "y" Weekday - = ( "monday" / "Monday" / "Mon" / "mon" ) { return 1 } + = ( "monday" / "Monday" / ("Mon" ! "t" ) / ("mon" ! "t") ) { return 1 } / ( "tuesday" / "Tuesday" / "Tue" / "tue") { return 2 } / ( "wednesday"/ "Wednesday" / "Wed" / "wed") { return 3 } / ( "thursday"/ "Thursday" / "Thu" / "thu") { return 4 } @@ -168,8 +168,8 @@ Weekday / ( "saturday"/ "Saturday" / "Sat" / "sat") { return 6 } / ( "sunday"/ "Sunday" / "Sun" / "sun") { return 7 } -Month - = ( "january"/ "January"/ "jan"/ "Jan") { return 1 } +Month + = ( "january"/ "January"/ "jan"/ "Jan") { return 1 } / ("february"/ "February"/ "feb"/ "Feb") { return 2 } / ("march"/ "March"/ "mar"/ "Mar") { return 3 } / ("april"/ "April"/ "apr"/ "Apr") { return 4 } @@ -181,7 +181,7 @@ Month / ("october"/ "October"/ "oct"/ "Oct") { return 10 } / ("november"/ "November"/ "nov"/ "Nov") { return 11 } / ("december"/ "December"/ "dec"/ "Dec") { return 12 } - + Unit = CalendarUnit / DurationUnit @@ -274,12 +274,11 @@ CalendarExpression }; } / "next" _ unit:Unit { - var wdawd return { type: "CalendarExpression", valueType: "moment", direction: "down", - unit: unit.unit, + unit: unit, expression: { type: "BinaryExpression", operator: "+", @@ -296,53 +295,47 @@ CalendarExpression } / month: Month { return { - modifier: "", - type: "monthLiteration", - value: month + type: "monthLiteration", + value: month } } - + / "next" _ month: Month { return { - modifier: "next", - type: "monthLiteration", - value: month + type: "nextMonthLiteration", + value: month } } - + / "this" _ month: Month { return { - modifier: "this", - type: "monthLiteration", + type: "thisMonthLiteration", value: month } } / weekday: Weekday { return { - modifier: "", type: "weekdayLiteration", - value: weekday + value: weekday } } - + / "next" _ weekday: Weekday { return { - modifier: "next", - type: "weekdayLiteration", - value: weekday + type: "nextWeekdayLiteration", + value: weekday } } - + / "this" _ weekday: Weekday { return { - modifier: "this", - type: "weekdayLiteration", - value: weekday + type: "thisWeekdayLiteration", + value: weekday } } - - - + + + / "this" _ unit:Unit { return { type: "CalendarExpression", @@ -375,7 +368,7 @@ CalendarExpression }; } - + / unit:CalendarUnit _ "of" _ expr:MomentExpression { return { type: "CalendarExpression", diff --git a/package.json b/package.json index a460c50..92b784e 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "test": "test" }, "scripts": { - "test": "node_modules/.bin/istanbul cover -x 'lib/parser.js' node_modules/.bin/_mocha", + "test": "node scripts/peg.js && node_modules/.bin/istanbul cover -x 'lib/parser.js' node_modules/.bin/_mocha", "check-coverage": "node_modules/.bin/istanbul check-coverage", "postinstall": "node scripts/peg.js" }, diff --git a/test/month-literals.spec.js b/test/month-literals.spec.js new file mode 100644 index 0000000..c912e1b --- /dev/null +++ b/test/month-literals.spec.js @@ -0,0 +1,24 @@ +var parser = require('..'); +var _ = require('underscore'); +var expect = require('chai').expect; +var moment = require('moment'); + +var now = moment.utc('2016-04-01T01:02:03.456'); + +describe('Month literals parsing', function() { + var tests = { + 'next february': + now.clone().startOf('month').add(10, 'month'), + 'this Feb': + now.clone().startOf('month').subtract(2, 'month'), + 'feb': + now.clone().startOf('month').add(10, 'month'), + }; + + _.each(tests, function(expected, input) { + it('handles "' + input + '"', function() { + expect(parser.parseMoment(input, {now: now}).isSame(expected)).is.true; + }); + }); + +}); diff --git a/test/weekday-literals.spec.js b/test/weekday-literals.spec.js new file mode 100644 index 0000000..7a8d054 --- /dev/null +++ b/test/weekday-literals.spec.js @@ -0,0 +1,24 @@ +var parser = require('..'); +var _ = require('underscore'); +var expect = require('chai').expect; +var moment = require('moment'); + +var now = moment.utc('2016-01-01T01:02:03.456'); + +describe('Weekday literals parsing', function() { + var tests = { + 'next wednesday': + now.clone().startOf('day').add(5, 'day'), + 'this Wed': + now.clone().startOf('day').subtract(2, 'day'), + 'wed': + now.clone().startOf('day').add(5, 'day'), + }; + + _.each(tests, function(expected, input) { + it('handles "' + input + '"', function() { + expect(parser.parseMoment(input, {now: now}).isSame(expected)).is.true; + }); + }); + +}); From 332c20a2456c80610d1611bcc98bd9baa0c03912 Mon Sep 17 00:00:00 2001 From: Xuezheng Ma Date: Mon, 20 Jun 2016 22:22:46 -0500 Subject: [PATCH 3/4] keep weekday/month in calendar expressions --- lib/moment-generator.js | 36 ++---- lib/parser.pegjs | 225 +++++++++++++++++++++------------- test/month-literals.spec.js | 4 + test/weekday-literals.spec.js | 4 + 4 files changed, 160 insertions(+), 109 deletions(-) diff --git a/lib/moment-generator.js b/lib/moment-generator.js index 2a5ad50..b40f1ab 100644 --- a/lib/moment-generator.js +++ b/lib/moment-generator.js @@ -34,34 +34,22 @@ var MomentGenerator = ASTVisitor.extend({ return this.end.clone(); }, - visit_monthLiteration: function(node) { - if (this.now.clone().month() >= node.value) { - node.value += 12; + visit_WeekdayLiteral: function(node) { + var value = node.value + var relative = node.relative + if (typeof(relative) === "undefined") { + relative = (this.now.clone().weekday() > value)? 1: 0 } - return this.now.clone().startOf('year').add(node.value - 1, 'month'); + return this.now.clone().startOf('week').add(relative, 'week').weekday(value) }, - visit_nextMonthLiteration: function(node) { - return this.now.clone().startOf('year').add(1, 'year').add(node.value - 1, 'month'); - }, - - visit_thisMonthLiteration: function(node) { - return this.now.clone().startOf('year').add(node.value - 1, 'month'); - }, - - visit_weekdayLiteration: function(node) { - if (this.now.clone().weekday() >= node.value) { - node.value += 7; + visit_MonthLiteral: function(node) { + var value = node.value + var relative = node.relative + if (typeof(relative) === "undefined") { + relative = (this.now.clone().month() > value)? 1: 0 } - return this.now.clone().startOf('week').add(node.value, 'day'); - }, - - visit_nextWeekdayLiteration: function(node) { - return this.now.clone().startOf('week').add(1, 'week').add(node.value, 'day'); - }, - - visit_thisWeekdayLiteration: function(node) { - return this.now.clone().startOf('week').add(node.value, 'day'); + return this.now.clone().startOf('year').add(relative, 'year').month(value) }, visit_YesterdayLiteral: function(node) { diff --git a/lib/parser.pegjs b/lib/parser.pegjs index 76e8162..bd6b747 100644 --- a/lib/parser.pegjs +++ b/lib/parser.pegjs @@ -134,11 +134,11 @@ DurationString DurationAbbrev = "ms" - / "s" ! ("a"/"e"/"u") { return "s"; } - / "m" ! ("a"/"o") { return "m"; } + / "s" + / "m" / "h" - / "d" ! "e" { return "d"; } - / "w" ! "e" { return "w"; } + / "d" + / "w" CalendarUnit = string:CalendarString "s" { @@ -154,37 +154,35 @@ CalendarString / "year" CalendarAbbrev - = "d" ! "e" { return "d"; } - / "w" ! "e" { return "w"; } - / "M" ! ("a"/"o") { return "M"; } + = "d" + / "w" + / "M" / "y" -Weekday - = ( "monday" / "Monday" / ("Mon" ! "t" ) / ("mon" ! "t") ) { return 1 } - / ( "tuesday" / "Tuesday" / "Tue" / "tue") { return 2 } - / ( "wednesday"/ "Wednesday" / "Wed" / "wed") { return 3 } - / ( "thursday"/ "Thursday" / "Thu" / "thu") { return 4 } - / ( "friday"/ "Friday" / "Fri" / "fri") { return 5 } - / ( "saturday"/ "Saturday" / "Sat" / "sat") { return 6 } - / ( "sunday"/ "Sunday" / "Sun" / "sun") { return 7 } - -Month - = ( "january"/ "January"/ "jan"/ "Jan") { return 1 } - / ("february"/ "February"/ "feb"/ "Feb") { return 2 } - / ("march"/ "March"/ "mar"/ "Mar") { return 3 } - / ("april"/ "April"/ "apr"/ "Apr") { return 4 } - / ("may"/ "May") { return 5 } - / ("june"/ "June"/ "jun"/ "Jun") { return 6 } - / ("july"/ "July"/ "jul"/ "Jul") { return 7 } - / ("august"/ "August"/ "aug"/ "Aug") { return 8 } - / ("september"/ "September"/ "sep"/ "Sep") { return 9 } - / ("october"/ "October"/ "oct"/ "Oct") { return 10 } - / ("november"/ "November"/ "nov"/ "Nov") { return 11 } - / ("december"/ "December"/ "dec"/ "Dec") { return 12 } - - -Unit = CalendarUnit / DurationUnit +WeekdayUnit + = ( "sun"i "day"?) { return 0 } + / ( "mon"!"t"i "day"? ) { return 1 } + / ( "tue"i "sday"?) { return 2 } + / ( "wed"i "nesday"?) { return 3 } + / ( "thu"i "rsday"?) { return 4 } + / ( "fri"i "day"?) { return 5 } + / ( "sat"i "urday"?) { return 6 } + + +MonthUnit + = ( "jan"i "uary"?) { return 0 } + / ("feb"i "ruary"?) { return 1 } + / ("mar"i "ch"?) { return 2 } + / ("apr"i "il"?) { return 3 } + / ("may"i) { return 4 } + / ("jun"i "e"?) { return 5 } + / ("jul"i "y"?) { return 6 } + / ("aug"i "ust"?) { return 7 } + / ("sep"i "tember"?) { return 8 } + / ("oct"i "ober"?) { return 9 } + / ("nov"i "ember"?) { return 10 } + / ("dec"i "ember"?) { return 11 } HumanDuration = num:Integer? _ unit:CalendarUnit { @@ -273,70 +271,109 @@ CalendarExpression valueType: "moment" }; } - / "next" _ unit:Unit { + / _ unit:( WeekdayUnit ) { return { type: "CalendarExpression", valueType: "moment", direction: "down", - unit: unit, + unit: "day", expression: { - type: "BinaryExpression", - operator: "+", - left: { - type: "NowLiteral" - }, - right: { - type: "MomentDuration", - value: 1, - unit: unit - } + type: "WeekdayLiteral", + value: unit } }; } - / month: Month { - return { - type: "monthLiteration", - value: month - } + / "this" _ unit:( WeekdayUnit ) { + return { + type: "CalendarExpression", + valueType: "moment", + direction: "down", + unit: "day", + expression: { + type: "WeekdayLiteral", + value: unit, + relative: 0 + } + }; } - - / "next" _ month: Month { - return { - type: "nextMonthLiteration", - value: month - } + / "last" _ unit:( WeekdayUnit ) { + return { + type: "CalendarExpression", + valueType: "moment", + direction: "down", + unit: "day", + expression: { + type: "WeekdayLiteral", + value: unit, + relative: -1 + } + }; } - - / "this" _ month: Month { - return { - type: "thisMonthLiteration", - value: month - } + / "next" _ unit:( WeekdayUnit ) { + return { + type: "CalendarExpression", + valueType: "moment", + direction: "down", + unit: "day", + expression: { + type: "WeekdayLiteral", + value: unit, + relative: 1 + } + }; } - / weekday: Weekday { - return { - type: "weekdayLiteration", - value: weekday - } + / _ unit:( MonthUnit ) { + return { + type: "CalendarExpression", + valueType: "moment", + direction: "down", + unit: "month", + expression: { + type: "MonthLiteral", + value: unit + } + }; } - - / "next" _ weekday: Weekday { - return { - type: "nextWeekdayLiteration", - value: weekday - } + / "this" _ unit:( MonthUnit ) { + return { + type: "CalendarExpression", + valueType: "moment", + direction: "down", + unit: "month", + expression: { + type: "MonthLiteral", + value: unit, + relative: 0 + } + }; } - - / "this" _ weekday: Weekday { - return { - type: "thisWeekdayLiteration", - value: weekday - } + / "last" _ unit:( MonthUnit ) { + return { + type: "CalendarExpression", + valueType: "moment", + direction: "down", + unit: "month", + expression: { + type: "MonthLiteral", + value: unit, + relative: -1 + } + }; } - - - - / "this" _ unit:Unit { + / "next" _ unit:( MonthUnit ) { + return { + type: "CalendarExpression", + valueType: "moment", + direction: "down", + unit: "month", + expression: { + type: "MonthLiteral", + value: unit, + relative: 1 + } + }; + } + / "this" _ unit:( CalendarUnit / DurationUnit ) { return { type: "CalendarExpression", valueType: "moment", @@ -347,7 +384,7 @@ CalendarExpression } }; } - / "last" _ unit:Unit { + / "last" _ unit:( CalendarUnit / DurationUnit ) { return { type: "CalendarExpression", valueType: "moment", @@ -367,8 +404,26 @@ CalendarExpression } }; } - - + / "next" _ unit:( CalendarUnit / DurationUnit ) { + return { + type: "CalendarExpression", + valueType: "moment", + direction: "down", + unit: unit, + expression: { + type: "BinaryExpression", + operator: "+", + left: { + type: "NowLiteral" + }, + right: { + type: "MomentDuration", + value: 1, + unit: unit + } + } + }; + } / unit:CalendarUnit _ "of" _ expr:MomentExpression { return { type: "CalendarExpression", diff --git a/test/month-literals.spec.js b/test/month-literals.spec.js index c912e1b..7488414 100644 --- a/test/month-literals.spec.js +++ b/test/month-literals.spec.js @@ -13,6 +13,10 @@ describe('Month literals parsing', function() { now.clone().startOf('month').subtract(2, 'month'), 'feb': now.clone().startOf('month').add(10, 'month'), + 'last feb': + now.clone().startOf('month').add(-14, 'month'), + 'may': + now.clone().startOf('month').add(1, 'month'), }; _.each(tests, function(expected, input) { diff --git a/test/weekday-literals.spec.js b/test/weekday-literals.spec.js index 7a8d054..56a4624 100644 --- a/test/weekday-literals.spec.js +++ b/test/weekday-literals.spec.js @@ -13,6 +13,10 @@ describe('Weekday literals parsing', function() { now.clone().startOf('day').subtract(2, 'day'), 'wed': now.clone().startOf('day').add(5, 'day'), + 'last wed': + now.clone().startOf('day').add(-9, 'day'), + 'sat': + now.clone().startOf('day').add(1, 'day'), }; _.each(tests, function(expected, input) { From ddfaeaa65912d839103895ea0c4778f737d7bf45 Mon Sep 17 00:00:00 2001 From: xuezhma Date: Tue, 21 Jun 2016 02:05:23 -0500 Subject: [PATCH 4/4] no need to startof week, align some lines --- lib/moment-generator.js | 4 ++-- lib/parser.pegjs | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/moment-generator.js b/lib/moment-generator.js index b40f1ab..546c4ad 100644 --- a/lib/moment-generator.js +++ b/lib/moment-generator.js @@ -40,7 +40,7 @@ var MomentGenerator = ASTVisitor.extend({ if (typeof(relative) === "undefined") { relative = (this.now.clone().weekday() > value)? 1: 0 } - return this.now.clone().startOf('week').add(relative, 'week').weekday(value) + return this.now.clone().add(relative, 'week').weekday(value) }, visit_MonthLiteral: function(node) { @@ -49,7 +49,7 @@ var MomentGenerator = ASTVisitor.extend({ if (typeof(relative) === "undefined") { relative = (this.now.clone().month() > value)? 1: 0 } - return this.now.clone().startOf('year').add(relative, 'year').month(value) + return this.now.clone().add(relative, 'year').month(value) }, visit_YesterdayLiteral: function(node) { diff --git a/lib/parser.pegjs b/lib/parser.pegjs index bd6b747..f7fdb70 100644 --- a/lib/parser.pegjs +++ b/lib/parser.pegjs @@ -171,7 +171,7 @@ WeekdayUnit MonthUnit - = ( "jan"i "uary"?) { return 0 } + = ( "jan"i "uary"?) { return 0 } / ("feb"i "ruary"?) { return 1 } / ("mar"i "ch"?) { return 2 } / ("apr"i "il"?) { return 3 } @@ -292,7 +292,7 @@ CalendarExpression expression: { type: "WeekdayLiteral", value: unit, - relative: 0 + relative: 0 } }; } @@ -305,7 +305,7 @@ CalendarExpression expression: { type: "WeekdayLiteral", value: unit, - relative: -1 + relative: -1 } }; } @@ -318,7 +318,7 @@ CalendarExpression expression: { type: "WeekdayLiteral", value: unit, - relative: 1 + relative: 1 } }; } @@ -343,7 +343,7 @@ CalendarExpression expression: { type: "MonthLiteral", value: unit, - relative: 0 + relative: 0 } }; } @@ -356,7 +356,7 @@ CalendarExpression expression: { type: "MonthLiteral", value: unit, - relative: -1 + relative: -1 } }; } @@ -369,7 +369,7 @@ CalendarExpression expression: { type: "MonthLiteral", value: unit, - relative: 1 + relative: 1 } }; }