Work with dates and times

Reference: FQL Date docs, FQL Time docs

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

  • Convert strings to dates and times (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.

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 a string to a date

Use Date() to convert a YYYY-MM-DD 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 string.
  let dateStr = timeStr.split("T")[0]
  // Convert the 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 string.
  let dateStr = timeStr.split("T")[0]
  // Convert the string to a date value.
  Date(dateStr)
}

Convert a date to a string

Use date.toString() to convert a date value to a YYYY-MM-DD 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")
})

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 a 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 a string.
  let dateStr = date.toString()
  // Append a time component to the 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
}

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!