[[date_nanos]]
=== Date nanoseconds field type
++++
<titleabbrev>Date nanoseconds</titleabbrev>
++++

This data type is an addition to the `date` data type. However there is an
important distinction between the two. The existing `date` data type stores
dates in millisecond resolution. The `date_nanos` data type stores dates
in nanosecond resolution, which limits its range of dates from roughly
1970 to 2262, as dates are still stored as a long representing nanoseconds
since the epoch.

Queries on nanoseconds are internally converted to range queries on this long
representation, and the result of aggregations and stored fields is converted
back to a string depending on the date format that is associated with the field.

Date formats can be customised, but if no `format` is specified then it uses
the default:

[source,js]
----
    "strict_date_optional_time_nanos||epoch_millis"
----
// NOTCONSOLE

For instance:

[source,console]
----
PUT my-index-000001?include_type_name=true
{
  "mappings": {
    "_doc": {
      "properties": {
        "date": {
          "type": "date_nanos" <1>
        }
      }
    }
  }
}

PUT my-index-000001/_bulk?refresh
{ "index" : { "_id" : "1" } }
{ "date": "2015-01-01" } <2>
{ "index" : { "_id" : "2" } }
{ "date": "2015-01-01T12:10:30.123456789Z" } <3>
{ "index" : { "_id" : "3" } }
{ "date": 1420070400000 } <4>

GET my-index-000001/_search
{
  "sort": { "date": "asc"}, <5>
  "runtime_mappings": {
    "date_has_nanos": {
      "type": "boolean",
      "script": "emit(doc['date'].value.nano != 0)" <6>
    }
  },
  "fields": [
    {
      "field": "date",
      "format": "strict_date_optional_time_nanos" <7>
    },
    {
      "field": "date_has_nanos"
    }
  ]
}
----
// TEST[s/_search/_search?filter_path=hits.hits/]
<1> The `date` field uses the default `format`.
<2> This document uses a plain date.
<3> This document includes a time.
<4> This document uses milliseconds-since-the-epoch.
<5> Note that the `sort` values that are returned are all in
nanoseconds-since-the-epoch.
<6> Use `.nano` in scripts to return the nanosecond component of the date.
<7> You can specify the format when fetching data using the <<search-fields-param,`fields` parameter>>.
Use <<strict-date-time-nanos,`strict_date_optional_time_nanos`>> or you'll get a rounded result.

////
[source,console-result]
----
{
  "hits": {
    "hits": [
      {
        "_id": "1",
        "_index": "my-index-000001",
        "_type": "_doc",
        "_score": null,
        "_source": {"date": "2015-01-01"},
        "fields": {
          "date": ["2015-01-01T00:00:00.000Z"],
          "date_has_nanos": [false]
        },
        "sort": [1420070400000000000]
      },
      {
        "_id": "3",
        "_type": "_doc",
        "_index": "my-index-000001",
        "_score": null,
        "_source": {"date": 1420070400000},
        "fields": {
          "date": ["2015-01-01T00:00:00.000Z"],
          "date_has_nanos": [false]
        },
        "sort": [1420070400000000000]
      },
      {
        "_id": "2",
        "_index": "my-index-000001",
        "_type": "_doc",
        "_score": null,
        "_source": {"date": "2015-01-01T12:10:30.123456789Z"},
        "fields": {
          "date": ["2015-01-01T12:10:30.123456789Z"],
          "date_has_nanos": [true]
        },
        "sort": [1420114230123456789]
      }
    ]
  }
}
----
////

You can also specify multiple date formats separated by `||`. The
same mapping parameters than with the `date` field can be used.

[WARNING]
====
Date nanoseconds
include::date.asciidoc[tag=decimal-warning]
====

[[date-nanos-limitations]]
==== Limitations

Aggregations are still on millisecond resolution, even when using a `date_nanos`
field. This limitation also affects <<transforms,{transforms}>>.
