Temporal values

Cypher® has built-in support for handling temporal values, which can be stored as properties on nodes and relationships in Neo4j databases. This section will discuss how Cypher handles time zones, before exploring temporal values in more detail.

Temporal value types

The following table lists the temporal value types and their supported components:

Type Date support Time support Time zone support

DATE

LOCAL TIME

ZONED TIME

LOCAL DATETIME

ZONED DATETIME

DURATION

-

-

-

DATE, LOCAL TIME, ZONED TIME, LOCAL DATETIME, and ZONED DATETIME are temporal instant types. A temporal instant value expresses a point in time with varying degrees of precision.

By contrast, DURATION is not a temporal instant type. A DURATION represents a temporal amount, capturing the difference in time between two instants, and can be negative. DURATION captures the amount of time between two instants, it does not capture a start time and end time.

Starting from Neo4j 5.9, some temporal types have been renamed. The table below shows the current as well as the old names of the temporal types.

Type Old type name

DATE

Date

LOCAL TIME

LocalTime

ZONED TIME

Time

LOCAL DATETIME

LocalDateTime

ZONED DATETIME

DateTime

DURATION

Duration

Time zones

Time zones are represented either as an offset from UTC, or as a logical identifier of a named time zone (these are based on the IANA time zone database). In either case, the time is stored as UTC internally, and the time zone offset is only applied when the time is presented. This means that temporal instants can be ordered without taking time zone into account. If, however, two times are identical in UTC, then they are ordered by timezone.

When creating a time using a named time zone, the offset from UTC is computed from the rules in the time zone database to create a time instant in UTC, and to ensure the named time zone is a valid one.

It is possible for time zone rules to change in the IANA time zone database. For example, there could be alterations to the rules for daylight savings time in a certain area. If this occurs after the creation of a temporal instant, the presented time could differ from the originally-entered time, insofar as the local timezone is concerned. However, the absolute time in UTC would remain the same.

There are three ways of specifying a time zone in Cypher:

  • Specifying the offset from UTC in hours and minutes (ISO 8601).

  • Specifying a named time zone.

  • Specifying both the offset and the time zone name (with the requirement that these match).

See specifying time zones for examples.

The named time zone form uses the rules of the IANA time zone database to manage daylight savings time (DST).

The default time zone of the database can be configured using the configuration option db.temporal.timezone. This configuration option influences the creation of temporal types for the following functions:

  • Getting the current date and time without specifying a time zone.

  • Creating a temporal type from its components without specifying a time zone.

  • Creating a temporal type by parsing a STRING without specifying a time zone.

  • Creating a temporal type by combining or selecting values that do not have a time zone component, and without specifying a time zone.

  • Truncating a temporal value that does not have a time zone component, and without specifying a time zone.

Temporal instants

Specifying temporal instants

A temporal instant consists of three parts; the date, the time, and the timezone. These parts can be combined to produce the various temporal value types. The character T is a literal character.

Temporal instant type Composition of parts

DATE

<date>

LOCAL TIME

<time> or T<time>

ZONED TIME

<time><timezone> or T<time><timezone>

LOCAL DATETIME*

<date>T<time>

ZONED DATETIME*

<date>T<time><timezone>

*When date and time are combined, date must be complete; i.e. fully identify a particular day.

Specifying dates

Component Format Description

Year

YYYY

Specified with at least four digits (special rules apply in certain cases).

Month

MM

Specified with a double digit number from 01 to 12.

Week

ww

Always prefixed with W and specified with a double digit number from 01 to 53.

Quarter

q

Always prefixed with Q and specified with a single digit number from 1 to 4.

Day of the month

DD

Specified with a double digit number from 01 to 31.

Day of the week

D

Specified with a single digit number from 1 to 7.

Day of the quarter

DD

Specified with a double digit number from 01 to 92.

Ordinal day of the year

DDD

Specified with a triple digit number from 001 to 366.

If the year is before 0000 or after 9999, the following additional rules apply:

  • Minus sign, - must prefix any year before 0000, (e.g. -3000-01-01).

  • Plus sign, + must prefix any year after 9999, (e.g. +11000-01-01).

  • The year must be separated with - from the next component:

    • if the next component is month, (e.g. +11000-01).

    • if the next component is day of the year, (e.g. +11000-123).

