Work with dates and times

Reference: FQL Time docs, FQL Date docs

FQL includes types for time and date values. This guide covers how to use FQL’s built-in methods for time and date values to:

  • Convert ISO 8601 strings to times and dates (and the reverse)

  • Convert Unix timestamps to times (and the reverse)

  • Perform date-time math while automatically converting time units, accounting for variable month lengths, leap days, and more.

  • Sort document sets on date and time values.

  • Run range searches on dates and times in document sets.

Times

Use FQL’s Time methods to create and manipulate time values. All time values are in UTC.

Get the current time

Use Time.now() to get the current time as a time value:

Time.now()

Convert an ISO 8601 string to a time

Use Time() to convert an ISO 8601 string to a time:

Time("2099-10-20T21:15:09.890729Z")

Time.fromString() is equivalent to Time():

// Equivalent to Time("2099-10-20T21:15:09.890729Z")
Time.fromString("2099-10-20T21:15:09.890729Z")

Convert a Unix timestamp to a time

Use Time.epoch() to convert a Unix timestamp to a time. Time.epoch() requires the time increment used to offset the Unix epoch:

Time.epoch(1676030400, 'seconds')

Convert a date to a time

FQL doesn’t include a built-in method for converting dates to times. However, you can use an anonymous function or user-defined functions (UDFs) to convert dates to times.

As an anonymous function:

// Accepts a date value.
let dateToTime: (Date) => Time = (date) => {
  // Convert the date to an ISO 8601 string.
  let dateStr = date.toString()
  // Append a time component to the IS0 8601 string.
  // In this example, use midnight.
  let timeStr = dateStr + "T00:00:00Z"
  // Convert the ISO 8601 string to a time value.
  Time(timeStr)
}

// Convert the current date to a time.
dateToTime(Date.today())

As a UDF:

function dateToTime(date: Date): Time {
  // Convert the date to an ISO 8601 string.
  let dateStr = date.toString()
  // Append a time component to the IS0 8601 string.
  // In this example, use midnight.
  let timeStr = dateStr + "T00:00:00Z"
  // Convert the ISO 8601 string to a time value.
  Time(timeStr)
}

Convert a time to an ISO 8601 string

Use time.toString() to convert a time to an ISO 8601 string:

// Get the current time as an IS0 8601 string.
Time.now().toString()

Convert a time to a Unix epoch

Use time.toMicros(), time.toMillis(), and time.toSeconds() to convert a time to a Unix timestamp, offset using the respective time unit:

// Get the current time as a Unix timestamp
// in seconds since the Unix epoch.
Time.now().toSeconds()

Add to a time

Use time.add() to add time increments to a time:

// Adds 20 minutes to the current time.
Time.now().add(20, 'minutes')

Subtract from a time

Use time.subtract() to subtract time increments from a time:

// Subtract 5 seconds from the current time.
Time.now().subtract(5, 'seconds')

Get the difference between two times

Use time.difference() to get the difference between two times in a time unit you choose.

Time('2099-02-10T12:10:00.000Z')
  .difference(Time('2099-02-10T12:00:00.000Z'), 'minutes')

Compare two times

You can use comparison operators to compare time values:

Time('2099-02-10T12:10:00.000Z') > Time('2099-02-10T12:00:00.000Z')

Sort a set on a time value

You can use set.order() to sort a set by a time value:

// Sorts `Order` documents by descending
// `createdAt` time value.
Order.all().order(desc(.createdAt))

For better performance with large sets, define an index that includes the time field as an index value:

collection Order {
  ...

  // Defines the `sortedByCreatedAtHighToLow()` index.
  index sortedByCreatedAtHighToLow {
    // `values` are document fields for sorting and range searches.
    // In this example, you sort or filter index results by their
    // descending `createdAt` field value.
    values [desc(.createdAt)]
  }
  ...
}

Then call the index to return the set sorted by the value:

// Sorts `Order` documents by descending
// `createdAt` time value.
Order.sortedByCreatedAtHighToLow()

Run a range search on time values

You can use set.where() to filter a set by a range of time values:

// Gets `Order` documents with a `createdAt` time:
// - Less than or equal to the current time.
// - Greater than or equal to the current time minus 5 days.
Order.all()
  .where(.createdAt <= Time.now())
  .where(.createdAt >= Time.now().subtract(5, "days"))

For better performance with large sets, define an index that includes the time field as an index value:

collection Order {
  createdAt: Time
  ...

  // Defines the `sortedByCreatedAtHighToLow()` index.
  index sortedByCreatedAtHighToLow {
    // `values` are document fields for sorting and range searches.
    // In this example, you sort or filter index results by their
    // descending `createdAt` field value.
    values [desc(.createdAt)]
  }
  ...
}

