%YAML 1.1
---
$schema: "http://stsci.edu/schemas/yaml-schema/draft-01"
id: "http://stsci.edu/schemas/asdf/time/time-1.1.0"
title: Represents an instance in time.
description: |
  A "time" is a single instant in time.  It may explicitly specify the
  way time is represented (the "format") and the "scale" which
  specifies the offset and scaling relation of the unit of time.

  Specific emphasis is placed on supporting time scales (e.g. UTC,
  TAI, UT1, TDB) and time representations (e.g. JD, MJD, ISO 8601)
  that are used in astronomy and required to calculate, e.g., sidereal
  times and barycentric corrections.

  Times may be represented as one of the following:

  - an object, with explicit `value`, and optional `format`, `scale`
    and `location`.

  - a string, in which case the format is guessed from across
    the unambiguous options (`iso`, `byear`, `jyear`, `yday`), and the
    scale is hardcoded to `UTC`.

  In either case, a single time tag may be used to represent an
  n-dimensional array of times, using either an `ndarray` tag or
  inline as (possibly nested) YAML lists.  If YAML lists, the same
  format must be used for all time values.

  The precision of the numeric formats should only be assumed to be as
  good as an IEEE-754 double precision (float64) value.  If
  higher-precision is required, the `iso` or `yday` format should be
  used.

examples:
  -
    - Example ISO time
    - |
        !time/time-1.1.0 "2000-12-31T13:05:27.737"

  -
    - Example year, day-of-year and time format time
    - |
        !time/time-1.1.0 "2001:003:04:05:06.789"

  -
    - Example Besselian Epoch time
    - |
        !time/time-1.1.0 B2000.0

  -
    - Example Besselian Epoch time, equivalent to above
    - |
        !time/time-1.1.0
          value: 2000.0
          format: byear

  -
    - Example list of times
    - |
        !time/time-1.1.0
          ["2000-12-31T13:05:27.737", "2000-12-31T13:06:38.444"]

  -
    - Example of an array of times
    - |
        !time/time-1.1.0
          value: !core/ndarray-1.0.0
            data: [2000, 2001]
            datatype: float64
          format: jyear

  -
    - Example with a location
    - |
        !time/time-1.1.0
          value: 2000.0
          format: jyear
          scale: tdb
          location:
            x: !unit/quantity-1.1.0
              value: 6378100
              unit: !unit/unit-1.0.0 m
            y: !unit/quantity-1.1.0
              value: 0
              unit: !unit/unit-1.0.0 m
            z: !unit/quantity-1.1.0
              value: 0
              unit: !unit/unit-1.0.0 m

definitions:
  iso_time:
    type: string
    pattern: "[0-9]{4}-(0[1-9])|(1[0-2])-(0[1-9])|([1-2][0-9])|(3[0-1])[T ]([0-1][0-9])|(2[0-4]):[0-5][0-9]:[0-5][0-9](.[0-9]+)?"

  byear:
    type: string
    pattern: "B[0-9]+(.[0-9]+)?"

  jyear:
    type: string
    pattern: "J[0-9]+(.[0-9]+)?"

  yday:
    type: string
    pattern: "[0-9]{4}:(00[1-9])|(0[1-9][0-9])|([1-2][0-9][0-9])|(3[0-5][0-9])|(36[0-5]):([0-1][0-9])|([0-1][0-9])|(2[0-4]):[0-5][0-9]:[0-5][0-9](.[0-9]+)?"

  string_formats:
    anyOf:
      - $ref: "#/definitions/iso_time"
      - $ref: "#/definitions/byear"
      - $ref: "#/definitions/jyear"
      - $ref: "#/definitions/yday"

  array_of_strings:
    type: array
    items:
      anyOf:
        - $ref: "#/definitions/array_of_strings"
        - $ref: "#/definitions/string_formats"