If the year component is prefixed with either - or +, and is separated from the next component, Year is allowed to contain up to nine digits. Thus, the allowed range of years is between -999,999,999 and +999,999,999. For all other cases, i.e. the year is between 0000 and 9999 (inclusive), Year must have exactly four digits (the year component is interpreted as a year of the Common Era (CE)).

The following formats are supported for specifying dates:

Format Description Example Interpretation of example

YYYY-MM-DD

Calendar date: Year-Month-Day

2015-07-21

2015-07-21

YYYYMMDD

Calendar date: Year-Month-Day

20150721

2015-07-21

YYYY-MM

Calendar date: Year-Month

2015-07

2015-07-01

YYYYMM

Calendar date: Year-Month

201507

2015-07-01

YYYY-Www-D

Week date: Year-Week-Day

2015-W30-2

2015-07-21

YYYYWwwD

Week date: Year-Week-Day

2015W302

2015-07-21

YYYY-Www

Week date: Year-Week

2015-W30

2015-07-20

YYYYWww

Week date: Year-Week

2015W30

2015-07-20

YYYY-Qq-DD

Quarter date: Year-Quarter-Day

2015-Q2-60

2015-05-30

YYYYQqDD

Quarter date: Year-Quarter-Day

2015Q260

2015-05-30

YYYY-Qq

Quarter date: Year-Quarter

2015-Q2

2015-04-01

YYYYQq

Quarter date: Year-Quarter

2015Q2

2015-04-01

YYYY-DDD

Ordinal date: Year-Day

2015-202

2015-07-21

YYYYDDD

Ordinal date: Year-Day

2015202

2015-07-21

YYYY

Year

2015

2015-01-01

The smallest components can be omitted. Cypher will assume omitted components to have their lowest possible value. For example, 2013-06 will be interpreted as being the same date as 2013-06-01.

Specifying times

Component Format Description

Hour

HH

Specified with a double digit number from 00 to 23.

Minute

MM

Specified with a double digit number from 00 to 59.

Second

SS

Specified with a double digit number from 00 to 59.

fraction

sssssssss

Specified with a number from 0 to 999999999. It is not required to specify leading zeros. fraction is an optional, sub-second component of Second. This can be separated from Second using either a full stop (.) or a comma (,). The fraction is in addition to the two digits of Second.

Cypher does not support leap seconds; UTC-SLS (UTC with Smoothed Leap Seconds) is used to manage the difference in time between UTC and TAI (International Atomic Time).

The following formats are supported for specifying times:

Format Description Example Interpretation of example

HH:MM:SS.sssssssss

Hour:Minute:Second.fraction

21:40:32.142

21:40:32.142

HHMMSS.sssssssss

Hour:Minute:Second.fraction

214032.142

21:40:32.142

HH:MM:SS

Hour:Minute:Second

21:40:32

21:40:32.000

HHMMSS

Hour:Minute:Second

214032

21:40:32.000

HH:MM

Hour:Minute

21:40

21:40:00.000

HHMM

Hour:Minute

2140

21:40:00.000

HH

Hour

21

21:00:00.000

The smallest components can be omitted. For example, a time may be specified with Hour and Minute, leaving out Second and fraction. On the other hand, specifying a time with Hour and Second, while leaving out Minute, is not possible.

Specifying time zones

The time zone is specified in one of the following ways:

  • As an offset from UTC.

  • Using the Z shorthand for the UTC (±00:00) time zone.

When specifying a time zone as an offset from UTC, the rules below apply:

  • The time zone always starts with either a plus (+) or minus (-) sign.

    • Positive offsets, i.e. time zones beginning with +, denote time zones east of UTC.

    • Negative offsets, i.e. time zones beginning with -, denote time zones west of UTC.

  • A double-digit hour offset follows the +/- sign.

  • An optional double-digit minute offset follows the hour offset, optionally separated by a colon (:).

  • The time zone of the International Date Line is denoted either by +12:00 or -12:00, depending on country.

When creating values of the ZONED DATETIME temporal instant type, the time zone may also be specified using a named time zone, using the names from the IANA time zone database. This may be provided either in addition to, or in place of the offset. The named time zone is given last and is enclosed in square brackets ([]). Should both the offset and the named time zone be provided, the offset must match the named time zone.

The following formats are supported for specifying time zones:

Format Description Example Supported for ZONED DATETIME Supported for ZONED TIME

