# Tipos temporales: Operaciones genéricas (Parte 1)

## Introducción

A continuación presentamos las funciones y operadores para tipos temporales. Estas funciones y operadores son polimórficos, es decir, sus argumentos pueden ser de varios tipos y el tipo del resultado puede depender del tipo de los argumentos. Para expresar esto, usamos la siguiente notación:

- `time` representa cualquier tipo de tiempo, es decir, `timestamptz`, `tstzspan`, `tstzset` o `tstzspanset`,

- `ttype` representa cualquier tipo temporal,

- `tdisc` representa cualquier tipo temporal con tipo de base discreto, es decir, `tbool`, `tint` o `ttext`,

- `tcont` representa cualquier tipo temporal con tipo de base continuo, es decir, `tfloat`, `tgeompoint` o `tgeogpoint`,

- `torder` representa cualquier tipo temporal cuyo tipo de base tiene definido un orden total, es decir, `tint`, `tfloat` o `ttext`,

- `talpha` representa cualquier tipo temporal alfanumérico, por ejemplo, `tint` or `ttext`,

- `tnumber` representa cualquier tipo de número temporal, es decir, `tint` o `tfloat`,

- `tpoint` representa un tipo de punto temporal, es decir, `tgeompoint` o `tgeogpoint`,

- `ttypeInst` representa cualquier tipo temporal con subtipo instante,

- `ttypeDiscSeq` representa cualquier tipo temporal con subtipo secuencia e interpolación discreta,

- `ttypeContSeq` representa cualquier tipo temporal con subtipo secuencia e interpolación contínua,

- `ttypeSeqSet` representa cualquier tipo temporal con subtipo conjunto de secuencias

- `base` representa cualquier tipo de base de un tipo temporal, es decir, `boolean`, `integer`, `float`, `text`, `geometry` o `geography`,

- `values` representa cualquier conjunto de valores de un tipo base de un tipo temporal, por ejemplo, `integer`, `intset`, `intspan` y `intspanset` para el tipo base `integer`

- `number` representa cualquier tipo de base numérico, es decir, `integer` o `float`,

- `numspan` representa cualquier tipo de rango numérico, es decir, `intspan` o `floatspan`,

- `geo` representa los tipos `geometry` o `geography`,

- `geompoint` representa el tipo `geometry` restringido a un punto.

- `point` representa los tipos `geometry` o `geography` restringidos a un punto.

- `lines` representa los tipos `geometry` o `geography` restringidos a una (multi)línea.

- `type[]` representa una matriz de `type`.

- `<type>` en el nombre de una función representa las funciones obtenidas al remplazar `<type>` por un `type` específico. Por ejemplo, `tintDiscSeq` o `tfloatDiscSeq` son representadas por `ttypeDiscSeq`.

Una forma común de generalizar las operaciones tradicionales a los tipos temporales es aplicar la operación en cada instante, lo que da un valor temporal como resultado. En ese caso, la operación sólo se define en la intersección de las extensiones temporales de los operandos; si las extensiones temporales son disjuntas, el resultado es nulo. Por ejemplo, los operadores de comparación temporal, como `#<`, determinan si los valores tomados por sus operandos en cada instante satisfacen la condición y devuelven un booleano temporal. A continuación se dan ejemplos de las diversas generalizaciones de los operadores.

    -- Comparación temporal
    SELECT tfloat '[2@2001-01-01, 2@2001-01-03)' #< tfloat '[1@2001-01-01, 3@2001-01-03)';
    -- {[f@2001-01-01, f@2001-01-02], (t@2001-01-02, t@2001-01-03)}
    SELECT tfloat '[1@2001-01-01, 3@2001-01-03)' #< tfloat '[3@2001-01-03, 1@2001-01-05)';
    -- NULL

    -- Adición temporal
    SELECT tint '[1@2001-01-01, 1@2001-01-03)' + tint '[2@2001-01-02, 2@2001-01-05)';
    -- [3@2001-01-02, 3@2001-01-03)

    -- Intersección temporal
    SELECT tintersects(tgeompoint '[Point(0 1)@2001-01-01, Point(3 1)@2001-01-04)',
    geometry 'Polygon((1 0,1 2,2 2,2 0,1 0))');
    -- {[f@2001-01-01, t@2001-01-02, t@2001-01-03], (f@2001-01-03, f@2001-01-04]}

    -- Distancia temporal
    SELECT tgeompoint '[Point(0 0)@2001-01-01 08:00:00, Point(0 1)@2001-01-03 08:10:00)' <->
    tgeompoint '[Point(0 0)@2001-01-02 08:05:00, Point(1 1)@2001-01-05 08:15:00)';
    -- [0.5@2001-01-02 08:05:00+00, 0.745184033794557@2001-01-03 08:10:00+00)

Otro requisito común es determinar si los operandos satisfacen alguna vez o siempre una condición con respecto a una operación. Estos se pueden obtener aplicando los operadores de comparación alguna vez o siempre. Estos operadores se indican anteponiendo los operadores de comparación tradicionales con, respectivamente, `?` (alguna vez) y `%` (siempre). A continuación se dan ejemplos de operadores de comparación alguna vez y siempre.

    -- ¿Se cruzan los operandos alguna vez?
    SELECT eIntersects(tgeompoint '[Point(0 1)@2001-01-01, Point(3 1)@2001-01-04)',
      geometry 'Polygon((1 0,1 2,2 2,2 0,1 0))') ?= true;
    -- true

    -- ¿Se cruzan los operandos siempre?
    SELECT aIntersects(tgeompoint '[Point(0 1)@2001-01-01, Point(3 1)@2001-01-04)',
      geometry 'Polygon((0 0,0 2,4 2,4 0,0 0))') %= true;
    -- true

    -- ¿Es el operando izquierdo alguna vez menor que el derecho?
    SELECT (tfloat '[1@2001-01-01, 3@2001-01-03)' ?<
      tfloat '[3@2001-01-01, 1@2001-01-03)') ?= true;
    -- true

    -- ¿Es el operando izquierdo siempre menor que el derecho?
    SELECT (tfloat '[1@2001-01-01, 3@2001-01-03)' %<
      tfloat '[2@2001-01-01, 4@2001-01-03)') %= true;
    -- true

Por ejemplo, la función `eIntersects` determina si hay un instante en el que los dos argumentos se cruzan espacialmente.

A continuación describimos las funciones y operadores para tipos temporales. Para mayor concisión, en los ejemplos usamos principalmente secuencias compuestas por dos instantes.

## Entrada y salida

MobilityDB generaliza los formatos de entrada y salida Well-Known Text (WKT), Moving Features JSON (MF-JSON) y Well-Known Binary (WKB) del Open Geospatial Consortium para todos los tipos temporales. Presentamos a continuación las funciones de entrada y salida para los tipos temporales. Empezamos describiendo formato WKT.

Un valor de instante es un par de la forma `v@t`, donde `v` es un valor del tipo de base y `t` es un valor de `timestamptz`. Ejemplos de entrada de valores de instante son los siguientes:

    SELECT tbool 'true@2001-01-01 08:00:00';
    SELECT tint '1@2001-01-01 08:00:00';
    SELECT tfloat '1.5@2001-01-01 08:00:00';
    SELECT ttext 'AAA@2001-01-01 08:00:00';
    SELECT tgeompoint 'Point(0 0)@2017-01-01 08:00:05';
    SELECT tgeogpoint 'Point(0 0)@2017-01-01 08:00:05';

Un valor de secuencia es un conjunto de valores `v1@t1,...,vn@tn` delimitado por límites superior e inferior, que pueden ser inclusivo (representados por ‘`[`’ y ‘`]`’) o exclusivos (representados por ‘`(`’ y ‘`)`’). Un valor de secuencia compuesto por una sola pareja `v@t` se denomina secuencia instantánea. Los valores de secuencia tienen una función de interpolación asociada que puede ser discreta, lineal o escalonada. Por definición, los límites inferior y superior de una secuencia instantánea o de un valor de secuencia con interpolación discreta son inclusivos. La extensión temporal de un valor de secuencia con interpolación discreta es un conjunto de marcas de tiempo. Ejemplos de valores de secuencia con interpolación discreta son los siguientes.

    SELECT tbool '{true@2001-01-01 08:00:00, false@2001-01-03 08:00:00}';
    SELECT tint '{1@2001-01-01 08:00:00, 2@2001-01-03 08:00:00}';
    SELECT tint '{1@2001-01-01 08:00:00}'; -- Instantaneous sequence
    SELECT tfloat '{1.0@2001-01-01 08:00:00, 2.0@2001-01-03 08:00:00}';
    SELECT ttext '{AAA@2001-01-01 08:00:00, BBB@2001-01-03 08:00:00}';
    SELECT tgeompoint '{Point(0 0)@2017-01-01 08:00:00, Point(0 1)@2017-01-02 08:05:00}';
    SELECT tgeogpoint '{Point(0 0)@2017-01-01 08:00:00, Point(0 1)@2017-01-02 08:05:00}';

