Enable Lacona to parse natural language dates, times, and both together
JavaScript
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
src
test
.gitignore
.npmignore
.travis.yml
CHANGELOG.md
LICENSE
README.md
package.json

README.md

elliptical-datetime

Phrases to allow elliptical to understand natural language dates, times, and more. Maintained as part of the elliptical core. While multiple languages will be supported in the future, only the Gregorian calendar will be supported (no historical or Lunar calendars).

Usage Notes

Complex phrases themselves allow for implied components. That is to say, "January 3rd" is a valid Day, but it is also a valid Date and DateTime. The year is implied based upon the current year, and the time of day is assumed to be defaultTime (8:00 by default). Because of this, custom phrases making use of dates should never have a construct like this:

<choice>
  <DateTime />
  <Date />
  <Time />
</choice>

The DateTime itself allows Dates and Times to be entered alone, so such a setup just causes problems. Instead, use props like defaultTime to modify the default settings.

Example

/** @jsx createElement */
import {DateTime} from 'elliptical-datetime'
import {String} from 'elliptical-string'
import {createElement, compile} from 'elliptical'

const parse = compile(
  <sequence>
    <literal text='remind me to ' />
    <String id='title' />
    <DateTime id='date' past={false} />
  </sequence>
)

/*
  parse will understand:
    - remind me to wash the car tomorrow [implies 8am]
    - remind me to wash the car this afternoon at 5
    - remind me to wash the car at 6:32pm [implies today, unless it is currently after 6:32pm, in which case it implies tomorrow]
    - remind me to wash the car at 4pm on Saturday
    - remind me to wash the car 3 days before December 25 [implies 8am]
*/

Phrases

Time

A phrase that represents a specific time of day.

Result

{
  hour: <Integer>, // the hour in 24-hour time. 0 for midnight, 12 for noon, 20 for 8pm
  minute: <Integer>, // 0 if unspecified. Minimum of 0, maximum of 59
  second: <Integer> // 0 if unspecified. Minimum of 0, maximum of 59
}

Props

  • prepositions: Boolean - defaults to false. Allow the user to input standard prepositions, in applicable languages. In English, this means things like:
    • 'at 3pm' vs '3pm'

Day

A phrase that represents a specific date, with no time or year information. This is useful for representing Birthdays, annual holidays etc.

Result

{
  month: <Integer>, // the 0-indexed month of the year. 0 for January, 11 for December
  day: <Integer> // the 1-indexed day of the month.
}

Props

  • prepositions: Boolean - defaults to false. Allow the user to input standard prepositions, in applicable languages. In English, this means things like:
    • 'on January 2nd' vs 'January 2nd'

Date

A phrase that represents a specific date, with no time information.

Note that the user does not necessarily need to specify the full date. If the user enters a date without a specified year:

  • DayOfTheYear without a specified year: If future and past are true, this implies <DayOfTheYear> this year. If future is false, it represents the most recent <DayOfTheYear> (either this year or last year depending on the current date). If past is false, it represents the closest upcoming <DayOfTheYear> (either this year or next year depending on the current date).

Result

Date //Standard Javascript Date object. Time is always 0:00 (midnight). Local timezone.

Props

  • prepositions: Boolean - defaults to false. Allow the user to input standard prepositions, in applicable languages. In English, this means things like:
    • 'on January 2nd' vs 'January 2nd'
  • future: Boolean - defaults to true. Can the user input dates in the future?
  • past: Boolean - defaults to true. Can the user input dates in the past?

DateTime

A phrase that represents a specific point in time.

Note that the user does not necessarily need to specify the full date and time. If the user enters a:

  • Time: If future and past are true, this implies <Time> today. If future is false, it represents the most recent <Time> (either today or yesterday depending on the current time). If past is false, it represents the closest upcoming <Time> (either today or tomorrow depending on the current time).
  • Date: The start time is implied as <defaultTime> <Date> (defaultTime defaults to 8:00).

Result

Date //Standard Javascript Date object. Local timezone.

Props

  • defaultTime: Date - defaults to {hour: 8}. The time of day to use for start if only the day is specified.
  • prepositions: Boolean - defaults to false. Allow the user to input standard prepositions, in applicable languages. In English, this means things like:
    • 'on January 2nd at 3pm' vs 'January 2nd at 3pm'
    • 'at 3pm tomorrow' vs '3pm tomorrow'
  • future: Boolean - defaults to true. Can the user input points in the future?
  • past: Boolean - defaults to true. Can the user input points in the past?
  • timezoneOffset: Number. The timezone offset in which to interpret the user's input, as returned from new Date().getTimezoneOffset(). If not specified, defaults to the current timezoneOffset of the javascript context. This is useful if elliptical is being used on a server - set this prop to the timezoneOffset sent from the client.