Z

UTC

Z

±HH:MM

Hour:Minute

+09:30

±HH:MM[ZoneName]

Hour:Minute[ZoneName]

+08:45[Australia/Eucla]

±HHMM

Hour:Minute

+0100

±HHMM[ZoneName]

Hour:Minute[ZoneName]

+0200[Africa/Johannesburg]

±HH

Hour

-08

±HH[ZoneName]

Hour[ZoneName]

+08[Asia/Singapore]

[ZoneName]

[ZoneName]

[America/Regina]

Components of temporal instants

Components of temporal instant values can be accessed as properties.

Components of temporal instant values and where they are supported
Component Description Type Range/Format DATE ZONED DATETIME LOCAL DATETIME ZONED TIME LOCAL TIME

instant.year

The year component represents the astronomical year number of the instant.[1]

INTEGER

At least 4 digits. For more information, see the rules for using the Year component.

instant.quarter

The quarter-of-the-year component.

INTEGER

1 to 4.

instant.month

The month-of-the-year component.

INTEGER

1 to 12.

instant.week

The week-of-the-year component.[2]

INTEGER

1 to 53.

instant.weekYear

The year that the week-of-year component belongs to.[3]

INTEGER

At least 4 digits. For more information, see the rules for using the Year component.

instant.dayOfQuarter

The day-of-the-quarter component.

INTEGER

1 to 92.

instant.quarterDay

The day-of-the-quarter component (alias for instant.dayOfQuarter).

INTEGER

1 to 92.

instant.day

The day-of-the-month component.

INTEGER

1 to 31.

instant.ordinalDay

The day-of-the-year component.

INTEGER

1 to 366.

instant.dayOfWeek

The day-of-the-week component (the first day of the week is Monday).

INTEGER

1 to 7.

instant.weekDay

The day-of-the-week component (alias for instant.dayOfWeek).

INTEGER

1 to 7.

instant.hour

The hour component.

INTEGER

0 to 23.

instant.minute

The minute component.

INTEGER

0 to 59.

instant.second

The second component.[4]

INTEGER

0 to 59.

instant.millisecond

The millisecond component.

INTEGER

0 to 999.

instant.microsecond

The microsecond component.

INTEGER

0 to 999999.

instant.nanosecond

The nanosecond component.

INTEGER

0 to 999999999.

instant.timezone

The timezone component.

STRING

Depending on how the time zone was specified, this is either a time zone name or an offset from UTC in the format ±HHMM.

instant.offset

The timezone offset.

STRING

In the format ±HHMM.

instant.offsetMinutes

The timezone offset in minutes.

INTEGER

-1080 to +1080.

instant.offsetSeconds

The timezone offset in seconds.

INTEGER

-64800 to +64800.

instant.epochMillis

The number of milliseconds between 1970-01-01T00:00:00+0000 and the instant.[5]

INTEGER

Positive for instants after and negative for instants before 1970-01-01T00:00:00+0000.

instant.epochSeconds

The number of seconds between 1970-01-01T00:00:00+0000 and the instant.[6]

INTEGER

Positive for instants after and negative for instants before 1970-01-01T00:00:00+0000.

Examples

To work with a particular temporal instant type, its corresponding function must be used. For example, in order to create a property value of type ZONED DATETIME, the datetime() function must be used.

For specific examples, see:

DATE

To work with DATE values, including creating, parsing, and extracting components, use the date() function.

Example 1. DATE
Create a DATE property value
CREATE (n:Label)
SET n.date = date("2025-02-18")
RETURN n.date AS date, valueType(n.date) AS temporalValueType
Result
date temporalValueType

2025-02-18

"DATE NOT NULL"

Rows: 1

Create a DATE property value using components
CREATE (n:Label)
SET n.date = date({year: 2025, month: 2, day: 18})
RETURN n.date AS date, valueType(n.date) AS temporalValueType
Result
date temporalValueType

2025-02-18

"DATE NOT NULL"

Rows: 1

Parse a DATE using the week date format:
RETURN date('+2015-W13-4') AS theDate
Result
theDate

2015-03-26

Rows: 1

Get the components of a DATE value
WITH date({year: 1984, month: 10, day: 11}) AS d
RETURN d.year, d.quarter, d.month, d.week, d.weekYear, d.day, d.ordinalDay, d.dayOfWeek, d.dayOfQuarter
Result
d.year d.quarter d.month d.week d.weekYear d.day d.ordinalDay d.dayOfWeek d.dayOfQuarter