La extensión temporal de un valor de secuencia con interpolación lineal o escalonada es un período definido por el primer y el últimpo instante, así como por los límites inferior y superior. Ejemplos de valores de secuencia con interpolación lineal son los siguientes:

    SELECT tbool '[true@2001-01-01 08:00:00, true@2001-01-03 08:00:00]';
    SELECT tint '[1@2001-01-01 08:00:00, 1@2001-01-03 08:00:00]';
    SELECT tfloat '[2.5@2001-01-01 08:00:00, 3@2001-01-03 08:00:00, 1@2001-01-04 08:00:00]';
    SELECT tfloat '[1.5@2001-01-01 08:00:00]'; -- Instantaneous sequence
    SELECT ttext '[BBB@2001-01-01 08:00:00, BBB@2001-01-03 08:00:00]';
    SELECT tgeompoint '[Point(0 0)@2017-01-01 08:00:00, Point(0 0)@2017-01-01 08:05:00)';
    SELECT tgeogpoint '[Point(0 0)@2017-01-01 08:00:00, Point(0 1)@2017-01-01 08:05:00,
      Point(0 0)@2017-01-01 08:10:00)';

Los valores de secuencia cuyo tipo base es continuo pueden especificar que la interpolación es escalonada con el prefijo `Interp=Step`. Si no se especifica, se supone que la interpolación es lineal por defecto. A continuación se dan ejemplos de valores de secuencia con interpolación escalonada:

    SELECT tfloat 'Interp=Step;[2.5@2001-01-01 08:00:00, 3@2001-01-01 08:10:00]';
    SELECT tgeompoint 'Interp=Step;[Point(0 0)@2017-01-01 08:00:00,
      Point(1 1)@2017-01-01 08:05:00, Point(1 1)@2017-01-01 08:10:00)';
    SELECT tgeompoint 'Interp=Step;[Point(0 0)@2017-01-01 08:00:00,
     Point(1 1)@2017-01-01 08:05:00, Point(0 0)@2017-01-01 08:10:00)';
    ERROR:  Invalid end value for temporal sequence with step interpolation
    SELECT tgeogpoint 'Interp=Step;[Point(0 0)@2017-01-01 08:00:00,
      Point(1 1)@2017-01-01 08:10:00]';

Los dos últimos instantes de un valor de secuencia con interpolación discreta y límite superior exclusivo deben tener el mismo valor base, como se muestra en el segundo y tercer ejemplo anteriores.

Un valor de conjunto de secuencias es un conjunto `{v1,...,vn}` donde cada `vi` es un valor de secuencia. La interpolación de los valores conjunto de secuencias solo puede ser lineal o escalonada, no discreta. Todas las secuencias que componen un valor de conjunto de secuencias deben tener la misma interpolación. La extensión temporal de un valor de conjunto de secuencias es un conjunto de períodos. Ejemplos de valores de conjunto de secuencias con interpolación lineal son los siguientes:

    SELECT tbool '{[false@2001-01-01 08:00:00, false@2001-01-03 08:00:00),
      [true@2001-01-03 08:00:00], (false@2001-01-04 08:00:00, false@2001-01-06 08:00:00]}';
    SELECT tint '{[1@2001-01-01 08:00:00, 1@2001-01-03 08:00:00),
      [2@2001-01-04 08:00:00, 3@2001-01-05 08:00:00, 3@2001-01-06 08:00:00]}';
    SELECT tfloat '{[1@2001-01-01 08:00:00, 2@2001-01-03 08:00:00, 2@2001-01-04 08:00:00,
      3@2001-01-06 08:00:00]}';
    SELECT ttext '{[AAA@2001-01-01 08:00:00, BBB@2001-01-03 08:00:00, BBB@2001-01-04 08:00:00),
      [CCC@2001-01-05 08:00:00, CCC@2001-01-06 08:00:00]}';
    SELECT tgeompoint '{[Point(0 0)@2017-01-01 08:00:00, Point(0 1)@2017-01-01 08:05:00),
      [Point(0 1)@2017-01-01 08:10:00, Point(1 1)@2017-01-01 08:15:00)}';
    SELECT tgeogpoint '{[Point(0 0)@2017-01-01 08:00:00, Point(0 1)@2017-01-01 08:05:00),
      [Point(0 1)@2017-01-01 08:10:00, Point(1 1)@2017-01-01 08:15:00)}';

Los valores de conjunto de secuencias cuyo tipo base es continuo pueden especificar que la interpolación es escalonada con el prefijo `Interp=Step`. Si no se especifica, se supone que la interpolación es lineal por defecto. A continuación se dan ejemplos de valores de conjunto de secuencias con interpolación escalonada:

    SELECT tfloat 'Interp=Step;{[1@2001-01-01 08:00:00, 2@2001-01-03 08:00:00,
      2@2001-01-04 08:00:00, 3@2001-01-06 08:00:00]}';
    SELECT tgeompoint 'Interp=Step;{[Point(0 0)@2017-01-01 08:00:00,
      Point(0 1)@2017-01-01 08:05:00], [Point(0 1)@2017-01-01 08:10:00,
      Point(0 1)@2017-01-01 08:15:00)}';
    SELECT tgeogpoint 'Interp=Step;{[Point(0 0)@2017-01-01 08:00:00,
      Point(0 1)@2017-01-01 08:05:00], [Point(0 1)@2017-01-01 08:10:00,
      Point(0 1)@2017-01-01 08:15:00)}';

Para los puntos temporales, es posible especificar el identificador de referencia espacial (SRID) utilizando la representación extendida de texto conocido (EWKT) de la siguiente manera:

    SELECT tgeompoint 'SRID=5435;[Point(0 0)@2001-01-01,Point(0 1)@2001-01-02]'

Todas las geometrías componentes serán entonces del SRID dado. Además, cada geometría componente puede especificar su SRID con el formato EWKT como en el siguiente ejemplo

    SELECT tgeompoint '[SRID=5435;Point(0 0)@2001-01-01,SRID=5435;Point(0 1)@2001-01-02]'

Se genera un error si las geometrías componentes no están todas en el mismo SRID o si el SRID de una geometría componente es diferente al del punto temporal.

    SELECT tgeompoint '[SRID=5435;Point(0 0)@2001-01-01,SRID=4326;Point(0 1)@2001-01-02]';
    -- ERROR: Geometry SRID (4326) does not match temporal type SRID (5435)
    SELECT tgeompoint 'SRID=5435;[SRID=4326;Point(0 0)@2001-01-01,
      SRID=4326;Point(0 1)@2001-01-02]'
    -- ERROR: Geometry SRID (4326) does not match temporal type SRID (5435)

Damos a continuación las funciones de entrada y salida en formato textual (Well-Known Text o WKT), binario (Well-Known Binary o WKB) y Moving Features JSON (MF-JSON) para los tipos alfanuméricos temporales. Las funciones correspondientes para los puntos temporales se detallan en la tpoint_inout. El formato de salida predeterminado de todos los tipos alfanuméricos temporales es el formato de texto conocido. La función `asText` que se da a continuación permite determinar la salida de valores temporales de punto flotante.

- Devuelve la representación textual conocida (Well-Known Text o WKT)

  `asText(tfloat,maxdecdigits=15) → text`

  El argumento `maxdecdigits` puede usarse para establecer el número máximo de decimales en la salida de los valores en punto flotante (por defecto 15).

      SELECT asText(tfloat '[10.55@2001-01-01, 25.55@2001-01-02]', 0);
      -- [11@2001-01-01, 26@2001-01-02]