anyOf:
  - $ref: "#/definitions/string_formats"

  - $ref: "#/definitions/array_of_strings"

  - $ref: "../core/ndarray-1.0.0#/anyOf/1"

  - type: object
    properties:
      value:
        description: |
          The value(s) of the time.

        anyOf:
          - $ref: "#/definitions/string_formats"
          - $ref: "#/definitions/array_of_strings"
          - $ref: "../core/ndarray-1.0.0"
          - type: number

      format:
        description: |
          The format of the time.

          If not provided, the the format should be guessed from the
          string from among the following unambiguous options:
          `iso`, `byear`, `jyear` and `yday`.

          The supported formats are:

          - `iso`: ISO 8601 compliant date-time format
            `YYYY-MM-DDTHH:MM:SS.sss...`.  For example,
            `2000-01-01 00:00:00.000` is midnight on January 1,
            2000.  The `T` separating the date from the time
            section is optional.

          - `yday`: Year, day-of-year and time as
            `YYYY:DOY:HH:MM:SS.sss...`. The day-of-year (DOY) goes
            from 001 to 365 (366 in leap years). For example,
            `2000:001:00:00:00.000` is midnight on January 1,
            2000.

          - `byear`: Besselian Epoch year, eg. `B1950.0`.  The `B`
            is optional if the `byear` format is explicitly
            specified.

          - `jyear`: Julian Epoch year, eg. `J2000.0`.  The `J` is
            optional if the `jyear` format is explicitly
            specified.

          - `decimalyear`: Time as a decimal year, with integer
            values corresponding to midnight of the first day of
            each year. For example 2000.5 corresponds to the ISO
            time `2000-07-02 00:00:00`.

          - `jd`: Julian Date time format. This represents the
            number of days since the beginning of the Julian
            Period. For example, 2451544.5 in `jd` is midnight on
            January 1, 2000.

          - `mjd`: Modified Julian Date time format. This
            represents the number of days since midnight on
            November 17, 1858. For example, 51544.0 in MJD is
            midnight on January 1, 2000.

          - `gps`: GPS time: seconds from 1980-01-06 00:00:00 UTC
            For example, 630720013.0 is midnight on January 1,
            2000.

          - `unix`: Unix time: seconds from 1970-01-01 00:00:00
            UTC. For example, 946684800.0 in Unix time is midnight
            on January 1, 2000.  [TODO: Astropy's definition of
            UNIX time doesn't match POSIX's here.  What should we
            do for the purposes of ASDF?]

        enum:
          - iso
          - yday
          - byear
          - jyear
          - decimalyear
          - jd
          - mjd
          - gps
          - unix
          - cxcsec

      scale:
        description: |
          The time scale (or time standard) is a specification for
          measuring time: either the rate at which time passes; or
          points in time; or both. See also [3] and [4].

          These scales are defined in detail in [SOFA Time Scale and
          Calendar Tools](http://www.iausofa.org/sofa_ts_c.pdf).

          The supported time scales are:

          - `utc`: Coordinated Universal Time (UTC).  This is the
            default time scale, except for `gps`, `unix`.

          - `tai`: International Atomic Time (TAI).

          - `tcb`: Barycentric Coordinate Time (TCB).

          - `tcg`: Geocentric Coordinate Time (TCG).

          - `tdb`: Barycentric Dynamical Time (TDB).

          - `tt`: Terrestrial Time (TT).

          - `ut1`: Universal Time (UT1).

        enum:
          - utc
          - tai
          - tcb
          - tcg
          - tdb
          - tt
          - ut1

      location:
        description: |
          Specifies the observer location for scales that are
          sensitive to observer location, currently only `tdb`.  May
          be specified either with geocentric coordinates (X, Y, Z)
          with an optional unit or geodetic coordinates:
            - `long`: longitude in degrees
            - `lat`: in degrees
            - `h`: optional height

        type: object
        properties:
          x:
            $ref: "../unit/quantity-1.1.0"
          y:
            $ref: "../unit/quantity-1.1.0"
          z:
            $ref: "../unit/quantity-1.1.0"
        required: [x, y, z]

    required: [value]
...