1984

4

10

41

1984

11

285

4

11

Rows: 1

LOCAL TIME

To work with LOCAL TIME values, including creating, parsing, and extracting components, use the localtime() function.

Example 2. LOCAL TIME
Create a LOCAL TIME property value
CREATE (n:Label)
SET n.localTime = localtime("12:34:56.789")
RETURN n.localTime AS localTime, valueType(n.localTime) AS temporalValueType
Result
localTime temporalValueType

12:34:56.789

"LOCAL TIME NOT NULL"

Rows: 1

Create a LOCAL TIME property value using components
CREATE (n:Label)
SET n.localTime = localtime({hour: 12, minute: 34, second: 56, millisecond: 789})
RETURN n.localTime AS localTime, valueType(n.localTime) AS temporalValueType
Result
localTime temporalValueType

12:34:56.789

"LOCAL TIME NOT NULL"

Rows: 1

Get the components of a LOCAL TIME value
WITH localtime({hour: 12, minute: 34, second: 56, millisecond: 789}) AS t
RETURN t.hour, t.minute, t.second, t.millisecond
Result
t.hour t.minute t.second t.millisecond

12

34

56

789

Rows: 1

ZONED TIME

To work with ZONED TIME values, including creating, parsing, and extracting components, use the time() function.

Example 3. ZONED TIME
Create a ZONED TIME property value with an offset
CREATE (n:Label)
SET n.zonedTime = time("12:34:56.789+02:00")
RETURN n.zonedTime AS zonedTime, valueType(n.zonedTime) AS temporalValueType
Result
zonedTime temporalValueType

12:34:56.789+02:00

"ZONED TIME NOT NULL"

Rows: 1

Create a ZONED TIME property value with components and a time zone
CREATE (n:Label)
SET n.zonedTime = time({hour: 12, minute: 34, second: 56, millisecond: 789, timezone: 'Europe/Stockholm'})
RETURN n.zonedTime AS zonedTime, valueType(n.zonedTime) AS temporalValueType
Result
time temporalValueType

12:34:56.789+01:00

"ZONED TIME NOT NULL"

Rows: 1

Get the components of a ZONED TIME value
WITH time("12:34:56.789+02:00") AS t
RETURN t.hour, t.minute, t.second, t.millisecond, t.offset
Result
t.hour t.minute t.second t.millisecond t.offset

12

34

56

789

"+02:00"

Rows: 1

LOCAL DATETIME

To work with LOCAL DATETIME values, including creating, parsing, and extracting components, use the localdatetime() function.

Example 4. LOCAL DATETIME
Create a LOCAL DATETIME property value using the ordinal date format:
CREATE (n:Label)
SET n.localDateTime = localdatetime("2025-02-18T12:34:56")
RETURN n.localDateTime AS localDateTime, valueType(n.localDateTime) AS temporalValueType
Result
localDateTime temporalValueType

2025-02-18T12:34:56

"LOCAL DATETIME NOT NULL"

Rows: 1

Create a LOCAL DATETIME property value using temporal components
CREATE (n:Label)
SET n.localDateTime = localdatetime({year: 2025, month: 2, day: 18, hour: 12, minute: 34, second: 56, millisecond: 789})
RETURN n.localDateTime AS localDateTime, valueType(n.localDateTime) AS temporalValueType
Result
localDatetime temporalValueType

2025-02-18T12:34:56.789

"LOCAL DATETIME NOT NULL"

Rows: 1

Parse a LOCAL DATETIME using the ordinal date format:
RETURN localdatetime('2015185T19:32:24') AS theLocalDateTime
Result
theLocalDateTime

2015-07-04T19:32:24

Rows: 1

Get the components of a LOCAL DATETIME value
WITH localdatetime({year: 2025, month: 2, day: 19, hour: 12, minute: 34, second: 56, millisecond: 789}) AS t
RETURN t.year, t.month, t.day, t.hour, t.minute, t.second, t.millisecond
Result
t.year t.month t.day t.hour t.minute t.second t.millisecond

2025

2

19

12

34

56

789

Rows: 1

ZONED DATETIME

To work with ZONED DATETIME values, including creating, parsing, and extracting components, use the datetime() function.