- Devuelve la representación binaria conocida (Well-Known Binary o WKB)

  `asBinary(ttype,endian text='') → bytea`

  El resultado se codifica utilizando la codificación little-endian (NDR) o big-endian (XDR). Si no se especifica ninguna codificación, se utiliza la codificación de la máquina.

      SELECT asBinary(tbool 'true@2001-01-01');
      -- \x011a000101009c57d3c11c0000
      SELECT asBinary(tint '1@2001-01-01', 'XDR');
      -- \x000023010000000100001cc1d3579c00
      SELECT asBinary(tfloat '1.5@2001-01-01');
      -- \x01210001000000000000f83f009c57d3c11c0000
      SELECT asBinary(ttext 'AAA@2001-01-01');
      -- \x01290001040000000000000041414100009c57d3c11c0000

- Devuelve la representación hexadecimal binaria conocida (HexWKB) en formato texto

  `asHexWKB(ttype,endian text='') → text`

  El resultado se codifica utilizando la codificación little-endian (NDR) o big-endian (XDR). Si no se especifica ninguna codificación, se utiliza la codificación de la máquina.

      SELECT asHexWKB(tbool 'true@2001-01-01');
      -- 011A000101009C57D3C11C0000
      SELECT asHexWKB(tint '1@2001-01-01', 'XDR');
      -- 000023010000000100001CC1D3579C00
      SELECT asHexWKB(tfloat '1.5@2001-01-01');
      -- 01210001000000000000F83F009C57D3C11C0000
      SELECT asHexWKB(ttext 'AAA@2001-01-01');
      -- 01290001040000000000000041414100009C57D3C11C0000

- Devuelve la representación JSON de características móviles (Moving Features JSON o MF-JSON)

  `asMFJSON(ttype,options=0,flags=0,maxdecdigits=15) → bytea`

  El argumento `options` puede usarse para agregar un cuadro delimitador en la salida MFJSON:

  - 0: significa que no hay opción (valor por defecto)

  - 1: cuadro delimitador MFJSON

  El argumento `flags` puede usarse para personalizar la salida JSON, por ejemplo, para producir una salida JSON fácil de leer (para lectores humanos). Consulte la documentación de la biblioteca `json-c` para conocer los valores possible. Los valores típicos son los siguientes:

  - 0: means no option (default value)

  - 1: JSON_C_TO_STRING_SPACED

  - 2: JSON_C_TO_STRING_PRETTY

  El argumento `maxdecdigits` puede usarse para establecer el número máximo de decimales en la salida de los valores en punto flotante (por defecto 15).

      SELECT asMFJSON(tbool 't@2001-01-01 18:00:00', 1);
      /* {"type":"MovingBoolean","period":{"begin":"2001-01-01T18:00:00+01",
        "end":"2001-01-01T18:00:00+01","lowerInc":true,"upperInc":true},
        "values":[true],"datetimes":["2001-01-01T18:00:00+01"],"interpolation":"None"} */
      SELECT asMFJSON(tint '{10@2001-01-01 18:00:00, 25@2001-01-01 18:10:00}', 1);
      /* {"type":"MovingInteger","bbox":[10,25],"period":{"begin":"2001-01-01T18:00:00+01",
         "end":"2001-01-01T18:10:00+01"},"values":[10,25],"datetimes":["2001-01-01T18:00:00+01",
         "2001-01-01T18:10:00+01"],"lowerInc":true,"upperInc":true,
         "interpolation":"Discrete"} */
      SELECT asMFJSON(tfloat '[10.5@2001-01-01 18:00:00+02, 25.5@2001-01-01 18:10:00+02]');
      /* {"type":"MovingFloat","values":[10.5,25.5],"datetimes":["2001-01-01T17:00:00+01",
        "2001-01-01T17:10:00+01"],"lowerInc":true,"upperInc":true,"interpolation":"Linear"} */
      SELECT asMFJSON(ttext '{[walking@2001-01-01 18:00:00+02,
        driving@2001-01-01 18:10:00+02]}');
      /* {"type":"MovingText","sequences":[{"values":["walking","driving"],
        "datetimes":["2001-01-01T17:00:00+01","2001-01-01T17:10:00+01"],
        "lowerInc":true,"upperInc":true}],"interpolation":"Step"} */

- Entrar un valor temporal de su representación binaria conocida (WKB)

  `ttypeFromBinary(bytea) → ttype`

  Hay una función por tipo temporal, el nombre de la función tiene como prefijo el nombre del tipo, que son `tbool` o `tint` en los ejemplos a continuación.

      SELECT tboolFromBinary('\x010d000101009c57d3c11c0000');
      -- t@2001-01-01
      SELECT tintFromBinary('\x000016010000000100001cc1d3579c00');
      -- 1@2001-01-01
      SELECT tfloatFromBinary('\x01130081000000000000f83f009c57d3c11c0000');
      -- 1.5@2001-01-01
      SELECT ttextFromBinary('\x01170001040000000000000041414100009c57d3c11c0000');
      -- "AAA"@2001-01-01

- Entrar un valor temporal de su representación hexadecimal binaria conocida (HexWKB)

  `ttypeFromHexWKB(text) → ttype`

  Hay una función por tipo temporal, el nombre de esta función tiene como prefijo el nombre del tipo, que son `tbool` o `tint` en los ejemplos a continuación

      SELECT tboolFromHexWKB('010D000101009C57D3C11C0000');
      -- t@2001-01-01
      SELECT tintFromHexWKB('000016010000000100001CC1D3579C00');
      -- 1@2001-01-01
      SELECT tfloatFromHexWKB('01130081000000000000F83F009C57D3C11C0000');
      -- 1.5@2001-01-01
      SELECT ttextFromHexWKB('01170001040000000000000041414100009C57D3C11C0000');
      -- "AAA"@2001-01-01

- Entrar un valor temporal de su representación Moving Features JSON (MF-JSON)

  `ttypeFromMFJSON(bytea) → ttype`

  Hay una función por tipo temporal, el nombre de esta función tiene como prefijo el nombre del tipo, que son `tbool` o `tint` en los ejemplos a continuación

      SELECT tboolFromMFJSON(text
        '{"type":"MovingBoolean","period":{"begin":"2001-01-01T18:00:00+01",
        "end":"2001-01-01T18:00:00+01","lowerInc":true,"upperInc":true},
        "values":[true],"datetimes":["2001-01-01T18:00:00+01"],"interpolation":"None"}');
      -- t@2001-01-01 18:00:00
      SELECT tintFromMFJSON(text
        '{"type":"MovingInteger","bbox":[10,25],"period":{"begin":"2001-01-01T18:00:00+01",
         "end":"2001-01-01T18:10:00+01"},"values":[10,25],"datetimes":["2001-01-01T18:00:00+01",
         "2001-01-01T18:10:00+01"],"lowerInc":true,"upperInc":true,
         "interpolation":"Discrete"}');
      -- {10@2001-01-01 18:00:00, 25@2001-01-01 18:10:00}
      SELECT tfloatFromMFJSON(text
        '{"type":"MovingFloat","values":[10.5,25.5],"datetimes":["2001-01-01T17:00:00+01",
         "2001-01-01T17:10:00+01"],"lowerInc":true,"upperInc":true,
         "interpolation":"Linear"}');
      -- [10.5@2001-01-01 18:00:00, 25.5@2001-01-01 18:10:00]'
      SELECT ttextFromMFJSON(text
        '{"type":"MovingText","sequences":[{"values":["walking","driving"],
        "datetimes":["2001-01-01T17:00:00+01","2001-01-01T17:10:00+01"],
        "lowerInc":true,"upperInc":true}],"interpolation":"Step"}');
      -- {["walking"@2001-01-01 18:00:00, "driving"@2001-01-01 18:10:00]}');

## Constructores

A continuación, damos las funciones de constructor para los distintos subtipos. El uso de la función de constructor suele ser más conveniente que escribir una constante literal.

