* and an ANTLR listener to generate a structured date from the resulting parse
* tree.
*/
-public class ANTLRStructuredDateEvaluator extends StructuredDateBaseListener implements StructuredDateEvaluator {
+public class ANTLRStructuredDateEvaluator extends StructuredDateBaseListener implements StructuredDateEvaluator {
/**
* The result of the evaluation.
*/
protected StructuredDate result;
-
+
/**
* The operation stack. The parse listener methods that are implemented here
* pop input parameters off the stack, and push results back on to the stack.
*/
protected Stack<Object> stack;
-
+
public ANTLRStructuredDateEvaluator() {
}
StructuredDateLexer lexer = new StructuredDateLexer(inputStream);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
StructuredDateParser parser = new StructuredDateParser(tokenStream);
-
+
// Don't try to recover from parse errors, just bail.
parser.setErrorHandler(new BailErrorStrategy());
-
+
// Don't print error messages to the console.
parser.removeErrorListeners();
-
+
// Generate our own custom error messages.
parser.addParseListener(this);
// ParseCancellationException is thrown by the BailErrorStrategy when there is a
// parse error, with the underlying RecognitionException as the cause.
RecognitionException re = (RecognitionException) e.getCause();
-
+
throw new StructuredDateFormatException(getErrorMessage(re), re);
}
-
+
// The parsing was successful. Return the result.
return result;
}
-
+
@Override
public void exitDisplayDate(DisplayDateContext ctx) {
if (ctx.exception != null) return;
Date latestDate = (Date) stack.pop();
Date earliestDate = (Date) stack.pop();
-
+
// If the earliest date and the latest date are the same, it's just a "single" date.
// There's no need to have the latest, so set it to null.
-
+
if (earliestDate.equals(latestDate)) {
latestDate = null;
}
Date earliestDate = (Date) stack.pop();
// Set null eras to the default.
-
+
if (earliestDate.getEra() == null) {
earliestDate.setEra(Date.DEFAULT_ERA);
}
-
+
if (latestDate.getEra() == null) {
latestDate.setEra(Date.DEFAULT_ERA);
}
-
+
// Finalize any deferred calculations.
-
+
if (latestDate instanceof DeferredDate) {
((DeferredDate) latestDate).resolveDate();
}
-
+
if (earliestDate instanceof DeferredDate) {
((DeferredDate) earliestDate).resolveDate();
}
-
+
// Calculate the earliest date or end date.
-
+
if (ctx.BEFORE() != null) {
latestDate = earliestDate;
earliestDate = DateUtils.getEarliestBeforeDate(earliestDate, latestDate);
int latestInterval = DateUtils.getCircaIntervalYears(latestDate.getYear(), latestDate.getEra());
// Express the circa interval as a qualifier.
-
+
// stack.push(earliestDate.withQualifier(QualifierType.MINUS, earliestInterval, QualifierUnit.YEARS));
// stack.push(latestDate.withQualifier(QualifierType.PLUS, latestInterval, QualifierUnit.YEARS));
-
+
// OR:
-
+
// Express the circa interval as an offset calculated into the year.
-
+
DateUtils.subtractYears(earliestDate, earliestInterval);
DateUtils.addYears(latestDate, latestInterval);
-
+
stack.push(earliestDate);
stack.push(latestDate);
}
-
+
@Override
public void exitCertainDate(CertainDateContext ctx) {
if (ctx.exception != null) return;
Date earliestDate = (Date) stack.pop();
// Set null eras to the default.
-
+
if (earliestDate.getEra() == null) {
earliestDate.setEra(Date.DEFAULT_ERA);
}
-
+
if (latestDate.getEra() == null) {
latestDate.setEra(Date.DEFAULT_ERA);
}
-
+
// Finalize any deferred calculations.
-
+
if (latestDate instanceof DeferredDate) {
((DeferredDate) latestDate).resolveDate();
}
-
+
if (earliestDate instanceof DeferredDate) {
((DeferredDate) earliestDate).resolveDate();
}
-
+
stack.push(earliestDate);
stack.push(latestDate);
}
@Override
public void exitHyphenatedRange(HyphenatedRangeContext ctx) {
if (ctx.exception != null) return;
-
+
Date latestEndDate = (Date) stack.pop();
stack.pop(); // latestStartDate
stack.pop(); // earliestEndDate
if (earliestStartDate.getEra() == null && latestEndDate.getEra() != null) {
earliestStartDate.setEra(latestEndDate.getEra());
}
-
+
// Finalize any deferred calculations.
-
+
if (earliestStartDate instanceof DeferredDate) {
((DeferredDate) earliestStartDate).resolveDate();
}
@Override
public void exitNthCenturyRange(NthCenturyRangeContext ctx) {
if (ctx.exception != null) return;
-
+
Era era = (Era) stack.pop();
Integer endN = (Integer) stack.pop();
- Part endPart = (Part) stack.pop();
+ Part endPart = (Part) stack.pop();
Integer startN = (Integer) stack.pop();
Part startPart = (Part) stack.pop();
-
+
if (era == null) {
era = Date.DEFAULT_ERA;
}
-
+
int startYear = DateUtils.nthCenturyToYear(startN);
int endYear = DateUtils.nthCenturyToYear(endN);
-
+
stack.push(startPart == null ? DateUtils.getCenturyStartDate(startYear, era) : DateUtils.getPartialCenturyStartDate(startYear, startPart, era));
stack.push(startPart == null ? DateUtils.getCenturyEndDate(startYear, era) : DateUtils.getPartialCenturyEndDate(startYear, startPart, era));
stack.push(endPart == null ? DateUtils.getCenturyStartDate(endYear, era) : DateUtils.getPartialCenturyStartDate(endYear, endPart, era));
Integer year = (Integer) stack.pop();
Integer numMonthEnd = (Integer) stack.pop();
Integer numMonthStart = (Integer) stack.pop();
-
+
stack.push(new Date(year, numMonthStart, 1, era));
stack.push(new Date(year, numMonthStart, DateUtils.getDaysInMonth(numMonthStart, year, era), era));
stack.push(new Date(year, numMonthEnd, 1, era));
stack.push(new Date(year, numMonthEnd, DateUtils.getDaysInMonth(numMonthEnd, year, era), era));
}
-
+
@Override
public void exitQuarterInYearRange(QuarterInYearRangeContext ctx) {
if (ctx.exception != null) return;
Integer year = (Integer) stack.pop();
Integer lastQuarter = (Integer) stack.pop();
Integer firstQuarter = (Integer) stack.pop();
-
+
stack.push(DateUtils.getQuarterYearStartDate(firstQuarter, year).withEra(era));
stack.push(DateUtils.getQuarterYearEndDate(firstQuarter, year, era).withEra(era));
stack.push(DateUtils.getQuarterYearStartDate(lastQuarter, year).withEra(era));
Integer dayOfMonthEnd = (Integer) stack.pop();
Integer dayOfMonthStart = (Integer) stack.pop();
Integer numMonth = (Integer) stack.pop();
-
+
stack.push(new Date(year, numMonth, dayOfMonthStart, era));
stack.push(new Date(year, numMonth, dayOfMonthStart, era));
stack.push(new Date(year, numMonth, dayOfMonthEnd, era));
stack.push(new Date(year, numMonth, dayOfMonthEnd, era));
}
-
+
@Override
public void exitNumDayInMonthRange(NumDayInMonthRangeContext ctx) {
if (ctx.exception != null) return;
Integer dayOfMonthEnd = (Integer) stack.pop();
Integer dayOfMonthStart = (Integer) stack.pop();
Integer numMonth = (Integer) stack.pop();
-
+
stack.push(new Date(year, numMonth, dayOfMonthStart, era));
stack.push(new Date(year, numMonth, dayOfMonthStart, era));
stack.push(new Date(year, numMonth, dayOfMonthEnd, era));
stack.push(new Date(year, numMonth, dayOfMonthEnd, era));
}
-
+
@Override
public void exitDate(DateContext ctx) {
if (ctx.exception != null) return;
// Expect the canonical year-month-day-era ordering
// to be on the stack.
-
+
Era era = (Era) stack.pop();
Integer dayOfMonth = (Integer) stack.pop();
Integer numMonth = (Integer) stack.pop();
Integer year = (Integer) stack.pop();
-
+
// For the latest date we could either return null, or a copy of the earliest date,
// since the UI doesn't care. Use a copy of the earliest date, since it makes
// things easier here if we don't have to test for null up the tree.
-
+
stack.push(new Date(year, numMonth, dayOfMonth, era));
stack.push(new Date(year, numMonth, dayOfMonth, era));
}
-
-
+
+
@Override
public void exitNumDate(NumDateContext ctx) {
if (ctx.exception != null) return;
-
+
// This could either be year-month-day, or
// month-day-year. Try to determine which,
// and reorder the stack into the canonical
// year-month-day-era ordering.
-
+
Era era = (Era) stack.pop();
Integer num3 = (Integer) stack.pop();
Integer num2 = (Integer) stack.pop();
Integer num1 = (Integer) stack.pop();
-
- // Default to a year-month-day interpretation.
-
- int year = num1;
- int numMonth = num2;
- int dayOfMonth = num3;
-
- if (DateUtils.isValidDate(num1, num2, num3, era)) {
- // Interpreting as year-month-day produces a valid date. Go with it.
- }
- else if (DateUtils.isValidDate(num3, num1, num2, era)) {
- // Interpreting as year-month-day doesn't produce a valid date, but
- // month-day-year does. Go with month-day-year.
-
- year = num3;
- numMonth = num1;
- dayOfMonth = num2;
- }
-
+
+ // Default to a month-day-year interpretation.
+
+ int numMonth = num1;
+ int dayOfMonth = num2;
+ int year = num3;
+
+ if (DateUtils.isValidDate(num3, num1, num2, era)) {
+ // Interpreting as month-day-year produces a valid date. Go with it.
+ }
+ else if (DateUtils.isValidDate(num1, num2, num3, era)) {
+ // Interpreting as month-day-year doesn't produce a valid date, but
+ // year-month-day does. Go with year-month-day.
+
+ year = num1;
+ numMonth = num2;
+ dayOfMonth = num3;
+ }
+
stack.push(year);
stack.push(numMonth);
stack.push(dayOfMonth);
// Reorder the stack into a canonical ordering,
// year-month-day-era.
-
+
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
Integer dayOfMonth = (Integer) stack.pop();
// Reorder the stack into a canonical ordering,
// year-month-day-era.
-
+
Integer dayOfMonth = (Integer) stack.pop();
Integer numMonth = (Integer) stack.pop();
Integer year = (Integer) stack.pop();
Era era = (Era) stack.pop();
-
+
stack.push(year);
stack.push(numMonth);
stack.push(dayOfMonth);
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
Integer numMonth = (Integer) stack.pop();
-
+
stack.push(new Date(year, numMonth, 1, era));
stack.push(new Date(year, numMonth, DateUtils.getDaysInMonth(numMonth, year, era), era));
}
-
+
@Override
public void exitInvMonthYear(InvMonthYearContext ctx) {
if (ctx.exception != null) return;
-
+
// Invert the arguments.
Integer numMonth = (Integer) stack.pop();
stack.push(year);
stack.push(era);
}
-
+
@Override
public void exitYearSpanningWinter(YearSpanningWinterContext ctx) {
if (ctx.exception != null) return;
-
+
Era era = (Era) stack.pop();
Integer endYear = (Integer) stack.pop();
Integer startYear = (Integer) stack.pop();
-
+
stack.push(new Date(startYear, 12, 1).withEra(era));
stack.push(DateUtils.getQuarterYearEndDate(1, endYear, era).withEra(era));
}
@Override
public void exitPartialYear(PartialYearContext ctx) {
if (ctx.exception != null) return;
-
+
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
Part part = (Part) stack.pop();
-
+
stack.push(DateUtils.getPartialYearStartDate(part, year).withEra(era));
stack.push(DateUtils.getPartialYearEndDate(part, year, era).withEra(era));
}
@Override
public void exitQuarterYear(QuarterYearContext ctx) {
if (ctx.exception != null) return;
-
+
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
Integer quarter = (Integer) stack.pop();
@Override
public void exitHalfYear(HalfYearContext ctx) {
if (ctx.exception != null) return;
-
+
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
Integer half = (Integer) stack.pop();
stack.push(DateUtils.getHalfYearStartDate(half, year).withEra(era));
stack.push(DateUtils.getHalfYearEndDate(half, year, era).withEra(era));
- }
-
+ }
+
@Override
public void exitInvSeasonYear(InvSeasonYearContext ctx) {
if (ctx.exception != null) return;
-
+
// Invert the arguments.
-
+
Integer quarter = (Integer) stack.pop();
Integer year = (Integer) stack.pop();
Era era = (Era) stack.pop();
-
+
stack.push(quarter);
stack.push(year);
stack.push(era);
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
-
+
stack.push(new Date(year, 1, 1, era));
stack.push(new Date(year, 12, 31, era));
}
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
Part part = (Part) stack.pop();
-
+
if (era != null) {
// If the era was explicitly specified, the start and end years
// may be calculated now.
// range, where the era will be inherited from the era of the end of
// the range; this era won't be known until farther up the parse tree,
// when both sides of the range will have been parsed.
-
+
stack.push(new DeferredPartialDecadeStartDate(year, part));
stack.push(new DeferredPartialDecadeEndDate(year, part));
}
Integer year = (Integer) stack.pop();
// Calculate the start and end year of the decade, which depends on the era.
-
+
if (era != null) {
// If the era was explicitly specified, the start and end years
// may be calculated now.
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
Part part = (Part) stack.pop();
-
+
if (era != null) {
// If the era was explicitly specified, the start and end years
// may be calculated now.
// range, where the era will be inherited from the era of the end of
// the range; this era won't be known until farther up the parse tree,
// when both sides of the range will have been parsed.
-
+
stack.push(new DeferredPartialCenturyStartDate(year, part));
stack.push(new DeferredPartialCenturyEndDate(year, part));
}
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
Integer quarter = (Integer) stack.pop();
-
+
if (era != null) {
// If the era was explicitly specified, the start and end years
// may be calculated now.
// range, where the era will be inherited from the era of the end of
// the range; this era won't be known until farther up the parse tree,
// when both sides of the range will have been parsed.
-
+
stack.push(new DeferredQuarterCenturyStartDate(year, quarter));
stack.push(new DeferredQuarterCenturyEndDate(year, quarter));
}
@Override
public void exitHalfCentury(HalfCenturyContext ctx) {
if (ctx.exception != null) return;
-
+
Era era = (Era) stack.pop();
Integer year = (Integer) stack.pop();
Integer half = (Integer) stack.pop();
-
+
if (era != null) {
// If the era was explicitly specified, the start and end years
// may be calculated now.
// range, where the era will be inherited from the era of the end of
// the range; this era won't be known until farther up the parse tree,
// when both sides of the range will have been parsed.
-
+
stack.push(new DeferredHalfCenturyStartDate(year, half));
stack.push(new DeferredHalfCenturyEndDate(year, half));
}
// range, where the era will be inherited from the era of the end of
// the range; this era won't be known until farther up the parse tree,
// when both sides of the range will have been parsed.
-
+
stack.push(new DeferredCenturyStartDate(year));
stack.push(new DeferredCenturyEndDate(year));
}
@Override
public void exitMillennium(MillenniumContext ctx) {
if (ctx.exception != null) return;
-
+
Era era = (Era) stack.pop();
Integer n = (Integer) stack.pop();
// range, where the era will be inherited from the era of the end of
// the range; this era won't be known until farther up the parse tree,
// when both sides of the range will have been parsed.
-
+
stack.push(new DeferredMillenniumStartDate(n));
stack.push(new DeferredMillenniumEndDate(n));
}
@Override
public void exitStrCentury(StrCenturyContext ctx) {
if (ctx.exception != null) return;
-
+
Integer n = (Integer) stack.pop();
-
+
// Convert the nth number to a year number,
// and push on the stack.
-
+
Integer year = DateUtils.nthCenturyToYear(n);
-
+
stack.push(year);
}
// and push on the stack.
Integer year = new Integer(stripEndLetters(ctx.HUNDREDS().getText()));
-
+
if (year == 0) {
throw new StructuredDateFormatException("unexpected century '" + ctx.HUNDREDS().getText() + "'");
}
-
+
stack.push(year);
}
// Convert the string to a number,
// and push on the stack.
-
+
Integer year = new Integer(ctx.NUMBER().getText());
-
+
if (year == 0) {
throw new StructuredDateFormatException("unexpected year '" + ctx.NUMBER().getText() + "'");
}
// Convert the string a number,
// and push on the stack.
-
+
Integer month = new Integer(ctx.NUMBER().getText());
-
+
if (month < 1 || month > 12) {
throw new StructuredDateFormatException("unexpected month '" + ctx.NUMBER().getText() + "'");
}
-
+
stack.push(month);
}
// alternative with nth instead of LAST,
// the nth handler will already have pushed
// a number on the stack.
-
+
if (ctx.LAST() != null) {
stack.push(new Integer(2));
}
-
+
// Check for a valid half.
-
+
Integer n = (Integer) stack.peek();
-
+
if (n < 1 || n > 2) {
throw new StructuredDateFormatException("unexpected half '" + n + "'");
}
}
-
+
@Override
public void exitNthQuarter(NthQuarterContext ctx) {
if (ctx.exception != null) return;
// alternative with nth instead of LAST,
// the nth handler will already have pushed
// a number on the stack.
-
+
if (ctx.LAST() != null) {
stack.push(new Integer(4));
}
-
+
// Check for a valid quarter.
-
+
Integer n = (Integer) stack.peek();
-
+
if (n < 1 || n > 4) {
throw new StructuredDateFormatException("unexpected quarter '" + n + "'");
}
@Override
public void exitNth(NthContext ctx) {
if (ctx.exception != null) return;
-
+
// Convert the string to a number,
// and push on the stack.
-
+
Integer n = null;
-
+
if (ctx.NTHSTR() != null) {
n = new Integer(stripEndLetters(ctx.NTHSTR().getText()));
}
else if (ctx.FOURTH() != null) {
n = 4;
}
-
+
stack.push(n);
}
@Override
public void exitStrMonth(StrMonthContext ctx) {
if (ctx.exception != null) return;
-
+
// Convert the month name to a number,
// and push on the stack.
-
+
TerminalNode monthNode = ctx.MONTH();
-
+
if (monthNode == null) {
monthNode = ctx.SHORTMONTH();
}
-
+
String monthStr = monthNode.getText();
stack.push(DateUtils.getMonthByName(monthStr));
}
-
+
@Override
public void exitStrSeason(StrSeasonContext ctx) {
if (ctx.exception != null) return;
-
+
// Convert the season to a quarter number,
// and push on the stack.
-
+
Integer quarter = null;
-
+
if (ctx.WINTER() != null) {
quarter = 1;
}
else if (ctx.FALL() != null) {
quarter = 4;
}
-
+
stack.push(quarter);
}
@Override
public void exitAllOrPartOf(AllOrPartOfContext ctx) {
if (ctx.exception != null) return;
-
+
// If a part was specified, it will have been
// pushed on the stack in exitPartOf(). If not,
// push null on the stack.
-
+
if (ctx.partOf() == null) {
stack.push(null);
}
@Override
public void exitPartOf(PartOfContext ctx) {
if (ctx.exception != null) return;
-
+
// Convert the token to a Part,
// and push on the stack.
-
+
Part part = null;
-
+
if (ctx.EARLY() != null) {
part = Part.EARLY;
}
else if (ctx.LATE() != null) {
part = Part.LATE;
}
-
+
stack.push(part);
}
// Convert the token to an Era,
// and push on the stack.
-
+
Era era = null;
-
+
if (ctx.BC() != null) {
era = Era.BCE;
}
else if (ctx.AD() != null) {
era = Era.CE;
}
-
+
stack.push(era);
}
// Convert the numeric string to an Integer,
// and push on the stack.
-
+
Integer dayOfMonth = new Integer(ctx.NUMBER().getText());
-
+
if (dayOfMonth == 0 || dayOfMonth > 31) {
throw new StructuredDateFormatException("unexpected day of month '" + ctx.NUMBER().getText() + "'");
}
stack.push(dayOfMonth);
}
-
+
@Override
public void exitNum(NumContext ctx) {
if (ctx.exception != null) return;
// and push on the stack.
Integer num = new Integer(ctx.NUMBER().getText());
-
+
stack.push(num);
}
protected String getErrorMessage(RecognitionException re) {
String message = "";
-
+
Parser recognizer = (Parser) re.getRecognizer();
TokenStream tokens = recognizer.getInputStream();
-
+
if (re instanceof NoViableAltException) {
NoViableAltException e = (NoViableAltException) re;
Token startToken = e.getStartToken();
String input = (startToken.getType() == Token.EOF ) ? "end of text" : quote(tokens.getText(startToken, e.getOffendingToken()));
-
+
message = "no viable date format found at " + input;
}
else if (re instanceof InputMismatchException) {
else if (re instanceof FailedPredicateException) {
FailedPredicateException e = (FailedPredicateException) re;
String ruleName = recognizer.getRuleNames()[recognizer.getContext().getRuleIndex()];
-
+
message = "failed predicate " + ruleName + ": " + e.getMessage();
}
-
+
return message;
}
-
+
protected String quote(String text) {
return "'" + text + "'";
}
-
+
protected String getTokenDisplayString(Token token) {
String string;
-
+
if (token == null) {
string = "[no token]";
}
else {
String text = token.getText();
-
+
if (text == null) {
if (token.getType() == Token.EOF ) {
string = "end of text";
string = quote(text);
}
}
-
+
return string;
}
protected String stripEndLetters(String input) {
return input.replaceAll("[^\\d]+$", "");
}
-
+
public static void main(String[] args) {
StructuredDateEvaluator evaluator = new ANTLRStructuredDateEvaluator();
-
+
for (String displayDate : args) {
try {
evaluator.evaluate(displayDate);
# Specify an input display date, and an expected output structured date. Fields expected to be null
# in the structured date may be omitted.
#
-# If the structured date's displayDate field is omitted, it will be expected to be equal to the
+# If the structured date's displayDate field is omitted, it will be expected to be equal to the
# input display date. This is the usual case.
#
# The StructuredDate's earliestSingleDate and latestDate should be specified as a
#
# Input Display Date Expected Structured Date
# =======================================================================================================
-#
+#
# Valid dates
# -------------------------------------------------------------------------------------------------------
'1974 A.D.': # year
earliestSingleDate: [1974, 1, 1, CE]
latestDate: [1974, 12, 31, CE]
-
+
'1974 a.d.': # year
earliestSingleDate: [1974, 1, 1, CE]
latestDate: [1974, 12, 31, CE]
"300s-200s BC": # hyphenatedRange, century
earliestSingleDate: [ 399, 1, 1, BCE]
latestDate: [ 200, 12, 31, BCE]
-
+
"1970's-1980's": # hyphenatedRange, decade
earliestSingleDate: [1970, 1, 1, CE]
latestDate: [1989, 12, 31, CE]
'30s BC-20s BC': # hyphenatedRange, decade
earliestSingleDate: [ 39, 1, 1, BCE]
latestDate: [ 20, 12, 31, BCE]
-
+
'1974-2013': # hyphenatedRange, year
earliestSingleDate: [1974, 1, 1, CE]
latestDate: [2013, 12, 31, CE]
'12 BC - 30': # hyphenatedRange, year
earliestSingleDate: [ 12, 1, 1, BCE]
latestDate: [ 30, 12, 31, CE]
-
+
'Spring 1974-Summer 1975': # hyphenatedRange, quarterYear
earliestSingleDate: [1974, 4, 1, CE]
latestDate: [1975, 9, 30, CE]
'1st half 2000 - 1st half 2001': # hyphenatedRange, halfYear
earliestSingleDate: [2000, 1, 1, CE]
- latestDate: [2001, 6, 30, CE]
+ latestDate: [2001, 6, 30, CE]
'second half 1998 - last half 2003': # hyphenatedRange, halfYear
earliestSingleDate: [1998, 7, 1, CE]
- latestDate: [2003, 12, 31, CE]
+ latestDate: [2003, 12, 31, CE]
'second half 1998 - last half 2003 ad': # hyphenatedRange, halfYear
earliestSingleDate: [1998, 7, 1, CE]
- latestDate: [2003, 12, 31, CE]
+ latestDate: [2003, 12, 31, CE]
'2nd half 12 - first half 11 BC': # hyphenatedRange, halfYear
earliestSingleDate: [ 12, 7, 1, BCE]
- latestDate: [ 11, 6, 30, BCE]
+ latestDate: [ 11, 6, 30, BCE]
'2nd half 12 b.c. - first half 2 AD': # hyphenatedRange, halfYear
earliestSingleDate: [ 12, 7, 1, BCE]
- latestDate: [ 2, 6, 30, CE]
+ latestDate: [ 2, 6, 30, CE]
'1st half 2000': # halfYear
earliestSingleDate: [2000, 1, 1, CE]
- latestDate: [2000, 6, 30, CE]
-
+ latestDate: [2000, 6, 30, CE]
+
'2nd half 2000': # halfYear
earliestSingleDate: [2000, 7, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
'last half 2000': # halfYear
earliestSingleDate: [2000, 7, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
'early 1960s': # partialDecade
earliestSingleDate: [1960, 1, 1, CE]
- latestDate: [1963, 12, 31, CE]
+ latestDate: [1963, 12, 31, CE]
"mid 1960's": # partialDecade
earliestSingleDate: [1964, 1, 1, CE]
- latestDate: [1966, 12, 31, CE]
+ latestDate: [1966, 12, 31, CE]
'late 1960s': # partialDecade
earliestSingleDate: [1967, 1, 1, CE]
- latestDate: [1969, 12, 31, CE]
+ latestDate: [1969, 12, 31, CE]
'early 1960s ce': # partialDecade
earliestSingleDate: [1960, 1, 1, CE]
- latestDate: [1963, 12, 31, CE]
+ latestDate: [1963, 12, 31, CE]
"mid-1960's a.d.": # partialDecade
earliestSingleDate: [1964, 1, 1, CE]
- latestDate: [1966, 12, 31, CE]
+ latestDate: [1966, 12, 31, CE]
'late 1960s AD': # partialDecade
earliestSingleDate: [1967, 1, 1, CE]
- latestDate: [1969, 12, 31, CE]
+ latestDate: [1969, 12, 31, CE]
'early 530s bc': # partialDecade
earliestSingleDate: [ 539, 1, 1, BCE]
- latestDate: [ 537, 12, 31, BCE]
+ latestDate: [ 537, 12, 31, BCE]
"middle 530's b.c.": # partialDecade
earliestSingleDate: [ 536, 1, 1, BCE]
- latestDate: [ 534, 12, 31, BCE]
+ latestDate: [ 534, 12, 31, BCE]
'late 530s B.C.': # partialDecade
earliestSingleDate: [ 533, 1, 1, BCE]
- latestDate: [ 530, 12, 31, BCE]
+ latestDate: [ 530, 12, 31, BCE]
"mid 1960's-early 1970's": # hyphenatedRange, partialDecade
earliestSingleDate: [1964, 1, 1, CE]
- latestDate: [1973, 12, 31, CE]
+ latestDate: [1973, 12, 31, CE]
"mid 1960's-early 1970's a.d.": # hyphenatedRange, partialDecade
earliestSingleDate: [1964, 1, 1, CE]
- latestDate: [1973, 12, 31, CE]
+ latestDate: [1973, 12, 31, CE]
"mid 520's-early 480's b.c.": # hyphenatedRange, partialDecade
earliestSingleDate: [ 526, 1, 1, BCE]
- latestDate: [ 487, 12, 31, BCE]
+ latestDate: [ 487, 12, 31, BCE]
'1960s': # decade
earliestSingleDate: [1960, 1, 1, CE]
- latestDate: [1969, 12, 31, CE]
+ latestDate: [1969, 12, 31, CE]
"1920's": # decade
earliestSingleDate: [1920, 1, 1, CE]
- latestDate: [1929, 12, 31, CE]
+ latestDate: [1929, 12, 31, CE]
'1920S': # decade
earliestSingleDate: [1920, 1, 1, CE]
- latestDate: [1929, 12, 31, CE]
+ latestDate: [1929, 12, 31, CE]
"20's BC": # decade
earliestSingleDate: [ 29, 1, 1, BCE]
- latestDate: [ 20, 12, 31, BCE]
+ latestDate: [ 20, 12, 31, BCE]
'1960s-1980s': # hyphenatedRange, decade
earliestSingleDate: [1960, 1, 1, CE]
- latestDate: [1989, 12, 31, CE]
+ latestDate: [1989, 12, 31, CE]
'1960s-1980s A.D.': # hyphenatedRange, decade
earliestSingleDate: [1960, 1, 1, CE]
- latestDate: [1989, 12, 31, CE]
+ latestDate: [1989, 12, 31, CE]
'1960s–1920s B.C.': # hyphenatedRange, decade (en dash)
earliestSingleDate: [1969, 1, 1, BCE]
- latestDate: [1920, 12, 31, BCE]
+ latestDate: [1920, 12, 31, BCE]
"1960's-early 1980's": # hyphenatedRange, decade, partialDecade
earliestSingleDate: [1960, 1, 1, CE]
- latestDate: [1983, 12, 31, CE]
+ latestDate: [1983, 12, 31, CE]
"late 1820's - 1880's": # hyphenatedRange, partialDecade, decade
earliestSingleDate: [1827, 1, 1, CE]
- latestDate: [1889, 12, 31, CE]
+ latestDate: [1889, 12, 31, CE]
'early 1900s': # partialCentury
earliestSingleDate: [1900, 1, 1, CE]
- latestDate: [1933, 12, 31, CE]
+ latestDate: [1933, 12, 31, CE]
'mid 1900s': # partialCentury
earliestSingleDate: [1933, 1, 1, CE]
- latestDate: [1966, 12, 31, CE]
+ latestDate: [1966, 12, 31, CE]
"Late 1900's": # partialCentury
earliestSingleDate: [1966, 1, 1, CE]
- latestDate: [1999, 12, 31, CE]
+ latestDate: [1999, 12, 31, CE]
'early 1900s ad': # partialCentury
earliestSingleDate: [1900, 1, 1, CE]
- latestDate: [1933, 12, 31, CE]
+ latestDate: [1933, 12, 31, CE]
'mid 1900s CE': # partialCentury
earliestSingleDate: [1933, 1, 1, CE]
- latestDate: [1966, 12, 31, CE]
+ latestDate: [1966, 12, 31, CE]
"Late 1900's A.D.": # partialCentury
earliestSingleDate: [1966, 1, 1, CE]
- latestDate: [1999, 12, 31, CE]
+ latestDate: [1999, 12, 31, CE]
'early 18th century': # partialCentury
earliestSingleDate: [1701, 1, 1, CE]
- latestDate: [1734, 12, 31, CE]
+ latestDate: [1734, 12, 31, CE]
'mid-18th century': # partialCentury
earliestSingleDate: [1734, 1, 1, CE]
- latestDate: [1767, 12, 31, CE]
+ latestDate: [1767, 12, 31, CE]
'Late 18th century': # partialCentury
earliestSingleDate: [1767, 1, 1, CE]
- latestDate: [1800, 12, 31, CE]
+ latestDate: [1800, 12, 31, CE]
'early 100s b.c.': # partialCentury
earliestSingleDate: [ 199, 1, 1, BCE]
- latestDate: [ 166, 12, 31, BCE]
+ latestDate: [ 166, 12, 31, BCE]
'middle 100s bc': # partialCentury
earliestSingleDate: [ 166, 1, 1, BCE]
- latestDate: [ 133, 12, 31, BCE]
+ latestDate: [ 133, 12, 31, BCE]
"Late 100's B.C.": # partialCentury
earliestSingleDate: [ 133, 1, 1, BCE]
- latestDate: [ 100, 12, 31, BCE]
+ latestDate: [ 100, 12, 31, BCE]
'early 2nd century b.c.': # partialCentury
earliestSingleDate: [ 200, 1, 1, BCE]
- latestDate: [ 167, 12, 31, BCE]
+ latestDate: [ 167, 12, 31, BCE]
'mid 2nd century bc': # partialCentury
earliestSingleDate: [ 167, 1, 1, BCE]
- latestDate: [ 134, 12, 31, BCE]
+ latestDate: [ 134, 12, 31, BCE]
'Late 2nd Century B.C.': # partialCentury
earliestSingleDate: [ 134, 1, 1, BCE]
- latestDate: [ 101, 12, 31, BCE]
+ latestDate: [ 101, 12, 31, BCE]
'mid-17th century - late 18th century': # hyphenatedRange, partialCentury
earliestSingleDate: [1634, 1, 1, CE]
- latestDate: [1800, 12, 31, CE]
+ latestDate: [1800, 12, 31, CE]
'mid 17th century - late 18th century a.d.': # hyphenatedRange, partialCentury
earliestSingleDate: [1634, 1, 1, CE]
- latestDate: [1800, 12, 31, CE]
+ latestDate: [1800, 12, 31, CE]
'middle 17th century AD - late 18th century a.d.': # hyphenatedRange, partialCentury
earliestSingleDate: [1634, 1, 1, CE]
- latestDate: [1800, 12, 31, CE]
+ latestDate: [1800, 12, 31, CE]
'late 1800s - early 1900s': # hyphenatedRange, partialCentury
earliestSingleDate: [1866, 1, 1, CE]
- latestDate: [1933, 12, 31, CE]
+ latestDate: [1933, 12, 31, CE]
'late 1800s - early 1900s ce': # hyphenatedRange, partialCentury
earliestSingleDate: [1866, 1, 1, CE]
- latestDate: [1933, 12, 31, CE]
+ latestDate: [1933, 12, 31, CE]
"mid 200s-late 100's BCE": # hyphenatedRange, partialCentury
earliestSingleDate: [ 266, 1, 1, BCE]
- latestDate: [ 100, 12, 31, BCE]
+ latestDate: [ 100, 12, 31, BCE]
'late 4th century - early 3rd century bc': # hyphenatedRange, partialCentury
earliestSingleDate: [ 334, 1, 1, BCE]
- latestDate: [ 267, 12, 31, BCE]
+ latestDate: [ 267, 12, 31, BCE]
'late 4th century B.C. - early 3rd century BC': # hyphenatedRange, partialCentury
earliestSingleDate: [ 334, 1, 1, BCE]
- latestDate: [ 267, 12, 31, BCE]
+ latestDate: [ 267, 12, 31, BCE]
'late 2nd century B.C. - mid 1st century': # hyphenatedRange, partialCentury
earliestSingleDate: [ 134, 1, 1, BCE]
- latestDate: [ 67, 12, 31, CE]
+ latestDate: [ 67, 12, 31, CE]
'late 2nd century B.C. - early 3rd century A.D.': # hyphenatedRange, partialCentury
earliestSingleDate: [ 134, 1, 1, BCE]
- latestDate: [ 234, 12, 31, CE]
+ latestDate: [ 234, 12, 31, CE]
'1st quarter 1900s': # quarterCentury
earliestSingleDate: [1900, 1, 1, CE]
- latestDate: [1924, 12, 31, CE]
+ latestDate: [1924, 12, 31, CE]
'second quarter 1900s': # quarterCentury
earliestSingleDate: [1925, 1, 1, CE]
- latestDate: [1949, 12, 31, CE]
+ latestDate: [1949, 12, 31, CE]
"3rd quarter 1900's": # quarterCentury
earliestSingleDate: [1950, 1, 1, CE]
- latestDate: [1974, 12, 31, CE]
+ latestDate: [1974, 12, 31, CE]
"fourth quarter 1900's": # quarterCentury
earliestSingleDate: [1975, 1, 1, CE]
- latestDate: [1999, 12, 31, CE]
+ latestDate: [1999, 12, 31, CE]
'first quarter 18th century': # quarterCentury
earliestSingleDate: [1701, 1, 1, CE]
- latestDate: [1725, 12, 31, CE]
+ latestDate: [1725, 12, 31, CE]
'2nd quarter 18th century': # quarterCentury
earliestSingleDate: [1726, 1, 1, CE]
- latestDate: [1750, 12, 31, CE]
+ latestDate: [1750, 12, 31, CE]
'third quarter 18th century': # quarterCentury
earliestSingleDate: [1751, 1, 1, CE]
- latestDate: [1775, 12, 31, CE]
+ latestDate: [1775, 12, 31, CE]
'4th quarter 18th century': # quarterCentury
earliestSingleDate: [1776, 1, 1, CE]
- latestDate: [1800, 12, 31, CE]
+ latestDate: [1800, 12, 31, CE]
'first quarter 1st century a.d.': # quarterCentury
earliestSingleDate: [ 1, 1, 1, CE]
- latestDate: [ 25, 12, 31, CE]
+ latestDate: [ 25, 12, 31, CE]
'4th quarter 22nd century CE': # quarterCentury
earliestSingleDate: [2176, 1, 1, CE]
- latestDate: [2200, 12, 31, CE]
+ latestDate: [2200, 12, 31, CE]
'First quarter 300s BC': # quarterCentury
earliestSingleDate: [ 399, 1, 1, BCE]
- latestDate: [ 375, 12, 31, BCE]
+ latestDate: [ 375, 12, 31, BCE]
"2nd quarter 300's BC": # quarterCentury
earliestSingleDate: [ 374, 1, 1, BCE]
- latestDate: [ 350, 12, 31, BCE]
+ latestDate: [ 350, 12, 31, BCE]
'third quarter 300s BC': # quarterCentury
earliestSingleDate: [ 349, 1, 1, BCE]
- latestDate: [ 325, 12, 31, BCE]
+ latestDate: [ 325, 12, 31, BCE]
'4th quarter 300s B.C.': # quarterCentury
earliestSingleDate: [ 324, 1, 1, BCE]
- latestDate: [ 300, 12, 31, BCE]
+ latestDate: [ 300, 12, 31, BCE]
'First quarter 1st century BC': # quarterCentury
earliestSingleDate: [ 100, 1, 1, BCE]
- latestDate: [ 76, 12, 31, BCE]
+ latestDate: [ 76, 12, 31, BCE]
'2nd quarter 1st century BC': # quarterCentury
earliestSingleDate: [ 75, 1, 1, BCE]
- latestDate: [ 51, 12, 31, BCE]
+ latestDate: [ 51, 12, 31, BCE]
'third quarter 1st century BC': # quarterCentury
earliestSingleDate: [ 50, 1, 1, BCE]
- latestDate: [ 26, 12, 31, BCE]
+ latestDate: [ 26, 12, 31, BCE]
'4th quarter 1st century BC': # quarterCentury
earliestSingleDate: [ 25, 1, 1, BCE]
- latestDate: [ 1, 12, 31, BCE]
+ latestDate: [ 1, 12, 31, BCE]
'1st quarter 2nd century B.C.': # quarterCentury
earliestSingleDate: [ 200, 1, 1, BCE]
- latestDate: [ 176, 12, 31, BCE]
+ latestDate: [ 176, 12, 31, BCE]
'second quarter 2nd century BCE': # quarterCentury
earliestSingleDate: [ 175, 1, 1, BCE]
- latestDate: [ 151, 12, 31, BCE]
+ latestDate: [ 151, 12, 31, BCE]
'3rd quarter 2nd century b.c.': # quarterCentury
earliestSingleDate: [ 150, 1, 1, BCE]
- latestDate: [ 126, 12, 31, BCE]
+ latestDate: [ 126, 12, 31, BCE]
'fourth quarter 2nd century b.c.e.': # quarterCentury
earliestSingleDate: [ 125, 1, 1, BCE]
- latestDate: [ 101, 12, 31, BCE]
+ latestDate: [ 101, 12, 31, BCE]
'last quarter 2nd century b.c.e.': # quarterCentury
earliestSingleDate: [ 125, 1, 1, BCE]
- latestDate: [ 101, 12, 31, BCE]
+ latestDate: [ 101, 12, 31, BCE]
'1st quarter 18th century - 3rd quarter 19th century': # hyphenatedRange, quarterCentury
earliestSingleDate: [1701, 1, 1, CE]
- latestDate: [1875, 12, 31, CE]
+ latestDate: [1875, 12, 31, CE]
'1st quarter 18th century - 3rd quarter 19th century a.d.': # hyphenatedRange, quarterCentury
earliestSingleDate: [1701, 1, 1, CE]
- latestDate: [1875, 12, 31, CE]
+ latestDate: [1875, 12, 31, CE]
'4th quarter 3rd century - 3rd quarter 2nd century b.c.': # hyphenatedRange, quarterCentury
earliestSingleDate: [ 225, 1, 1, BCE]
- latestDate: [ 126, 12, 31, BCE]
+ latestDate: [ 126, 12, 31, BCE]
'4th quarter 1st century b.c.-1st quarter 1st century ce': # hyphenatedRange, quarterCentury
earliestSingleDate: [ 25, 1, 1, BCE]
- latestDate: [ 25, 12, 31, CE]
+ latestDate: [ 25, 12, 31, CE]
'1st half 1900s': # halfCentury
earliestSingleDate: [1900, 1, 1, CE]
- latestDate: [1949, 12, 31, CE]
+ latestDate: [1949, 12, 31, CE]
'second half 1900s': # halfCentury
earliestSingleDate: [1950, 1, 1, CE]
- latestDate: [1999, 12, 31, CE]
+ latestDate: [1999, 12, 31, CE]
'last half 1900s': # halfCentury
earliestSingleDate: [1950, 1, 1, CE]
- latestDate: [1999, 12, 31, CE]
+ latestDate: [1999, 12, 31, CE]
'first half 20th century': # halfCentury
earliestSingleDate: [1901, 1, 1, CE]
- latestDate: [1950, 12, 31, CE]
+ latestDate: [1950, 12, 31, CE]
'2nd half 20th century': # halfCentury
earliestSingleDate: [1951, 1, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
'1st half 1900s A.D.': # halfCentury
earliestSingleDate: [1900, 1, 1, CE]
- latestDate: [1949, 12, 31, CE]
+ latestDate: [1949, 12, 31, CE]
"second half 1900's c.e.": # halfCentury
earliestSingleDate: [1950, 1, 1, CE]
- latestDate: [1999, 12, 31, CE]
+ latestDate: [1999, 12, 31, CE]
'1st half 1900s B.C.': # halfCentury
earliestSingleDate: [1999, 1, 1, BCE]
- latestDate: [1950, 12, 31, BCE]
+ latestDate: [1950, 12, 31, BCE]
"second half 1900's b.c.e.": # halfCentury
earliestSingleDate: [1949, 1, 1, BCE]
- latestDate: [1900, 12, 31, BCE]
+ latestDate: [1900, 12, 31, BCE]
'first half first century b.c.': # halfCentury
earliestSingleDate: [ 100, 1, 1, BCE]
- latestDate: [ 51, 12, 31, BCE]
+ latestDate: [ 51, 12, 31, BCE]
"second half 1st century BCE": # halfCentury
earliestSingleDate: [ 50, 1, 1, BCE]
- latestDate: [ 1, 12, 31, BCE]
+ latestDate: [ 1, 12, 31, BCE]
'1st half 1900s - 1st half 2000s': # hyphenatedRange, halfCentury
earliestSingleDate: [1900, 1, 1, CE]
- latestDate: [2049, 12, 31, CE]
+ latestDate: [2049, 12, 31, CE]
'1st half 1900s - 1st half 2000s ad': # hyphenatedRange, halfCentury
earliestSingleDate: [1900, 1, 1, CE]
- latestDate: [2049, 12, 31, CE]
+ latestDate: [2049, 12, 31, CE]
'2nd half 900s - 1st half 700s bc': # hyphenatedRange, halfCentury
earliestSingleDate: [ 949, 1, 1, BCE]
- latestDate: [ 750, 12, 31, BCE]
+ latestDate: [ 750, 12, 31, BCE]
'2nd half 200s bc - 1st half 100s': # hyphenatedRange, halfCentury
earliestSingleDate: [ 249, 1, 1, BCE]
- latestDate: [ 149, 12, 31, CE]
+ latestDate: [ 149, 12, 31, CE]
'1900s': # century
earliestSingleDate: [1900, 1, 1, CE]
- latestDate: [1999, 12, 31, CE]
+ latestDate: [1999, 12, 31, CE]
'20th century': # century
earliestSingleDate: [1901, 1, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
'20th century AD': # century
earliestSingleDate: [1901, 1, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
"1600's": # century
earliestSingleDate: [1600, 1, 1, CE]
- latestDate: [1699, 12, 31, CE]
+ latestDate: [1699, 12, 31, CE]
'21st century': # century
earliestSingleDate: [2001, 1, 1, CE]
- latestDate: [2100, 12, 31, CE]
+ latestDate: [2100, 12, 31, CE]
'1st century BC': # century
earliestSingleDate: [ 100, 1, 1, BCE]
- latestDate: [ 1, 12, 31, BCE]
+ latestDate: [ 1, 12, 31, BCE]
'8th century BC': # century
earliestSingleDate: [ 800, 1, 1, BCE]
- latestDate: [ 701, 12, 31, BCE]
+ latestDate: [ 701, 12, 31, BCE]
"100's BC": # century
earliestSingleDate: [ 199, 1, 1, BCE]
- latestDate: [ 100, 12, 31, BCE]
+ latestDate: [ 100, 12, 31, BCE]
'19th century - 20th century': # hyphenatedRange, century
earliestSingleDate: [1801, 1, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
'19th century - 20th century ad': # hyphenatedRange, century
earliestSingleDate: [1801, 1, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
'3rd century - 2nd century B.C.': # hyphenatedRange, century
earliestSingleDate: [ 300, 1, 1, BCE]
- latestDate: [ 101, 12, 31, BCE]
+ latestDate: [ 101, 12, 31, BCE]
'3rd century BC - 1st century A.D.': # hyphenatedRange, century
earliestSingleDate: [ 300, 1, 1, BCE]
- latestDate: [ 100, 12, 31, CE]
+ latestDate: [ 100, 12, 31, CE]
'late 1880s - early 1900s': # hyphenatedRange, partialDecade, partialCentury
earliestSingleDate: [1887, 1, 1, CE]
- latestDate: [1933, 12, 31, CE]
+ latestDate: [1933, 12, 31, CE]
'1st millennium': # millennium
earliestSingleDate: [ 1, 1, 1, CE]
- latestDate: [1000, 12, 31, CE]
+ latestDate: [1000, 12, 31, CE]
'2nd millennium': # millennium
earliestSingleDate: [1001, 1, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
'3rd millennium': # millennium
earliestSingleDate: [2001, 1, 1, CE]
- latestDate: [3000, 12, 31, CE]
+ latestDate: [3000, 12, 31, CE]
'5th millennium': # millennium
earliestSingleDate: [4001, 1, 1, CE]
- latestDate: [5000, 12, 31, CE]
+ latestDate: [5000, 12, 31, CE]
'1st Millennium BC': # millennium
earliestSingleDate: [1000, 1, 1, BCE]
- latestDate: [ 1, 12, 31, BCE]
+ latestDate: [ 1, 12, 31, BCE]
'2nd millennium B.C.E.': # millennium
earliestSingleDate: [2000, 1, 1, BCE]
- latestDate: [1001, 12, 31, BCE]
+ latestDate: [1001, 12, 31, BCE]
'1st millennium-2nd millennium': # hyphenatedRange, millennium
earliestSingleDate: [ 1, 1, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
'1st millennium-2nd millennium ad': # hyphenatedRange, millennium
earliestSingleDate: [ 1, 1, 1, CE]
- latestDate: [2000, 12, 31, CE]
+ latestDate: [2000, 12, 31, CE]
'3rd millennium-2nd millennium bc': # hyphenatedRange, millennium
earliestSingleDate: [3000, 1, 1, BCE]
- latestDate: [1001, 12, 31, BCE]
-
+ latestDate: [1001, 12, 31, BCE]
+
'Winter 2000': # quarterYear, seasonYear
earliestSingleDate: [2000, 1, 1, CE]
latestDate: [2000, 3, 31, CE]
'Autumn 2000': # quarterYear, seasonYear
earliestSingleDate: [2000, 10, 1, CE]
latestDate: [2000, 12, 31, CE]
-
+
'Aut 2000': # quarterYear, seasonYear
earliestSingleDate: [2000, 10, 1, CE]
latestDate: [2000, 12, 31, CE]
-
+
'Sum 12 BC': # quarterYear, seasonYear
earliestSingleDate: [ 12, 7, 1, BCE]
latestDate: [ 12, 9, 30, BCE]
'1st quarter - 3rd quarter 2000': # hyphenatedRange, quarterYear
earliestSingleDate: [2000, 1, 1, CE]
- latestDate: [2000, 9, 30, CE]
+ latestDate: [2000, 9, 30, CE]
'2nd quarter - last quarter 2000': # hyphenatedRange, quarterYear
earliestSingleDate: [2000, 4, 1, CE]
'May 130-May 120 BC': # hyphenatedRange, month
earliestSingleDate: [ 130, 5, 1, BCE]
latestDate: [ 120, 5, 31, BCE]
-
+
'3/12/2013': # date
earliestSingleDate: [2013, 3, 12, CE]
'03/05/13': # date
- earliestSingleDate: [ 3, 5, 13, CE]
+ earliestSingleDate: [ 13, 3, 5, CE]
'7-6-1773': # date
earliestSingleDate: [1773, 7, 6, CE]
earliestSingleDate: [ 13, 12, 3, CE]
'12-12-3': # date
- earliestSingleDate: [ 12, 12, 3, CE]
+ earliestSingleDate: [ 3, 12, 12, CE]
'3-12-12': # date
- earliestSingleDate: [ 3, 12, 12, CE]
+ earliestSingleDate: [ 12, 3, 12, CE]
'3-12-32': # date
earliestSingleDate: [ 32, 3, 12, CE]
"3/4/2000?": # oneDisplayDate - with question mark
earliestSingleDate: [2000, 3, 4, CE]
-# -------------------------------------------------------------------------------------------------------
+# -------------------------------------------------------------------------------------------------------
# Invalid dates
# -------------------------------------------------------------------------------------------------------
'': # empty
null
-
+
'Octo 19, 1821': # invalid month
null
'May-Foo 2000': # invalid month
null
-
+
'Something else': # totally not a date
- null
+ null
'BC 12, Sumer': # invalid season
null
'5th quarter 1900': # invalid quarter number
null
-
+
'0th quarter 1900': # invalid quarter number
- null
+ null
'third half 1900': # invalid half number
- null
-
+ null
+
'0th half 1900': # invalid half number
null
'3/4?/2005': # question mark
null
-
\ No newline at end of file