Example 5. ZONED DATETIME
Create a ZONED DATETIME property value using calendar date format
CREATE (n:Label)
SET n.zonedDateTime = datetime("2025-02-18T12:34:56.789+02:00")
RETURN n.zonedDateTime AS zonedDateTime, valueType(n.zonedDateTime) AS temporalValueType
Result
zonedDateTime temporalValueType

2025-02-18T12:34:56.789+02:00

"ZONED DATETIME NOT NULL"

Rows: 1

Create a ZONED DATETIME property value using temporal components
CREATE (n:Label)
SET n.zonedDateTime = datetime({year: 2025, month: 2, day: 18, hour: 12, minute: 34, second: 56, millisecond: 789, timezone: 'Europe/Stockholm'})
RETURN n.zonedDateTime, valueType(n.zonedDateTime) AS temporalValueType
Result
zonedDateTime temporalValueType

2025-02-18T12:34:56.789+01:00[Europe/Stockholm]

"ZONED DATETIME NOT NULL"

Rows: 1

Create a ZONED DATETIME property value using a timezone
CREATE (n:Label)
SET n.zonedDateTime = datetime({timezone: 'Europe/Stockholm'})
RETURN n.zonedDateTime AS zonedDateTime, valueType(n.zonedDateTime) AS temporalValueType
Result
zonedDateTime temporalValueType

2025-02-18T15:22:48.227+01:00[Europe/Stockholm]

"ZONED DATETIME NOT NULL"

Rows: 1

Parse a ZONED DATETIME using the calendar date format
RETURN datetime('2015-06-24T12:50:35.556+0100') AS theDateTime
Result
theDateTime

2015-06-24T12:50:35.556+01:00

Rows: 1

Get the date-related components of a ZONED DATETIME value:
WITH datetime({
  year: 1984, month: 11, day: 11,
  hour: 12, minute: 31, second: 14, nanosecond: 645876123,
  timezone: 'Europe/Stockholm'
}) AS d
RETURN d.year, d.quarter, d.month, d.week, d.weekYear, d.day, d.ordinalDay, d.dayOfWeek, d.dayOfQuarter
Result
d.year d.quarter d.month d.week d.weekYear d.day d.ordinalDay d.dayOfWeek d.dayOfQuarter

1984

4

11

45

1984

11

316

7

42

Rows: 1

Get the time-related components of a ZONED DATETIME value:
WITH datetime({
  year: 1984, month: 11, day: 11,
  hour: 12, minute: 31, second: 14, nanosecond: 645876123,
  timezone: 'Europe/Stockholm'
}) AS d
RETURN d.hour, d.minute, d.second, d.millisecond, d.microsecond, d.nanosecond
Result
d.hour d.minute d.second d.millisecond d.microsecond d.nanosecond

12

31

14

645

645876

645876123

Rows: 1

Get the epoch time and timezone-related components of a ZONED DATETIME value:
WITH datetime({
  year: 1984, month: 11, day: 11,
  hour: 12, minute: 31, second: 14, nanosecond: 645876123,
  timezone: 'Europe/Stockholm'
}) AS d
RETURN d.timezone, d.offset, d.offsetMinutes, d.epochSeconds, d.epochMillis
Result
d.timezone d.offset d.offsetMinutes d.epochSeconds d.epochMillis

"Europe/Stockholm"

"+01:00"

60

469020674

469020674645

Rows: 1

Truncating temporal values

The truncate functions in Neo4j allow you to reduce the precision of temporal values by truncating them to a specified component such as year, month, or second.

Example 6. Truncate DATE values

To truncate DATE values, use the date.truncate() function.

Get the first day of the current year:
RETURN date.truncate('year') AS firstDay
Result
firstDay

2022-01-01

Rows: 1

Get the date of the Thursday in the week of a specific date:
RETURN date.truncate('week', date('2019-10-01'), {dayOfWeek: 4}) AS thursday
Result
thursday

2019-10-03

Rows: 1

Example 7. Truncate LOCAL TIME values

To truncate LOCAL TIME values, use the localtime.truncate() function.

Get the start of the current minute for a specific LOCAL TIME value
RETURN localtime.truncate('minute', localtime("12:34:56.789")) AS truncatedMinute
Result
truncatedMinute

12:34

Rows: 1