- Constructores para tipos temporales que tienen un valor constante

  Estos constructores tienen dos argumentos, un tipo base y un tipo de tiempo, donde el último es un valor de `timestamptz`, `tstzset`, `tstzspan` o `tstzspanset` para construir, respectivamente, un valor de subtipo instante, una secuencia con interpolación discreta, una secuencia con interpolación linear o escalonada o un conjunto de secuencias. Las funciones para valores de secuencia o de conjunto de secuencias con tipo de base continuo tienen además un tercer argumento opcional que indica si el valor temporal resultante tiene interpolación lineal o escalonada. Se asume por defecto una interpolación lineal si el argumento no se especifica.

  `ttype(base,timestamptz) → ttypeInst`

  `ttype(base,tstzset) → ttypeDiscSeq`

  `ttype(base,tstzspan,interp='linear') → ttypeContSeq`

  `ttype(base,tstzspanset,interp='linear') → ttypeSeqSet`

      SELECT tbool(true, timestamptz '2001-01-01');
      SELECT tint(1, timestamptz '2001-01-01');
      SELECT tfloat(1.5, tstzset '{2001-01-01, 2001-01-02}');
      SELECT ttext('AAA', tstzset '{2001-01-01, 2001-01-02}');
      SELECT tfloat(1.5, tstzspan '[2001-01-01, 2001-01-02]');
      SELECT tfloat(1.5, tstzspan '[2001-01-01, 2001-01-02]', 'step');
      SELECT tgeompoint('Point(0 0)', tstzspan '[2001-01-01, 2001-01-02]');
      SELECT tgeogpoint('SRID=7844;Point(0 0)', tstzspanset '{[2001-01-01, 2001-01-02],
        [2001-01-03, 2001-01-04]}', 'step');

- Constructores para tipos temporales de subtipo secuencia

  Estos constructores tienen un primer argumento obligatorio, que es una matriz de valores de los valores instantáneos correspondientes y argumentos opcionales adicionales. El segundo argumento establece la interpolación. Si no se proporciona el argumento, es por defecto escalonada para los tipos de base base discretos como los enteros y es lineal para tipos de base continuous como los flotantes. Se genera un error cuando se establece la interpolación lineal para valores temporales con tipos de base discretos. Para secuencias continuas, el tercero y el cuarto argumentos son valores booleanos que indican, respectivamente, si los límites izquierdo y derecho son inclusivos o exclusivos. Se supone que estos argumentos son verdaderos de forma predeterminada si no se especifican.

  `ttypeSeq(ttypeInst[],interp={'step','linear'},leftInc bool=true,`

  `rightInc bool=true) → ttypeSeq`

      SELECT tboolSeq(ARRAY[tbool 'true@2001-01-01 08:00:00','false@2001-01-01 08:05:00'],
        'discrete');
      SELECT tintSeq(ARRAY[tint '1@2001-01-01 08:00:00', '2@2001-01-01 08:05:00']);
      SELECT tintSeq(ARRAY[tint '1@2001-01-01 08:00:00', '2@2001-01-01 08:05:00'], 'linear');
      -- ERROR:  The temporal type cannot have linear interpolation
      SELECT tfloatSeq(ARRAY[tfloat '1.0@2001-01-01 08:00:00', '2.0@2001-01-01 08:05:00'],
        'step', false, true);
      SELECT ttextSeq(ARRAY[ttext 'AAA@2001-01-01 08:00:00', 'BBB@2001-01-01 08:05:00']);
      SELECT tgeompointSeq(ARRAY[tgeompoint 'Point(0 0)@2001-01-01 08:00:00',
        'Point(0 1)@2001-01-01 08:05:00', 'Point(1 1)@2001-01-01 08:10:00'], 'discrete');
      SELECT tgeogpointSeq(ARRAY[tgeogpoint 'Point(1 1)@2001-01-01 08:00:00',
        'Point(2 2)@2001-01-01 08:05:00']);

- Constructores para tipos temporales de subtipo conjunto de secuencias

  `ttypeSeqSet(ttypeContSeq[]) → ttypeSeqSet`

  `ttypeSeqSetGaps(ttypeInst[],maxt=NULL,maxdist=NULL,interp='linear') → ttypeSeqSet`

  Un primer conjunto de constructores tiene un solo argumento, que es una matriz de valores de los valores de secuencia correspondientes. La interpolación del valor temporal resultante depende de la interpolación de las secuencias que lo componen. Se genera un error si las secuencias que componen la matriz tienen una interpolación diferente.

      SELECT tboolSeqSet(ARRAY[tbool '[false@2001-01-01 08:00:00, false@2001-01-01 08:05:00)',
        '[true@2001-01-01 08:05:00]','(false@2001-01-01 08:05:00, false@2001-01-01 08:10:00)']);
      SELECT tintSeqSet(ARRAY[tint '[1@2001-01-01 08:00:00, 2@2001-01-01 08:05:00,
        2@2001-01-01 08:10:00, 2@2001-01-01 08:15:00)']);
      SELECT tfloatSeqSet(ARRAY[tfloat '[1.0@2001-01-01 08:00:00, 2.0@2001-01-01 08:05:00,
        2.0@2001-01-01 08:10:00]', '[2.0@2001-01-01 08:15:00, 3.0@2001-01-01 08:20:00)']);
      SELECT tfloatSeqSet(ARRAY[tfloat 'Interp=Step;[1.0@2001-01-01 08:00:00,
        2.0@2001-01-01 08:05:00, 2.0@2001-01-01 08:10:00]',
        'Interp=Step;[3.0@2001-01-01 08:15:00, 3.0@2001-01-01 08:20:00)']);
      SELECT ttextSeqSet(ARRAY[ttext '[AAA@2001-01-01 08:00:00, AAA@2001-01-01 08:05:00)',
        '[BBB@2001-01-01 08:10:00, BBB@2001-01-01 08:15:00)']);
      SELECT tgeompointSeqSet(ARRAY[tgeompoint '[Point(0 0)@2001-01-01 08:00:00,
        Point(0 1)@2001-01-01 08:05:00, Point(0 1)@2001-01-01 08:10:00)',
        '[Point(0 1)@2001-01-01 08:15:00, Point(0 0)@2001-01-01 08:20:00)']);
      SELECT tgeogpointSeqSet(ARRAY[tgeogpoint
        'Interp=Step;[Point(0 0)@2001-01-01 08:00:00, Point(0 0)@2001-01-01 08:05:00)',
        'Interp=Step;[Point(1 1)@2001-01-01 08:10:00, Point(1 1)@2001-01-01 08:15:00)']);
      SELECT tfloatSeqSet(ARRAY[tfloat 'Interp=Step;[1.0@2001-01-01 08:00:00,
        2.0@2001-01-01 08:05:00, 2.0@2001-01-01 08:10:00]',
        '[3.0@2001-01-01 08:15:00, 3.0@2001-01-01 08:20:00)']);
      -- ERROR:  The temporal values must have the same interpolation

  Otro conjunto de constructores para valores de conjunto de secuencias tiene como primer argumento una matriz de valores de instante correspondientes, y dos argumentos que establecen un intervalo de tiempo máximo y una distancia máxima tal que se introduce un espacio entre secuencias del resultado siempre que dos instantes de entrada consecutivos tengan un intervalo de tiempo o una distancia mayor que estos valores. Para puntos temporales, la distancia se especifica en unidades del sistema de coordenadas. Estos dos argumentos de brechas son opcionales, pero al menos uno de ellos debe especificarse. Además, cuando el tipo base es continuo, un último argumento adicional establece si la interpolación es escalonada o lineal. Si no se especifica este argumento, se asume que es lineal por defecto.

  Los parámetros de la función dependen del tipo temporal. Por ejemplo, el parámetro de interpolación no está permitido para tipos temporales con subtipos discretos como `tint`. De manera similar, el parámetro `maxdist` no está permitido para tipos escalares como `ttext` que no tienen una función de distancia estándar.

      SELECT tintSeqSetGaps(ARRAY[tint '1@2001-01-01', '3@2001-01-02', '4@2001-01-03',
        '5@2001-01-05'], '1 day', 1);
      -- {[1@2001-01-01], [3@2001-01-02, 4@2001-01-03], [5@2001-01-05]}
      SELECT ttextSeqSetGaps(ARRAY[ttext 'AA@2001-01-01', 'BB@2001-01-02', 'AA@2001-01-03',
        'CC@2001-01-05'], '1 day');
      -- {["AA"@2001-01-01, "BB"@2001-01-02, "AA"@2001-01-03], ["CC"@2001-01-05]}
      SELECT asText(tgeompointSeqSetGaps(ARRAY[tgeompoint 'Point(1 1)@2001-01-01',
        'Point(2 2)@2001-01-02', 'Point(3 2)@2001-01-03', 'Point(3 2)@2001-01-05'],
        '1 day', 1, 'step'));
      /* Interp=Step;{[POINT(1 1)@2001-01-01], [POINT(2 2)@2001-01-02, POINT(3 2)@2001-01-03],
         [POINT(3 2)@2001-01-05]} */