Duration, TimeDuration, and DateDuration

A phrase that expresses an amount of time without a specific start or end point. In English, this is usually represented with strings like "2 weeks and a day".

Note that a duration does not imply an amount of absolute time. For example, the duration "1 month" represents a different amount of milliseconds if applied to "1 month from March 1st" (April 1st, 31 days away) than "1 month from April 1st" (May 1st, 30 days away).

TimeDuration only allows units of time that are smaller than a single day. Note that the actual time represented could still be larger than a day ("28 hours and 5 minutes"). Use the max property to restrict this range (max={hours: 24}).

DateDuration only allows units of time that are a day or larger.

Duration allows a combination of date and time units.

Result

An object of the form:

{
  years: <Number>,
  months: <Number>,
  days: <Number,
  hours: <Number>,
  minutes: <Number>,
  seconds: <Number>
}

Any properties may be undefined. For TimeDuration, years, months, and days will always be undefined. For DateDuration, hours, minutes, and seconds will always be undefined.

Note other units of time that are simply multiples of these 6 units (weeks, decades, double hours, etc.) are converted to these 6 units for output. Any units that cannot be reprented absolutely using these 6 units (lunar months, etc.) are unsupported.

This object is designed to be easily consumed and manipulated by moment.duration.

Fractional seconds are currently unsupported.

Props

  • None

TimeRange - NOT IMPLEMENTED

Reprents range that starts at a specific time and ends at a specific time, but is not tied to any particular date.

Result

An object of the form

{
  start: <Time>, //that is, the same type of object that is the result of the Time phrase
  end: <Time>, //that is, the same type of object that is the result of the Time phrase
  dayOffset: <Integer> //number of days that would take place between start and end, if dates were specified
}

If end is an earlier time of day than start, daysOffset will always be greater than 0.

Props

  • prepositions: Boolean - defaults to false. Allow the user to input standard prepositions, in applicable languages. In English, this means things like:
    • 'from 3pm to 4pm' vs '3pm to 4pm'

DateRange -- NOT IMPLEMENTED

Represents a range of dates.

Result

An object of the form

{
  start: <Date> // Time is always 0:00 (midnight). Localtime zone.
  end: <Date>
}

Props

  • prepositions: Boolean - defaults to false. Allow the user to input standard prepositions, in applicable languages. In English, this means things like:
    • 'on January 2nd for 3 days' vs 'January 2nd for 3 days'
    • 'from January 3 to January 5' vs 'January 3 to January 5'

Range

Represents an absolute period of time, with a beginning DateTime and an ending DateTime. This can take many forms linguistically.

Note that the user does not necessarily need to fully specify the start and end. Range makes some suggestions for simplicity. For example, if the user enters a:

  • Time: If future and past are true, this implies <Time> today. If future is false, it represents the most recent <Time> (either today or yesterday depending on the current time). If past is false, it represents the closest upcoming <Time> (either today or tomorrow depending on the current time). The end time is defaultDuration after the start time (defaultDuration defaults to 1 hour).
  • Date: The start time is implied as <defaultTime> <Date> (defaultTime defaults to 8:00).
  • DateTime: The end time is defaultDuration after <DateTime> (defaultDuration defaults to 1 hour).

Result

An object of the form

{
  start: <Date>,
  end: <Date>
}

end will always be after start.

Props

  • defaultDuration: Duration - defaults to {hours: 1}. The amount of time between start and end if the user does not indicate it directly.
  • defaultTime: Date - defaults to {hour: 8}. The time of day to use for start if only the day is specified.
  • prepositions: Boolean - defaults to false. Allow the user to input standard prepositions, in applicable languages. In English, this means things like:
    • 'from 3pm to 4pm' vs '3pm to 4pm'
    • 'on January 2nd for 3 hours' vs 'January 2nd for 3 hours'
  • future: Boolean - defaults to true. Can the user input ranges that end in the future?
  • past: Boolean - defaults to true. Can the user input ranges that begin in the past?
  • timezoneOffset: Number. The timezone offset in which to interpret the user's input, as returned from new Date().getTimezoneOffset(). If not specified, defaults to the current timezoneOffset of the javascript context. This is useful if elliptical is being used on a server - set this prop to the timezoneOffset sent from the client.