Get the start of the current second using the system’s LOCAL TIME
RETURN localtime.truncate('second') AS currentSecond
Result
currentSecond

10:12:28

Rows: 1

Example 8. Truncate ZONED TIME values

To truncate ZONED TIME values, use the time.truncate() function.

Get the start of the current minute for a specific ZONED TIME value
RETURN time.truncate('minute', time("12:34:56.789+02:00")) AS truncatedMinute
Result
truncatedMinute

12:34+02:00

Rows: 1

Get the current ZONED TIME truncated to the nearest minute
RETURN time.truncate('minute', time()) AS currentTime
Result
truncatedTime

10:20Z

Rows: 1

Example 9. Truncate LOCAL DATETIME values

To truncate LOCAL DATETIME values, use the localdatetime.truncate() function.

Get the start of the hour for a specific LOCAL DATETIME
RETURN localdatetime.truncate('hour', localdatetime("2025-02-18T12:34:56.789")) AS truncatedHour
Result
truncatedHour

2025-02-18T12:00

Rows: 1

Get the start of the current month in LOCAL DATETIME
RETURN localdatetime.truncate('month') AS truncatedMonth
Result
truncatedMonth

2025-02-01T00:00

Rows: 1

Example 10. Truncate ZONED DATETIME values

To truncate ZONED DATETIME values, use the datetime.truncate() function.

Get the start of the minute for a specific ZONED DATETIME
RETURN datetime.truncate('minute', datetime("2025-02-18T12:34:56.789+02:00")) AS truncatedZonedDateTime
Result
truncatedZonedDateTime

2025-02-18T12:34+02:00

Rows: 1

Get the start of Wednesday for the current week in ZONED DATETIME
RETURN datetime.truncate('week', datetime(), {dayOfWeek: 3}) AS startOfWednesday
Result
startOfWednesday

2025-02-19T00:00Z

Rows: 1

Durations

Specifying durations

A DURATION represents a temporal amount, capturing the difference in time between two instants, and can be negative.

The specification of a DURATION is prefixed with a P, and can use either a unit-based form or a date-and-time-based form:

  • Unit-based form: P[nY][nM][nW][nD][T[nH][nM][nS]]

    • The square brackets ([]) denote an optional component (components with a zero value may be omitted).

    • The n denotes a numeric value within the bounds of a 64-bit integer.

    • The value of the last — and smallest — component may contain a decimal fraction.

    • Each component must be suffixed by a component identifier denoting the unit.

    • The unit-based form uses M as a suffix for both months and minutes. Therefore, time parts must always be preceded with T, even when no components of the date part are given.

    • The maximum total length of a duration is bounded by the number of seconds that can be held in a 64-bit integer.

  • Date-and-time-based form: P<date>T<time>.

    • Unlike the unit-based form, this form requires each component to be within the bounds of a valid LOCAL DATETIME.

The following table lists the component identifiers for the unit-based form:

Component identifier Description Comments

Y

Years

M

Months

Must be specified before T.

W

Weeks

D

Days

H

Hours

M

Minutes

Must be specified after T.

S

Seconds

Components of durations

A DURATION can have several components, each categorized into Months, Days, and Seconds groups.

Components of DURATION values are truncated within their component groups as follows:

First order DURATION components
Component Group Component Description Type Details

Months

duration.years

The total number of years.

INTEGER

Each set of 4 quarters is counted as 1 year; each set of 12 months is counted as 1 year.

duration.quarters

The total number of quarters.

INTEGER

Each year is counted as 4 quarters; each set of 3 months is counted as 1 quarter.

duration.months

The total number of months.

INTEGER

Each year is counted as 12 months; each_quarter_ is counted as 3 months.

Days

duration.weeks

The total number of weeks.

INTEGER

Each set of 7 days is counted as 1 week.

duration.days

The total number of days.

INTEGER

Each week is counted as 7 days.

Seconds

duration.hours

The total number of hours.

INTEGER

Each set of 60 minutes is counted as 1 hour; each set of 3600 seconds is counted as 1 hour.

duration.minutes

The total number of minutes.

INTEGER

Each hour is counted as 60 minutes; each set of 60 seconds is counted as 1 minute.

duration.seconds

The total number of seconds.

INTEGER

Each hour is counted as 3600 seconds; each minute is counted as 60 seconds.