## Conversión de tipos

Un valor temporal se puede convertir en un tipo compatible usando la notación `CAST(ttype1 AS ttype2)` o `ttype1::ttype2`.

- Convertir un valor temporal a un cuadro delimitador

  `ttype::tstzspan`

  `tnumber::{span,tbox}`

  `tpoint::stbox`

      SELECT tint '[1@2001-01-01, 2@2001-01-03]'::tstzspan;
      -- [2001-01-01, 2001-01-03]
      SELECT ttext '(A@2001-01-01, B@2001-01-03, C@2001-01-05]'::tstzspan;
      -- (2001-01-01, 2001-01-05]
      SELECT tgeompoint '[Point(1 1)@2001-01-01, Point(3 3)@2001-01-03]'::tstzspan;
      -- [2001-01-01, 2001-01-03]

      SELECT tint '[1@2001-01-01, 2@2001-01-03]'::intspan;
      -- [1, 3)
      SELECT tfloat '(1@2001-01-01, 3@2001-01-03, 2@2001-01-05]'::floatspan;
      -- (1, 3]
      SELECT tfloat 'Interp=Step;(1@2001-01-01, 3@2001-01-03, 2@2001-01-05]'::floatspan;
      -- [1, 3]

      SELECT tint '[1@2001-01-01, 2@2001-01-03]'::tbox;
      -- TBOXINT XT((1,2),[2001-01-01,2001-01-03])
      SELECT tfloat '(1@2001-01-01, 3@2001-01-03, 2@2001-01-05]'::tbox;
      -- TBOXFLOAT XT((1,3),[2001-01-01,2001-01-05])
      SELECT tgeompoint '[Point(1 1)@2001-01-01, Point(3 3)@2001-01-03]'::stbox;
      -- STBOX XT(((1,1),(3,3)),[2001-01-01, 2001-01-03])
      SELECT tgeogpoint '[Point(1 1)@2001-01-01, Point(3 3)@2001-01-03]'::stbox;
      -- SRID=4326;GEODSTBOX XT(((1,1),(3,3)),[2001-01-01, 2001-01-03 00:00:00+01])
      SELECT tgeogpoint '[Point(1 1 1)@2001-01-01, Point(3 3 3)@2001-01-03]'::stbox;
      -- SRID=4326;GEODSTBOX ZT(((1,1,1),(3,3,3)),[2001-01-01, 2001-01-03])

- Convertir entre un entero temporal y un flotante temporal

  `tint::tfloat`

  `tfloat::tint`

      SELECT tint '[1@2001-01-01, 2@2001-01-03]'::tfloat;
      -- Interp=Step;[1@2001-01-01 00:00:00+00, 2@2001-01-03 00:00:00+00]
      SELECT tint '[1@2001-01-01, 2@2001-01-03, 3@2001-01-05]'::tfloat;
      -- Interp=Step;[1@2001-01-01, 2@2001-01-03, 3@2001-01-05]
      SELECT tfloat 'Interp=Step;[1.5@2001-01-01, 2.5@2001-01-03]'::tint;
      -- [1@2001-01-01 00:00:00+00, 2@2001-01-03 00:00:00+00]
      SELECT tfloat '[1.5@2001-01-01, 2.5@2001-01-03]'::tint;
      -- ERROR:  Cannot cast temporal float with linear interpolation to temporal integer

- Convertir entre un punto geométrico temporal y un punto geográfico temporal

  `tgeompoint::tgeogpoint`

  `tgeogpoint::tgeompoint`

      SELECT asText((tgeompoint '[Point(0 0)@2001-01-01, Point(0 1)@2001-01-02)')::tgeogpoint);
      -- {[POINT(0 0)@2001-01-01, POINT(0 1)@2001-01-02)}
      SELECT asText((tgeogpoint 'Point(0 0)@2001-01-01')::tgeompoint);
      -- {POINT(0 0)@2001-01-01}

Una forma común de almacenar puntos temporales en PostGIS es representarlos como geometrías de tipo `LINESTRING M` y utilizar la dimensión M para codificar marcas de tiempo como segundos desde 1970-01-01 00:00:00. Estas geometrías aumentadas con tiempo, llamadas trayectorias, se pueden validar con la función `ST_IsValidTrajectory` para verificar quel el valor M está creciendo de cada vértice al siguiente. Las trayectorias se pueden manipular con las funciones `ST_ClosestPointOfApproach`, `ST_DistanceCPA` y `ST_CPAWithin`. Los valores de puntos temporales se pueden convertir a/desde trayectorias de PostGIS.