Then use the index to run a range search on the index value:

// Gets `Order` documents with a `createdAt` time:
// - Less than or equal to the current time.
// - Greater than or equal to the current time minus 5 days.
Order.sortedByCreatedAtHighToLow({
  from: Time.now(),
  to: Time.now().subtract(5, "days")
})

Get a document’s timestamp

All documents include a ts (timestamp) metadata field that records the document’s last write. Fauna stores the field as a read-only Time value.

You can read the ts field like any other document field:

// Projects a `Product` document's `ts` field.
Product.byName("limes").first() {
  ts
}

Dates

Use FQL’s Date methods to create and manipulate date values. Date values are in UTC and don’t include a time component.

Get the current date

Use Date.today() to get the current date as a date value:

Date.today()

Convert an ISO 8601 string to a date

Use Date() to convert an ISO 8601 string to a date:

Date("2099-10-20")

Date.fromString() is equivalent to Date():

// Equivalent to Date("2099-10-20")
Date.fromString("2099-10-20")

Convert a time to a date

FQL doesn’t include a built-in method for converting a time to date. However, you can use an anonymous function or user-defined functions (UDFs) to convert a time to a date.

As an anonymous function:

// Accepts a time value.
let timeToDate: (Time) => Date = (time) => {
  // Convert the time to an ISO 8601 string.
  let timeStr = time.toString()
  // Remove the time component from the IS0 8601 string.
  let dateStr = timeStr.split("T")[0]
  // Convert the ISO 8601 string to a date value.
  Date(dateStr)
}

// Convert the current date to a time.
timeToDate(Time.now())

As a UDF:

function timeToDate(time: Time): Date {
  // Convert the time to an ISO 8601 string.
  let timeStr = time.toString()
  // Remove the time component from the IS0 8601 string.
  let dateStr = timeStr.split("T")[0]
  // Convert the ISO 8601 string to a date value.
  Date(dateStr)
}

Convert a date to an ISO 8601 string

Use date.toString() to convert a date value to an ISO 8601 string:

// Get the current date as an IS0 8601 string.
Date.today().toString()

Add to a date

Use date.add() to add days to a date:

// Adds 5 days to the current date.
Date.today().add(5, 'days')

Subtract from a date

Use date.subtract() to subtract days from a date:

// Subtract 2 days from the current date.
Date.today().subtract(2, 'days')

Get the difference between two dates

Use date.difference() to get the difference between two dates in days:

Date('2099-02-10').difference(Date('2099-01-01'))

Compare two dates

You can use comparison operators to compare date values:

Date('2099-02-10') > Date('2099-02-09')

Sort a set on a date value

You can use set.order() to sort a set by a date value:

// Sorts `Order` documents by descending
// `createdAtDate` date value.
Order.all().order(desc(.createdAtDate))

For better performance with large sets, define an index that includes the date field as an index value:

collection Order {
  ...

  // Defines the `sortedByCreatedAtDateHighToLow()` index.
  index sortedByCreatedAtDateHighToLow {
    // `values` are document fields for sorting and range searches.
    // In this example, you sort or filter index results by their
    // descending `createdAtDate` field value.
    values [desc(.createdAtDate)]
  }
  ...
}

Then call the index to return the set sorted by the value:

// Sorts `Order` documents by descending
// `createdAtDate` date value.
Order.sortedByCreatedAtDateHighToLow()

Run a ranged search on date values

You can use set.where() to filter a set on a range of date values:

// Gets `Order` documents with a `createdAtDate` date:
// - Less than or equal to the current date.
// - Greater than or equal to the current date minus 5 days.
Order.all()
  .where(.createdAtDate <= Date.today())
  .where(.createdAtDate >= Date.today().subtract(5, "days"))

For better performance with large sets, define an index that includes the date field as an index value:

collection Order {
  createdAtDate: Date
  ...

  // Defines the `sortedByCreatedAtDateHighToLow()` index.
  index sortedByCreatedAtDateHighToLow {
    // `values` are document fields for sorting and range searches.
    // In this example, you sort or filter index results by their
    // descending `createdAtDate` field value.
    values [desc(.createdAtDate)]
  }
  ...
}

Then use the index to run a range search on the index value:

// Gets `Order` documents with a `createdAtDate` date:
// - Less than or equal to the current date.
// - Greater than or equal to the current date minus 5 days.
Order.sortedByCreatedAtDateHighToLow({
  from: Date.today(),
  to: Date.today().subtract(5, "days")
})

Is this article helpful? 

Tell Fauna how the article can be improved:
Visit Fauna's forums or email docs@fauna.com

Thank you for your feedback!