duration.milliseconds

The total number of milliseconds

INTEGER

Each set of 1000 milliseconds is counted as 1 second.

duration.microseconds

The total number of microseconds.

INTEGER

Each millisecond is counted as 1000 microseconds.

duration.nanoseconds

The total number of nanoseconds.

INTEGER

Each microsecond is counted as 1000 nanoseconds.

Please note that:

  • Cypher uses UTC-SLS when handling leap seconds.

  • There are not always 24 hours in 1 day; when switching to/from daylight savings time, a day can have 23 or 25 hours.

  • There are not always the same number of days in a month.

  • Due to leap years, there are not always the same number of days in a year.

It is also possible to access the second order components of a component group bounded by the first order component of the group:

Second order DURATION components
Component Component Group Description Type

duration.quartersOfYear

Months

The number of quarters in the group that do not make a whole year.

INTEGER

duration.monthsOfYear

Months

The number of months in the group that do not make a whole year.

INTEGER

duration.monthsOfQuarter

Months

The number of months in the group that do not make a whole quarter.

INTEGER

duration.daysOfWeek

Days

The number of days in the group that do not make a whole week.

INTEGER

duration.minutesOfHour

Seconds

The number of minutes in the group that do not make a whole hour.

INTEGER

duration.secondsOfMinute

Seconds

The number of seconds in the group that do not make a whole minute.

INTEGER

duration.millisecondsOfSecond

Seconds

The number of milliseconds in the group that do not make a whole second.

INTEGER

duration.microsecondsOfSecond

Seconds

The number of microseconds in the group that do not make a whole second.

INTEGER

duration.nanosecondsOfSecond

Seconds

The number of nanoseconds in the group that do not make a whole second

INTEGER

Examples

Below are examples of parsing durations using the duration() function. More information can be found here.

Example 11. Return a duration of 14 days, 16 hours, and 12 minutes
Query
RETURN duration('P14DT16H12M') AS theDuration
Result
theDuration

P14DT16H12M

Rows: 1

Example 12. Return a duration of 5 months, 1 day, and 12 hours
Query
RETURN duration('P5M1.5D') AS theDuration
Result
theDuration

P5M1DT12H

Rows: 1

Example 13. Return a duration of 45 seconds
Query
RETURN duration('PT0.75M') AS theDuration
Result
theDuration

PT45S

Rows: 1

Example 14. Return a duration of 2 weeks, 3 days, and 12 hours
Query
RETURN duration('P2.5W') AS theDuration
Result
theDuration

P17DT12H

Rows: 1

Example 15. Get the month-based components of a DURATION value
Query
WITH duration({years: 1, months: 5, days: 111, minutes: 42}) AS d
RETURN d.years, d.quarters, d.quartersOfYear, d.months, d.monthsOfYear, d.monthsOfQuarter
Result
d.years d.quarters d.quartersOfYear d.months d.monthsOfYear d.monthsOfQuarter

1

5

1

17

5

2

Rows: 1

d.quarters has a value of 5 because the year of the duration has four quarters and there is another quarter in the five months. d.months has a value of 17 because it adds the 12 months in the year of the duration to the five months. d.quartersOfYear is the remaining quarter, counting towards the next full year. Similarly, d.monthsOfYear and d.monthsOfQuarter count towards the next full year and quarter respectively. See tables First order DURATION components and Second order DURATION components in Components of durations.

Example 16. Get the days-based components of a DURATION value
Query
WITH duration({months: 5, days: 25, hours: 1}) AS d
RETURN d.weeks, d.days, d.daysOfWeek
Result
d.weeks d.days d.daysOfWeek

3

25

4

Rows: 1

d.weeks has a value of 3 because the 25 days from the query are three full weeks (or 21 days). d.daysOfWeek are the remaining days, counting towards the next full week. See tables First order DURATION components and Second order DURATION components in Components of durations.

Example 17. Get the first order seconds-based components of a DURATION value
Query
WITH duration({
  years: 1, months:1, days:1, hours: 1,
  minutes: 1, seconds: 1, nanoseconds: 111111111
}) AS d
RETURN d.hours, d.minutes, d.seconds, d.milliseconds, d.microseconds, d.nanoseconds
Result
d.hours d.minutes d.seconds d.milliseconds d.microseconds d.nanoseconds

1

61

3661

3661111

3661111111