- Convertir entre un punto temporal y una trayectoria PostGIS

  `tpoint::geo`

  `geo::tpoint`

      SELECT ST_AsText((tgeompoint 'Point(0 0)@2001-01-01')::geometry);
      -- POINT M (0 0 978307200)
      SELECT ST_AsText((tgeompoint '{Point(0 0)@2001-01-01, Point(1 1)@2001-01-02,
        Point(1 1)@2001-01-03}')::geometry);
      -- MULTIPOINT M (0 0 978307200,1 1 978393600,1 1 978480000)
      SELECT ST_AsText((tgeompoint '[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02)')::geometry);
      -- LINESTRING M (0 0 978307200,1 1 978393600)
      SELECT ST_AsText((tgeompoint '{[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02),
        [Point(1 1)@2001-01-03, Point(1 1)@2001-01-04),
        [Point(1 1)@2001-01-05, Point(0 0)@2001-01-06)}')::geometry);
      /* MULTILINESTRING M ((0 0 978307200,1 1 978393600),(1 1 978480000,1 1 978566400),
        (1 1 978652800,0 0 978739200)) */
      SELECT ST_AsText((tgeompoint '{[Point(0 0)@2001-01-01, Point(1 1)@2001-01-02),
        [Point(1 1)@2001-01-03],
        [Point(1 1)@2001-01-05, Point(0 0)@2001-01-06)}')::geometry);
      /* GEOMETRYCOLLECTION M (LINESTRING M (0 0 978307200,1 1 978393600),
         POINT M (1 1 978480000),LINESTRING M (1 1 978652800,0 0 978739200)) */

      SELECT asText(geometry 'LINESTRING M (0 0 978307200,0 1 978393600,
        1 1 978480000)'::tgeompoint);
      -- [POINT(0 0)@2001-01-01, POINT(0 1)@2001-01-02, POINT(1 1)@2001-01-03]
      SELECT asText(geometry 'GEOMETRYCOLLECTION M (LINESTRING M (0 0 978307200,1 1 978393600),
        POINT M (1 1 978480000),LINESTRING M (1 1 978652800,0 0 978739200))'::tgeompoint);
      /* {[POINT(0 0)@2001-01-01, POINT(1 1)@2001-01-02], [POINT(1 1)@2001-01-03],
         [POINT(1 1)@2001-01-05, POINT(0 0)@2001-01-06]} */

## Accesores

- Devuelve el tamaño de la memoria en bytes

  `memSize(ttype) → integer`

      SELECT memSize(tint '{1@2001-01-01, 2@2001-01-02, 3@2001-01-03}');
      -- 176

- Devuelve el subtipo temporal

  `tempSubtype(ttype) → {'Instant','Sequence','SequenceSet'}`

      SELECT tempSubtype(tint '[1@2001-01-01, 2@2001-01-02, 3@2001-01-03]');
      -- Sequence

- Devuelve la interpolación

  `interp(ttype) → {'Discrete','Step','Linear'}`

      SELECT interp(tfloat '{1@2001-01-01, 2@2001-01-02, 3@2001-01-03}');
      -- Discrete
      SELECT interp(tint '[1@2001-01-01, 2@2001-01-02, 3@2001-01-03]');
      -- Step
      SELECT interp(tfloat '[1@2001-01-01, 2@2001-01-02, 3@2001-01-03]');
      -- Linear
      SELECT interp(tfloat 'Interp=Step;[1@2001-01-01, 2@2001-01-02, 3@2001-01-03]');
      -- Step
      SELECT interp(tgeompoint 'Interp=Step;[Point(1 1)@2001-01-01,
        Point(2 2)@2001-01-02, Point(3 3)@2001-01-03]');
      -- Step

- Devuelve el valor o la marca de tiempo de un instantes

  `getValue(ttypeInst) → base`

  `getTimestamp(ttypeInst) → timestamptz`

      SELECT getValue(tint '1@2001-01-01');
      -- 1
      SELECT getTimestamp(tfloat '1@2001-01-01');
      -- 2001-01-01

- Devuelve los valores o el tiempo en el que se define el valor temporal

  `getValues(talpha) → {bool[],spanset,textset}`

  `getTime(ttype) → tstzspanset`

      SELECT getValues(tbool '[false@2001-01-01, true@2001-01-02, false@2001-01-03]');
      -- {f,t}
      SELECT getValues(tint '[1@2001-01-01, 3@2001-01-02, 1@2001-01-03]');
      -- {[1, 2), [3, 4)}
      SELECT getValues(tint '{[1@2001-01-01, 2@2001-01-02, 1@2001-01-03],
        [4@2001-01-04, 4@2001-01-05]}');
      -- {[1, 3), [4, 5)}
      SELECT getValues(tfloat '{1@2001-01-01, 2@2001-01-02, 1@2001-01-03}');
      -- {[1, 1], [2, 2]}
      SELECT getValues(tfloat 'Interp=Step;{[1@2001-01-01, 2@2001-01-02, 1@2001-01-03],
        [3@2001-01-04, 3@2001-01-05]}');
      -- {[1, 1], [2, 2], [3, 3]}
      SELECT getValues(tfloat '[1@2001-01-01, 2@2001-01-02, 1@2001-01-03]');
      -- {[1, 2]}
      SELECT getValues(tfloat '{[1@2001-01-01, 2@2001-01-02, 1@2001-01-03],
        [3@2001-01-04, 3@2001-01-05]}');
      -- {[1, 2], [3, 3]}

      SELECT getTime(ttext 'walking@2001-01-01');
      -- {[2001-01-01, 2001-01-01]}
      SELECT getTime(tfloat '{1@2001-01-01, 2@2001-01-02, 1@2001-01-03}');
      -- {[2001-01-01, 2001-01-01], [2001-01-02, 2001-01-02], [2001-01-03, 2001-01-03]}
      SELECT getTime(tint '[1@2001-01-01, 1@2001-01-15)');
      -- {[2001-01-01, 2001-01-15)}
      SELECT getTime(tfloat '{[1@2001-01-01, 1@2001-01-10), [12@2001-01-12, 12@2001-01-15]}');
      -- {[2001-01-01, 2001-01-10), [2001-01-12, 2001-01-15]}

- Devuelve el rango de valores o el rango de tiempo ignorando las posibles brechas

  `valueSpan(tnumber) → numspan`

  `timeSpan(ttype) → tstzspan`

      SELECT valueSpan(tint '{[1@2001-01-01, 1@2001-01-03), [4@2001-01-03, 6@2001-01-05]}');
      -- [1,7)
      SELECT valueSpan(tfloat '{1@2001-01-01, 2@2001-01-03, 3@2001-01-05}');
      -- [1,3])

      SELECT timeSpan(tint '{1@2001-01-01, 2@2001-01-03, 3@2001-01-05}');
      -- [2001-01-01, 2001-01-05]
      SELECT timeSpan(tfloat '{[1@2001-01-01, 1@2001-01-02), [2@2001-01-03, 3@2001-01-04)}');
      -- [2001-01-01, 2001-01-04)

- Devuelve los valores del número o punto temporal como un conjunto

  `valueSet(tnumber,tpoint) → {numset,geoset}`

      SELECT valueSet(tint '[1@2001-01-01, 2@2001-01-03]');
      -- {1, 2}
      SELECT valueSet(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 4@2001-01-05)}');
      -- {1, 2, 3, 4}
      SELECT asText(valueSet(tgeompoint '{[Point(0 0)@2001-01-01, Point(0 1)@2001-01-02),
        [Point(0 1)@2001-01-03, Point(1 1)@2001-01-04)}'));
      -- {"POINT(0 0)", "POINT(1 1)", "POINT(0 1)"}

- Devuelve el valor inicial, final, o enésimo

  `startValue(ttype) → base`

  `endValue(ttype) → base`

  `valueN(ttype,int) → base`

  La función no tiene en cuenta si los límites son inclusivos o no.

      SELECT startValue(tfloat '(1@2001-01-01, 2@2001-01-03)');
      -- 1
      SELECT endValue(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}');
      -- 5
      SELECT valueN(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}', 3);
      -- 3

- Devuelve el valor mínimo o máximo

  `minValue(torder) → base`

  `maxValue(torder) → base`

  La función no tiene en cuenta si los límites son inclusivos o no.

      SELECT minValue(tfloat '{1@2001-01-01, 2@2001-01-03, 3@2001-01-05}');
      -- 1
      SELECT maxValue(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}');
      -- 5

- Devuelve el instante con el valor mínimo o máximo

  `minInstant(torder) → base`

  `maxInstant(torder) → base`

  La función no tiene en cuenta si los límites son inclusivos o no. Si varios instantes tienen el valor mínimo, se devuelve el primero.

      SELECT minInstant(tfloat '{1@2001-01-01, 2@2001-01-03, 3@2001-01-05}');
      -- 1@2001-01-01
      SELECT maxInstant(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}');
      -- 5@2001-01-05

- Devuelve el valor en una marca de tiempo

  `valueAtTimestamp(ttype,timestamptz) → base`

      SELECT valueAtTimestamp(tfloat '[1@2001-01-01, 4@2001-01-04)', '2001-01-02');
      -- 2

- Devuelve el intervalo de tiempo

  `duration(ttype,boundspan=false) → interval`

  Se puede poner en verdadero un parámetro adicional para calcular la duración del período limitador, ignorando así los posibles intervalos de tiempo

      SELECT duration(tfloat '{1@2001-01-01, 2@2001-01-03, 2@2001-01-05}');
      -- 00:00:00
      SELECT duration(tfloat '{1@2001-01-01, 2@2001-01-03, 2@2001-01-05}', true);
      -- 4 days
      SELECT duration(tfloat '[1@2001-01-01, 2@2001-01-03, 2@2001-01-05)');
      -- 4 days
      SELECT duration(tfloat '{[1@2001-01-01, 2@2001-01-03), [2@2001-01-04, 2@2001-01-05)}');
      -- 3 days
      SELECT duration(tfloat '{[1@2001-01-01, 2@2001-01-03), [2@2001-01-04, 2@2001-01-05)}',
        true);
      -- 4 days

- ¿Es el instante inicial/final inclusivo?

  `lowerInc(ttype) → bool`

  `upperInc(ttype) → bool`

      SELECT lowerInc(tint '[1@2001-01-01, 2@2001-01-02)');
      -- true
      SELECT upperInc(tfloat '{[1@2001-01-01, 2@2001-01-02), (2@2001-01-02, 3@2001-01-03)}');
      -- false

- Devuelve el número de instantes diferentes

  `numInstants(ttype) → integer`

      SELECT numInstants(tfloat '{[1@2001-01-01, 2@2001-01-02), (2@2001-01-02, 3@2001-01-03)}');
      -- 3

- Devuelve el instante inicial, final o enésimo

  `startInstant(ttype) → ttypeInst`

  `endInstant(ttype) → ttypeInst`

  `instantN(ttype,integer) → ttypeInst`

  La función no tiene en cuenta si los límites son inclusivos o no.

      SELECT startInstant(tfloat '{[1@2001-01-01, 2@2001-01-02),
        (2@2001-01-02, 3@2001-01-03)}');
      -- 1@2001-01-01
      SELECT endInstant(tfloat '{[1@2001-01-01, 2@2001-01-02), (2@2001-01-02, 3@2001-01-03)}');
      -- 3@2001-01-03
      SELECT instantN(tfloat '{[1@2001-01-01, 2@2001-01-02), (2@2001-01-02, 3@2001-01-03)}', 3);
      -- 3@2001-01-03

- Devuelve los instantes diferentes

  `instants(ttype) → ttypeInst[]`

      SELECT instants(tfloat '{[1@2001-01-01, 2@2001-01-02), (2@2001-01-02, 3@2001-01-03)}');
      -- {"1@2001-01-01","2@2001-01-02","3@2001-01-03"}

- Devuelve el número de marcas de tiempo diferentes

  `numTimestamps(ttype) → integer`

      SELECT numTimestamps(tfloat '{[1@2001-01-01, 2@2001-01-03),
        [3@2001-01-03, 5@2001-01-05)}');
      -- 3

- Devuelve la marca de tiempo inicial, final o enésima

  `startTimestamp(ttype) → timestamptz`

  `endTimestamp(ttype) → timestamptz`

  `timestampN(ttype,integer) → timestamptz`

  La función no tiene en cuenta si los límites son inclusivos o no.

      SELECT startTimestamp(tfloat '[1@2001-01-01, 2@2001-01-03)');
      -- 2001-01-01
      SELECT endTimestamp(tfloat '{[1@2001-01-01, 2@2001-01-03),
        [3@2001-01-03, 5@2001-01-05)}');
      -- 2001-01-05
      SELECT timestampN(tfloat '{[1@2001-01-01, 2@2001-01-03),
        [3@2001-01-03, 5@2001-01-05)}', 3);
      -- 2001-01-05

- Devuelve las marcas de tiempo diferentes

  `timestamps(ttype) → timestamptz[]`

      SELECT timestamps(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}');
      -- {"2001-01-01", "2001-01-03", "2001-01-05"}

- Devuelve el número de secuencias

  `numSequences({ttypeContSeq,ttypeSeqSet}) → integer`

      SELECT numSequences(tfloat '{[1@2001-01-01, 2@2001-01-03),
        [3@2001-01-03, 5@2001-01-05)}');
      -- 2

- Devuelve la secuencia inicial, final, o enésima

  `startSequence({ttypeContSeq,ttypeSeqSet}) → ttypeContSeq`

  `endSequence({ttypeContSeq,ttypeSeqSet}) → ttypeContSeq`

  `sequenceN({ttypeContSeq,ttypeSeqSet},integer) → ttypeContSeq`

      SELECT startSequence(tfloat '{[1@2001-01-01, 2@2001-01-03),
        [3@2001-01-03, 5@2001-01-05)}');
      -- [1@2001-01-01, 2@2001-01-03)
      SELECT endSequence(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}');
      -- [3@2001-01-03, 5@2001-01-05)
      SELECT sequenceN(tfloat '{[1@2001-01-01, 2@2001-01-03),
        [3@2001-01-03, 5@2001-01-05)}', 2);
      -- [3@2001-01-03, 5@2001-01-05)

- Devuelve las secuencias

  `sequences({ttypeContSeq,ttypeSeqSet}) → ttypeContSeq[]`

      SELECT sequences(tfloat '{[1@2001-01-01, 2@2001-01-03), [3@2001-01-03, 5@2001-01-05)}');
      -- {"[1@2001-01-01, 2@2001-01-03)", "[3@2001-01-03, 5@2001-01-05)"}

- Devuelve los segmentos

  `segments({ttypeContSeq,ttypeSeqSet}) → ttypeContSeq[]`

      SELECT segments(tint '{[1@2001-01-01, 3@2001-01-02, 2@2001-01-03],
        (3@2001-01-03, 5@2001-01-05]}');
      /* {"[1@2001-01-01, 1@2001-01-02)","[3@2001-01-02, 3@2001-01-03)","[2@2001-01-03]",
        "(3@2001-01-03, 3@2001-01-05)","[5@2001-01-05]"} */
      SELECT segments(tfloat '{[1@2001-01-01, 3@2001-01-02, 2@2001-01-03],
        (3@2001-01-03, 5@2001-01-05]}');
      /* {"[1@2001-01-01, 3@2001-01-02)","[3@2001-01-02, 2@2001-01-03]",
         "(3@2001-01-03, 5@2001-01-05]"} */

- Devuelve el área bajo la curva

  `integral(tnumber) → float`

      SELECT  integral(tint '[1@2001-01-01,2@2001-01-02]') / (24 * 3600 * 1e6);
      -- 1
      SELECT integral(tfloat '[1@2001-01-01,2@2001-01-02]') / (24 * 3600 * 1e6);
      -- 1.5

- Devuelve el promedio ponderado en el tiempo

  `twAvg(tnumber) → float`

      SELECT twAvg(tfloat '{[1@2001-01-01, 2@2001-01-03), [2@2001-01-04, 2@2001-01-06)}');
      -- 1.75

## Transformaciones

Un valor temporal se puede transformar en otro subtipo. Se genera un error si los subtipos son incompatibles.

- Transformar un tipo temporal a otro subtipo

  `ttypeInst(ttype) → ttypeInst`

  `ttypeSeq(ttype) → ttypeSeq`

  `ttypeSeqSet(ttype) → ttypeSeqSet`

      SELECT tboolInst(tbool '{[true@2001-01-01]}');
      -- t@2001-01-01
      SELECT tboolInst(tbool '{[true@2001-01-01, true@2001-01-02]}');
      -- ERROR: Cannot transform input value to a temporal instant
      SELECT tintSeq(tint '1@2001-01-01');
      -- [1@2001-01-01]
      SELECT tfloatSeqSet(tfloat '2.5@2001-01-01');
      -- {[2.5@2001-01-01]}
      SELECT tfloatSeqSet(tfloat '{2.5@2001-01-01, 1.5@2001-01-02, 3.5@2001-01-03}');
      -- {[2.5@2001-01-01],[1.5@2001-01-02],[3.5@2001-01-03]}

- Transformar un valor temporal a otra interpolación

  `setInterp(ttype, interp) → ttype`

      SELECT setInterp(tbool 'true@2001-01-01','discrete');
      -- {t@2001-01-01}
      SELECT setInterp(tfloat '{[1@2001-01-01], [2@2001-01-02], [1@2001-01-03]}', 'discrete');
      -- {1@2001-01-01, 2@2001-01-02, 1@2001-01-03}
      SELECT setInterp(tfloat 'Interp=Step;[1@2001-01-01, 2@2001-01-02,
        1@2001-01-03, 2@2001-01-04]', 'linear');
      /* {[1@2001-01-01, 1@2001-01-02), [2@2001-01-02, 2@2001-01-03),
         [1@2001-01-03, 1@2001-01-04), [2@2001-01-04]}" */
      SELECT asText(setInterp(tgeompoint 'Interp=Step;{[Point(1 1)@2001-01-01,
        Point(2 2)@2001-01-02], [Point(3 3)@2001-01-05, Point(4 4)@2001-01-06]}', 'linear'));
      /* {[POINT(1 1)@2001-01-01, POINT(1 1)@2001-01-02), [POINT(2 2)@2001-01-02],
         [POINT(3 3)@2001-01-05, POINT(3 3)@2001-01-06), [POINT(4 4)@2001-01-06]} */

- Desplazar el rango de valores or el intervalo de tiempo de un valor temporal con un valor or intervalo

  `shiftValue(tnumber,base) → tnumber`

  `shiftTime(ttype,interval) → ttype`

      SELECT shiftValue(tint '{1@2001-01-01, 2@2001-01-03, 1@2001-01-05}', 1);
      -- {2@2001-01-02, 3@2001-01-04, 2@2001-01-06}
      SELECT shiftValue(tfloat '{[1@2001-01-01,2@2001-01-02],[3@2001-01-03,4@2001-01-04]}', -1);
      --  {[0@2001-01-01, 1@2001-01-02], [2@2001-01-03, 3@2001-01-04]}

      SELECT shiftTime(tint '{1@2001-01-01, 2@2001-01-03, 1@2001-01-05}', '1 day');
      -- {1@2001-01-02, 2@2001-01-04, 1@2001-01-06}
      SELECT shiftTime(tfloat '[1@2001-01-01, 2@2001-01-03]', '1 day');
      -- [1@2001-01-02, 2@2001-01-04]
      SELECT asText(shiftTime(tgeompoint '{[Point(1 1)@2001-01-01, Point(2 2)@2001-01-03],
        [Point(2 2)@2001-01-04, Point(1 1)@2001-01-05]}', '1 day'));
      /* {[POINT(1 1)@2001-01-02, POINT(2 2)@2001-01-04],
         [POINT(2 2)@2001-01-05, POINT(1 1)@2001-01-06]} */

- Escalear el rango de valores o el intervalo de tiempo de un valor temporal a un valor o intervalo

  `scaleValue(tnumber,width) → tnumber`

  `scaleTime(ttype,interval) → ttype`

  Si el rango de valores o el intervalo de tiempo del valor temporal es cero (por ejemplo, para un instante temporal), el resultado es el valor temporal. El ancho o intervalo dado debe ser estrictamente mayor que cero.

      SELECT scaleValue(tint '1@2001-01-01', 1);
      -- 1@2001-01-01
      SELECT scaleValue(tfloat '{[1@2001-01-01,2@2001-01-02], [3@2001-01-03,4@2001-01-04]}', 6);
      -- {[1@2001-01-01, 3@2001-01-03], [5@2001-01-05, 7@2001-01-07]}
      SELECT scaleValue(tint '1@2001-01-01', -1);
      -- ERROR:   The value must be strictly positive: -1

      SELECT scaleTime(tint '1@2001-01-01', '1 day');
      -- 1@2001-01-01
      SELECT scaleTime(tint '{1@2001-01-01, 2@2001-01-03, 1@2001-01-05}', '1 day');
      -- {1@2001-01-01 00:00:00+01, 2@2001-01-01 12:00:00+01, 1@2001-01-02 00:00:00+01}
      SELECT scaleTime(tfloat '[1@2001-01-01, 2@2001-01-03]', '1 day');
      -- [1@2001-01-01, 2@2001-01-02]
      SELECT asText(scaleTime(tgeompoint '{[Point(1 1)@2001-01-01, Point(2 2)@2001-01-02,
        Point(1 1)@2001-01-03], [Point(2 2)@2001-01-04, Point(1 1)@2001-01-05]}', '1 day'));
      /* {[POINT(1 1)@2001-01-01 00:00:00+01, POINT(2 2)@2001-01-01 06:00:00+01,
         POINT(1 1)@2001-01-01 12:00:00+01], [POINT(2 2) @2001-01-01 18:00:00+01,
         POINT(1 1)@2001-01-02 00:00:00+01]} */
      SELECT scaleTime(tint '1@2001-01-01', '-1 day');
      -- ERROR:  The interval must be positive: -1 days

- Desplazar y escalear el rango de valores o intervalo de tiempo de un valor temporal a los dos valores o intervalos

  `shiftScaleValue(tnumber,base,base) → tnumber`

  `shiftScaleTime(ttype,interval,interval) → ttype`

  Estas funciones combinan las funciones `shiftValue` y `scaleValue` o `shiftTime` y `scaleTime`.

      SELECT shiftScaleValue(tint '1@2001-01-01', 1, 1);
      -- 2@2001-01-01
      SELECT shiftScaleValue(tfloat '{[1@2001-01-01,2@2001-01-02],[3@2001-01-03,4@2001-01-04]}',
        -1, 6);
      --  {[0@2001-01-01, 2@2001-01-02], [4@2001-01-03, 6@2001-01-04]}

      SELECT shiftScaleTime(tint '1@2001-01-01', '1 day', '1 day');
      -- 1@2001-01-02
      SELECT shiftScaleTime(tint '{1@2001-01-01, 2@2001-01-03, 1@2001-01-05}', '1 day','1 day');
      -- {1@2001-01-02 00:00:00+01, 2@2001-01-02 12:00:00+01, 1@2001-01-03 00:00:00+01}
      SELECT shiftScaleTime(tfloat '[1@2001-01-01, 2@2001-01-03]', '1 day', '1 day');
      -- [1@2001-01-02, 2@2001-01-03]
      SELECT asText(shiftScaleTime(tgeompoint '{[Point(1 1)@2001-01-01, Point(2 2)@2001-01-02,
        Point(1 1)@2001-01-03], [Point(2 2)@2001-01-04, Point(1 1)@2001-01-05]}',
        '1 day', '1 day'));
      /* {[POINT(1 1)@2001-01-02 00:00:00+01, POINT(2 2)@2001-01-02 06:00:00+01,
         POINT(1 1)@2001-01-02 12:00:00+01], [POINT(2 2) @2001-01-02 18:00:00+01,
         POINT(1 1)@2001-01-03 00:00:00+01]} */

- Extraer de un sequencia o un conjunto de secuencias temporales con interpolación linear los segmentos cuya distancia es menor o igual que el argumento dados y/o cuya duración es mayor o igual que el argumento dado &Z_support; &geography_support;

  `stops({ttypeContSeq,ttypeSeqSet},maxDist=0.0,minDuration='0 minutes') → ttypeSeqSet`

  Para los tipos espaciales, el tamaño del área se calcula como la diagonal del rectángulo mínimamente girado de los puntos de la subsecuencia. Para los tipos escalares, el tamaño se calcula como el ancho del intervalo circundante. Si no se proporciona `maxDist`, se supone que es 0.0 y, por lo tanto, la función extrae los segmentos constantes del valor temporal dado. Para puntos temporales, la distancia se calcula en las unidades del sistema de coordenadas. Nótese que aunque la función acepta geometrías 3D, el cálculo siempre se realiza en 2D.

      SELECT stops(tfloat '[1@2001-01-01, 1@2001-01-02, 2@2001-01-03]');
      -- {[1@2001-01-01, 1@2001-01-02)}
      SELECT stops(tfloat '[1@2001-01-01, 1@2001-01-02, 2@2001-01-03]', 0.0, '2 days');
      -- NULL
      SELECT asText(stops(tgeompoint '[Point(1 1)@2001-01-01, Point(1 1)@2001-01-02,
        Point(2 2)@2001-01-03, Point(2 2)@2001-01-04]'));
      /* {[POINT(1 1)@2001-01-01, POINT(1 1)@2001-01-02), [POINT(2 2)@2001-01-03,
         POINT(2 2)@2001-01-04]} */
      SELECT asText(stops(tgeompoint '[Point(1 1 1)@2001-01-01, Point(1 1 1)@2001-01-02,
        Point(2 2 2)@2001-01-03, Point(2 2 2)@2001-01-04]', 1.75));
      /* {[POINT Z (1 1 1)@2001-01-01, POINT Z (1 1 1)@2001-01-02, POINT Z (2 2 2)@2001-01-03,
         POINT Z (2 2 2)@2001-01-04]} */

- Transformar un valor temporal no lineal en un conjunto de filas, cada una es una pareja compuesta de un valor de base y un conjunto de períodos durante el cual el valor temporal tiene el valor de base &SRF;

  `unnest(ttype) → {(value,time)}`

      SELECT (un).value, (un).time
      FROM (SELECT unnest(tfloat '{1@2001-01-01, 2@2001-01-02, 1@2001-01-03}') AS un) t;
      -- 1 | {[2001-01-01, 2001-01-01], [2001-01-03, 2001-01-03]}
      -- 2 | {[2001-01-02, 2001-01-02]}
      SELECT (un).value, (un).time
      FROM (SELECT unnest(tint '[1@2001-01-01, 2@2001-01-02, 1@2001-01-03]') AS un) t;
      -- 1 | {[2001-01-01, 2001-01-02), [2001-01-03, 2001-01-03]}
      -- 2 | {[2001-01-02, 2001-01-03)}
      SELECT (un).value, (un).time
      FROM (SELECT unnest(tfloat '[1@2001-01-01, 2@2001-01-02, 1@2001-01-03]') AS un) t;
      -- ERROR:  The temporal value cannot have linear interpolation
      SELECT ST_AsText((un).value), (un).time
      FROM (SELECT unnest(tgeompoint 'Interp=Step;[Point(1 1)@2001-01-01,
        Point(2 2)@2001-01-02, Point(1 1)@2001-01-03]') AS un) t;
      --  POINT(1 1) | {[2001-01-01, 2001-01-02), [2001-01-03, 2001-01-03]}
      --  POINT(2 2) | {[2001-01-02, 2001-01-03)}