3661111111111

Rows: 1

d.minutes is the sum of 60 minutes of the hour and the one minute from the query as both duration.hours and duration.minutes are both seconds-based components. Similarly, d.seconds, d.milliseconds, d.microseconds and d.nanoseconds are sum values of the relevant seconds-based components from the query.

d.hours does not take the day from the query into account because duration.days is a days-based component.

See table First order DURATION components in Components of durations.

Example 18. Get the second order seconds-based components of a DURATION value
Query
WITH duration({
  years: 1, months:1, days:1,
  hours: 1, minutes: 1, seconds: 1, nanoseconds: 111111111
}) AS d
RETURN d.minutesOfHour, d.secondsOfMinute, d.millisecondsOfSecond, d.microsecondsOfSecond, d.nanosecondsOfSecond
Result
d.minutesOfHour d.secondsOfMinute d.millisecondsOfSecond d.microsecondsOfSecond d.nanosecondsOfSecond

1

1

111

111111

111111111

Rows: 1

The returned values all count towards the next full hour, minute or second respectively. For example, d.microsecondsOfSecond has a value of 111111 because it is the 111111111 nanoseconds from the query in microseconds (rounded down) but it is not another full second.

See table Second order DURATION components in Components of durations.

Example 19. Create a duration representing 1.5 days
Query
RETURN duration({days: 1, hours: 12}) AS theDuration
Result
theDuration

P1DT12H

Rows: 1

Example 20. Compute the DURATION between two temporal instants
Query
RETURN duration.between(date('1984-10-11'), date('2015-06-24')) AS theDuration
Result
theDuration

P30Y8M13D

Rows: 1

Example 21. Compute the number of days between two DATE values
Query
RETURN duration.inDays(date('2014-10-11'), date('2015-08-06')) AS theDuration
Result
theDuration

P299D

Rows: 1

Example 22. Get the DATE of the last day of the next month
Query
RETURN date.truncate('month', date() + duration('P2M')) - duration('P1D') AS lastDay
Result
lastDay

2022-07-31

Rows: 1

Example 23. Add a DURATION to a DATE
Query
RETURN time('13:42:19') + duration({days: 1, hours: 12}) AS theTime
Result
theTime

01:42:19.000000000+00:00

Rows: 1

Example 24. Add two DURATION values
Query
RETURN duration({days: 2, hours: 7}) + duration({months: 1, hours: 18}) AS theDuration
Result
theDuration

P1M2DT25H

Rows: 1

Example 25. Multiply a DURATION by a number
Query
RETURN duration({hours: 5, minutes: 21}) * 14 AS theDuration
Result
theDuration

PT74H54M

Rows: 1

Example 26. Divide a DURATION by a number
Query
RETURN duration({hours: 3, minutes: 16}) / 2 AS theDuration
Result
theDuration

PT1H38M

Rows: 1

Example 27. Examine whether two instants are less than one day apart
Query
WITH
  datetime('2015-07-21T21:40:32.142+0100') AS date1,
  datetime('2015-07-21T17:12:56.333+0100') AS date2
RETURN
CASE
  WHEN date1 < date2 THEN date1 + duration("P1D") > date2
  ELSE date2 + duration("P1D") > date1
END AS lessThanOneDayApart
Result
lessThanOneDayApart

true

Rows: 1

Example 28. Return the abbreviated name of the current month
Query
RETURN ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][date().month-1] AS month
Result
month

"Jun"

Rows: 1

Temporal indexing

All temporal types can be indexed, and thereby support exact lookups for equality predicates. Indexes for temporal instant types additionally support range lookups.


1. This is in accordance with the Gregorian calendar; i.e. years AD/CE start at year 1, and the year before that (year 1 BC/BCE) is 0, while year 2 BCE is -1 etc.
2. The first week of any year is the week that contains the first Thursday of the year, and thus always contains January 4.
3. For dates from December 29, this could be the next year, and for dates until January 3 this could be the previous year, depending on how week 1 begins.
4. Cypher does not support leap seconds; UTC-SLS (UTC with Smoothed Leap Seconds) is used to manage the difference in time between UTC and TAI (International Atomic Time).
5. The expression datetime().epochMillis returns the equivalent value of the timestamp() function.
6. For the nanosecond part of the epoch offset, the regular nanosecond component (instant.nanosecond) can be used.