Datový typ date!

1. Úvodem

Hodnota date! představuje datum, vycházející z Gregoriánského kalendáře. Datum může také uvádět čas a časové pásmo. Čas v datumu je vyjádřen ve 24 hodinovém formátu (včetně volitelné informace o časovém pásmu). Datumy Redu mají také extenzivní podporu pro vstupní formáty ISO 8601.

Note
  • date! používá proleptický Gregoriánský kalendář, s rozšířenou platností před rok svého vzniku, t.j. rok 1582. Je třeba se mít na pozoru při používání tohoto datového typu pro vyjadřování před gregoriánských datumů.

  • Podporované jsou datumy od 1/Jan/-16384 do 31/Dec/16383, zahrnujíce rozšiřující matematické operace (s přechody u matematických operací, způsobujících překročení mezí). Pro vstup je tento rozsah z praktických důvodů omezen na úsek od 1/Jan/-9999 do 31/Dec/9999.

2. Vytvoření

Hodnoty typu date! lze vytvořit s použitím literálové syntaxe nebo s použitím konstruktoru make nebo konverzí to.

2.1. Literálová skladba

Jsou podporovány mnohé literálové formáty, včetně formátů Rebolu a většiny datumových standardů ISO.

<date>/<time>
<date>/<time><zone>
<date>T<time>
<date>T<time>Z
<date>T<time><zone>

<date> formats:
    <yyyy><sep><mmm><sep><dd>
    <dd><sep><mmm><sep><yyyy>
    <dd><sep><mmm><sep><yy>

Additional <date> formats when followed by T:
    <yyyy><mm><dd>
    <yyyy>-W<ww>
    <yyyy>-W<ww>-<d>
    <yyyy>-<ddd>

<mmm> formats (month):
    <m>
    <mon>
    <month>

<time> formats:
    <hour>:<min>:<sec>
    <hour>:<min>:<sec><zone>
    <hhmmss>
    <hhmmss><zone>
    <hhmmss>.<dec>
    <hhmmss>.<dec><zone>
    <hhmm>
    <hhmm><zone>

<zone> formats (timezone):
    <sign><hour>
    <sign><hour>:<min15>
    <sign><hhmm>

<sec> formats (seconds):
    <ss>
    <ss>.<dec>

<sep>    : `-` nebo `/`
<yyyy>   : 3 nebo 4 číslice, udávající rok (4 číslice pro datumy ISO)
<yy>     : 2 poslední číslice roku 2000 plus
<m>      : 1 nebo 2 číslice, udávající měsíc
<mm>     : 2 číslice, udávající měsíc
<mon>	 : 3 začáteční písmena názvu měsíce
<month>  : celý název měsíce
<d>      : číslo, udávající den v týdnu (1 až 7)
<dd>     : 1 nebo 2 číslice, udávající den měsíce
<ddd>    : 3 číslice, udávající den roku
<ww>     : 2 číslice, udávající týden roku
<time>   : hodnota typu time!
<hour>   : 1 nebo 2 číslice, uvádějící hodiny
<min>    : 1 nebo 2 číslice, uvádějící minuty
<ss>     : 1 nebo 2 číslice, uvádějící vteřiny
<dec>    : desetinné číslo pro vteřiny
<sign>   : znak `+` nebo `-` (nelze vynechat)
<min15>  : totéž jako u <min> ale zaokrouhleno na násobek 15.
<hhmm>   : 4 číslice pro hodiny a minuty (bez separátoru)
<hhmmss> : 6 číslic pro hodiny, minuty a vteřiny (bez separátorů)

Jsou akceptovány mnohé vstupní formáty pro literálové datumy. Hodnoty mimo rozsah (překračující určená digitální čísla nebo mimo normu pole) generují chybu syntaxe. Při opětovné serializaci (např. pro zobrazení) se používají pouze následující kanonické formáty:

<dd>-<mon>-<yyyy>
<dd>-<mon>-<yyyy>/<hour>:<min>:<sec>
<dd>-<mon>-<yyyy>/<hour>:<min>:<sec><sign><hour>:<min15>
<sec><sign><hour>:<min15>

Nejsou-li pole pro time a/nebo zónu zadána, jsou vynechána. U negativních datumových hodnot se pro lepší čitelnost používá separátor / místo -.

Note
  • Názvy měsíců jsou anglické a jsou 'case-insensitive'.

  • Je-li rok určen pouze dvouciferným číslem (yy): pak je-li yy < 50, je interpretován jako 20yy, jinak je interpretován jako 19yy.

Příklady platných datumových vstupů:

1999-10-5
1999/10/5
5-10-1999
5/10/1999
5-October-1999
1999-9-11
11-9-1999
5/sep/2012
5-SEPTEMBER-2012

02/03/04
02/03/71

5/9/2012/6:0
5/9/2012/6:00
5/9/2012/6:00+8
5/9/2012/6:0+0430
4/Apr/2000/6:00+8:00
1999-10-2/2:00-4:30
1/1/1990/12:20:25-6

2017-07-07T08:22:23+00:00
2017-07-07T08:22:23Z
20170707T082223Z
20170707T0822Z
20170707T082223+0530

2017-W01
2017-W23-5
2017-W23-5T10:50Z
2017-001
2017-153T10:50:00-4:00

2.2. Vytvoření při runtime

make date! [<day> <month> <year>]
make date! [<year> <month> <day>]
make date! [<day> <month> <year> <time>]
make date! [<day> <month> <year> <time> <zone>]
make date! [<day> <month> <year> <hour> <minute> <second>]
make date! [<day> <month> <year> <hour> <minute> <second> <zone>]

<year>   : integer! value
<month>  : integer! value
<day>    : integer! value
<time>   : time! value
<zone>   : integer!, time! or pair! value
<hour>   : integer! value
<minute> : integer! value
<second> : integer! value
Note
  • Argumenty mimo stanovený rozsah vyvolají chybu. Pro normalizovaný výsledek se doporučuje použít akci to místo make.

  • Pole year a day jsou zaměnitelná, avšak jen pro nízké hodnoty roků. Rok může být použit na první pozici pouze tehdy, je-li jeho hodnota >= 100 a menší než hodnota třetího pole. Nejsou-li tyto podmínky splněny, je třetí pole vymezeno pro rok. Negativní roky mají být vždy určeny ve třetí pozici.

Příklady

make date! [1978 2 3]
== 3-Feb-1978

make date! [1978 2 3 5:0:0 8]
== 3-Feb-1978/5:00:00+08:00

make date! [1978 2 3 5:0:0]
== 3-Feb-1978/5:00:00

make date! [1978 2 3 5 20 30]
== 3-Feb-1978/5:20:30

make date! [1978 2 3 5 20 30 -4]
== 3-Feb-1978/5:20:30-4:00


make date! [100 12 31]
== 31-Dec-0100

;; 32 není platný den:
make date! [100 12 32]
*** Script Error: cannot MAKE/TO date! from: [100 12 32]
*** Where: make

;; první pole je < 100, není tedy považováno za vyjádření roku:
make date! [99 12 31]
*** Script Error: cannot MAKE/TO date! from: [99 12 31]
*** Where: make

3. Přístup ve formátu cesty

Přístup ve formátu path! (path accessor) poskytuje vhodný způsob získání či zadání všech polí hodoty date!.

3.1. /date

Syntaxe

<date>/date
<date>/date: <date2>

<date>  : slovo nebo cesta (path expression) odkazující na hodnotu date!
<date2> : hodnota typu date!

Popis

Vrací nebo zadá datumové pole datumu (s vyloučením času a pásma). Datumy se vrací jako hodnoty typu date!.

Příklady

d:  now
== 10-Jul-2017/22:46:22-06:00
d/date
== 10-Jul-2017

d/date: 15/09/2017
== 15-Sep-2017/22:46:22-06:00

3.2. /year

Syntaxe

<date>/year
<date>/year: <year>

<date> : slovo nebo cesta (path expression) odkazující na hodnotu date!
<year> : hodnota typu integer!

Popis

Vrací nebo zadá pole s rokem datumu. Roky se vrací jako celá čísla. Argument mimo stanovený rozsah je vrácen jako normalizované datum - s přechodem na počátek rozsahu.

Příklady

d:  now
== 10-Jul-2017/22:46:22-06:00
d/year: 10000
== 10000
d
== 10-Jul-10000/22:46:22-06:00
d/year: 32768
== 32768
d
== 10/Jul/-0000/22:46:22-06:00     ; hle přechod při přetečení

3.3. /month

Syntaxe

<date>/month
<date>/month: <month>

<date>  : slovo nebo cesta odkazující na hodnotu date!
<month> : hodnota typu integer!

Popis

Vrací nebo zadá pole pro měsíc datumu. Měsíce se vrací jako celá čísla. Argument mimo stanovený rozsah je vrácen jako normalizované datum - s přechodem na počátek rozsahu příštího roku.

Příklady

d: now
== 10-Jul-2017/22:48:31-06:00
d/month: 12
== 12
d
== 10-Dec-2017/22:48:31-06:00
d/month: 13
== 13
d
== 10-Jan-2018/22:48:31-06:00   ; hle přechod při přetečení
d/month
== 1                            ; normalizované vyjádření měsíce

3.4. /day

Syntaxe

<date>/day
<date>/day: <day>

<date> : slovo nebo cesta odkazující na hodnotu date!
<day>  : hodnota typu integer!

Popis

Vrací nebo zadá pole pro den datumu. Dny se vrací jako celá čísla. Argument mimo stanovený rozsah je vrácen jako normalizované datum - s přechodem na počátek rozsahu příštího měsíce.

Příklady

 d: 1-jan-2017
== 1-Jan-2017
d/day: 32        ; přetečení posune na počátek příštího měsíce
== 32
d
== 1-Feb-2017
d/day: 0         ; nula vrací na konec předchozího měsíce
== 0
d
== 31-Jan-2017

3.5. /time

Syntaxe

<date>/time
<date>/time: <time>

<date> : slovo nebo cesta odkazující na hodnotu date!
<time> : hodnota typu time! nebo none!

Popis

Vrací nebo zadá časové pole datumu. Čas se vrací jako hodnota typu time! neb none!, není-li čas zadán, případně byl-li resetován (viz níže). Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Je-li čas zadán hodnotou none!, jsou pole pro čas a pásmo nastaveny na nulu a nejsou dále zobrazovány.

Příklady

d: now
== 10-Jul-2017/23:18:54-06:00
d/time: 1:2:3
== 1:02:03
d
== 10-Jul-2017/1:02:03-06:00
d/time: none
== 10-Jul-2017

3.6. /hour

Syntaxe

<date>/hour
<date>/hour: <hour>

<date> : slovo nebo cesta odkazující na hodnotu date!
<hour> : hodnota typu integer! value

Popis

Vrací nebo zadá hodinové pole datumu. Hodiny se vrací jako celá čísla mezi 0 a 23. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Příklady

d: now
== 10-Jul-2017/23:19:40-06:00
d/hour: 0
== 0
d
== 10-Jul-2017/0:19:40-06:00
d/hour: 24                      ; způsobí posun o 24 hodin
== 24
d
== 11-Jul-2017/0:19:40-06:00

3.7. /minute

Syntaxe

<date>/minute
<date>/minute: <minute>

<date>   : slovo nebo cesta odkazující na hodnotu date!
<minute> : hodnota typu integer!

Popis

Vrací nebo zadá minutové pole datumu. Minuty se vrací jako celá čísla mezi 0 a 59. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Příklady

== 10-Jul-2017/23:20:25-06:00
d/minute: 0
== 0
d
== 10-Jul-2017/23:00:25-06:00
d/minute: 60
== 60
d
== 11-Jul-2017/0:00:25-06:00

3.8. /second

Syntaxe

<date>/second
<date>/second: <second>

<date>   : slovo nebo cesta odkazující na hodnotu date!
<second> : hodnota typu integer! nebo float!

Popis

Vrací nebo zadá vteřinové pole datumu. Vteřiny se vrací jako čísla typu ingeger! nebo float! o velikosti mezi 0 a 59. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Příklady

d: now
== 10-Jul-2017/23:21:15-06:00
d/second: 0
== 0
d
== 10-Jul-2017/23:21:00-06:00
d/second: -1
== -1
d
== 10-Jul-2017/23:20:59-06:00
d/second: 60
== 60
d
== 10-Jul-2017/23:21:00-06:00

3.9. /zone

Syntaxe

<date>/zone
<date>/zone: <zone>

<date> : slovo nebo cesta odkazující na hodnotu date!
<zone> : hodnota typu time! nebo integer!

Popis

Vrací nebo zadá pole časového pásme datumu. Časové zóny se vrací jako hodnoty typu time! o velikosti mezi -16:00 a +15:00. Nastavení časového pásma upřesněním /zone modifikuje pouze toto pole, čas se nemění. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Je-li časové pásmo zadáno celým číslem, vztahuje se na hodiny, zatímco minuty jsou nastaveny na 0.

Minuty časového pásma se uvádějí v násobcích čísla 15; jiné hodnoty se zaokrouhlují na nejbližší násobek patnácti dolů.

Příklady

d: 1/3/2017/5:30:0
d/zone: 8
== 1-Mar-2017/5:30:00+08:00

d/zone: -4:00
== 1-Mar-2017/5:30:00-04:00

3.10. /timezone

Syntaxe

<date>/timezone
<date>/timezone: <timezone>

<date>     : slovo nebo cesta odkazující na hodnotu date!
<timezone> : hodnota typu integer! nebo time!

Popis

Vrací nebo zadá časové pole datumu. Časová pásma se vrací jako hodnoty typu time! o velikostech mezi -16:00 a +15:00. Nastavení časového pásma upřesněním /timezone způsobí změnu jak času tak pásma, zachovávajíc nový ekvivalent starého času v nové zóně. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Je-li časové pásmo zadáno celým číslem, vztahuje se na hodiny, zatímco minuty jsou nastaveny na 0.

Minuty časového pásma se uvádějí v násobcích čísla 15; jiné hodnoty se zaokrouhlují na nejbližší násobek patnácti dolů.

Příklady

d: 1/3/2017/5:30:0
d/timezone: 8
== 1-Mar-2017/13:30:00+08:00

d/timezone: -4:00
== 1-Mar-2017/1:30:00-04:00
Note
  • Nastavení pole /timezone na hodnotu 0 nastaví čas ve standardu UTC (Coordinated Universal Time).

3.11. /yearday

Syntaxe

<date>/yearday
<date>/yearday: <day>

<date>    : slovo nebo cesta odkazující na hodnotu date!
<yearday> : hodnota typu integer!

Popis

Vrací pořadové číslo dne v roce, počínaje od 1. lednem. Zadání pořadového čísla roku způsobí příslušné přepočítání datumové hodnoty. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Note
  • Kvůli kompatibilitě s Rebolem je možné místo /yearday použít upřesnění /julian.

Příkklady

d: 1-jan-2017
== 1-Jan-2017
d/yearday
== 1
d: 31-dec-2017
== 31-Dec-2017
d/yearday
== 365
d: 31-dec-2020
== 31-Dec-2020
d/yearday
== 366                  ; přestupný rok

d: 31-dec-2017
== 31-Dec-2017
d/yearday: 420
== 420
d
== 24-Feb-2018

3.12. /weekday

Syntaxe

<date>/weekday
<date>/weekday: <day>

<date>    : slovo nebo cesta odkazující na hodnotu date!
<weekday> : hodnota typu integer!

Popis

Vrací pořadové číslo dne v týdnu, počínaje pondělím, konče nedělí. Zadání pořadového čísla dne v týdnu způsobí příslušné přepočítání datumové hodnoty. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Příklady

d: now
== 10-Jul-2017/23:25:35-06:00
d/weekday
== 1
d/weekday: 2
== 2
d
== 11-Jul-2017/23:25:35-06:00
d/weekday: 7
== 7
d
== 16-Jul-2017/23:25:35-06:00
d/weekday: 8
== 8
d
== 17-Jul-2017/23:25:35-06:00

3.13. /week

Syntaxe

<date>/week
<date>/week: <day>

<date> : slovo nebo cesta odkazující na hodnotu date!
<week> : hodnota typu integer!

Popis

Vrací číslo týdne nahodile (casual) definovaného (týden začíná v neděli, první týden začíná prvního ledna) od 1 do 53. Zadání pořadového čísla týdne způsobí příslušné přepočítání datumové hodnoty. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Note
  • Nahodilá (casual) definice týdne umožňuje započítání neúplných týdnů na počátku a na konci roku. Pro přesné počítání týdnů pro více roků používáme upřesnění /isoweek.

Příklady

d: now
== 10-Jul-2017/23:28:07-06:00
d/week
== 28
d/week: 29
== 29
d
== 16-Jul-2017/23:28:07-06:00
d/week: 52
== 52
d
== 24-Dec-2017/23:28:07-06:00
d/week: 53
== 53
d
== 31-Dec-2017/23:28:07-06:00
d/week: 54
== 54
d
== 7-Jan-2018/23:28:07-06:00

3.14. /isoweek

Syntaxe

<date>/isoweek
<date>/isoweek: <day>

<date>    : slovo nebo cesta odkazující na hodnotu date!
<isoweek> : hodnota typu integer!

Popis

Vrací číslo týdne podle definice ISO 8601, od 1 do 52 (v některých letech 53). Zadání pořadového čísla týdne způsobí příslušné přepočítání datumové hodnoty. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

Příklady

d: now
== 10-Jul-2017/23:29:13-06:00
d/isoweek
== 28
d/isoweek: 29
== 29
d
== 17-Jul-2017/23:29:13-06:00
d/isoweek: 52
== 52
d
== 25-Dec-2017/23:29:13-06:00
d/isoweek: 53
== 53
d
== 1-Jan-2018/23:29:13-06:00

3.15. Číselné indikátory

Pro přístup k polím datumu je rovněž možné použít číselný index (ordinal accessor) místo slovního označení:

<date>/<index>

<date>  : slovo nebo cesta odkazující na hodnotu date!
<index> : hodnota typu integer! odkazující na pole datumu.

Řadový indikátor (accessor) může být použit pro získání i pro zadání obsahu polí. Následující tabulka uvádí ekvivalentní názvy polí:

Index Name

1

date

2

year

3

month

4

day

5

zone

6

time

7

hour

8

minute

9

second

10

weekday

11

yearday

12

timezone

13

week

14

isoweek

3.16. Přístup k polím akcí Pick

K polím datumu lze přistoupit bez použití cesty a to s použitím funkce pick, což může být v některých případech výhodnější.

Syntaxe

pick <date> <field>

<date>  : hodnota typu date!
<field> : hodnota typu integer!

Celočíselný argument představuje řadový indikátor pro datumy. Viz tabulka výše.

Příklady

d: now
== 10-Jul-2017/23:35:01-06:00
names: system/catalog/accessors/date!
== [date year month day zone time hour minut second ...   ]

;; pad viz "help pad":

repeat i 14 [print [pad i 4 pad names/:i 10 pick d i]]
1    date       11-Jul-2017
2    year       2017
3    month      7
4    day        11
5    zone       8:00:00
6    time       21:43:52
7    hour       21
8    minute     43
9    second     52.0
10   weekday    2
11   yearday    192
12   timezone   8:00:00
13   week       28
14   isoweek    28

4. Konverze

4.1. Unixový čas epochy

Datumy lze konvertovat z/do formátu Unix epoch time s použitím akce to.

Syntaxe

to-integer <date>
to-date <epoch>

<date>  : hodnota typu date!
<epoch> : celočíselná hodnota, představující "epochální" čas

Unixové časy se vyjadřují ve formátu UTC. Nemá-li argument tento formát, je na něj před konverzí interně převeden.

d: 8-Jul-2017/17:49:27+08:00
to-integer d
== 1499507367

to-integer 8-Jul-2017/9:49:27
== 1499507367

to-date to-integer d
== 8-Jul-2017/9:49:27

Epochální čas není definován za rok 2038.

4.2. Konverze bloku

Syntaxe

to date! <spec>

<spec> : blok hodnot pro pole datumu

Blok s argumenty je konvertován na hodnotu typu date! podle stejné skladby jako jsme viděli v odstavci 2.2 Konstruktorová skladba. Argumenty mimo rozsah způsobí vytvoření normalizovaného datumu.

to-date [1978 2 3]
== 3-Feb-1978

Argumentační blok bude konvertován na hodnotu typu date! podle stejné syntaxe jako pro make (viz 2.2 [runtime-creation]). Hodnoty argumentu, které jsou mimo požadovaný rozsah, vyústí v normalizovaná data. Pro striktní konverzi hodnot z bloku, která místo normalizovaná data vyústi v chybové hlášení, použijte make.

5. Komparace

Na datumy lze aplikovat všechny relační operátory: =, ==, <>, >, <, >=, <=, =?. Podporovány jsou také akce min, max a sort.

Příklady

3-Jul-2017/9:41:40+2:00 = 3-Jul-2017/5:41:40-2:00
== true

10/10/2017 < 1/1/2017
== false

max 10/10/2017 1/1/2017
== 10-Oct-2017

1/1/1980 =? 1-JAN-1980
== true

sort [1/1/2017 5/10/1999 3-Jul-2017/5:41:40-2:00 1/1/1950 1/1/1980/2:2:2]
== [1-Jan-1950 1-Jan-1980/2:02:02 5-Oct-1999 1-Jan-2017 3-Jul-2017/5:41:40-02:00]

6. Aritmetika

Podporované matematické operace zahrnují:

  • sčítání nebo odčítání hodnot libovolného datumového pole: výsledek je normalizován

  • sčítání nebo odčítání celého čísla s hodnotou datumu: vztahuje se na dny datumu

  • sčítání nebo odčítání času s datumem: vztahuje se na časové pole datumu

  • odečtení dvou datumových hodnot: výsledkem je signovaný počet dnů mezi oběma datumy

  • použití funkce difference pro dva datumy: výsledkem je signovaný rozdíl v hodinách ve formátu time!

Examples

20-Feb-1980 + 50
== 10-Apr-1980

20-Feb-1980 + 3
== 23-Feb-1980

20-Feb-1980 - 25
== 26-Jan-1980

20-Feb-1980 + 100
== 30-May-1980

28-Feb-1980 + 20:30:45
== 28-Feb-1980/20:30:45

28-Feb-1980/8:30:00 + 20:30:45
== 29-Feb-1980/5:00:45

d: 20-Feb-1980
d/day: d/day + 50
== 10-Apr-1980

d: 20-Feb-1980
d/month: d/month + 5
== 20-Jul-1980

d: 28-Feb-1980/8:30:00
d/hour: d/hour + 48
== 1-Mar-1980/8:30:00

08/07/2017/10:45:00 - 20-Feb-1980/05:30:0
== 13653

difference 08/07/2017/10:45:00 20-Feb-1980/05:30:0
327677:15:00

7. Získání aktuálního datumu

Funkce now vrací aktuální datum a čas (včetně časového pásma) podle operačního systému počítače. Všechny přístupové indikátory (accessory) jsou funkci now přístupné jako upřesnění (refinements) s několika dodatky:

  • /utc: vrátí datum ve formátu UTC

  • /precise: vrátí čas s vyšší přesností (1/60 vteřiny ve Windows, mikrosekunda v Unix)

Příklady

now
== 8-Jul-2017/18:32:25+08:00

now/year
== 2017

now/hour
== 18

now/month
== 7

now/day
== 8

now/hour
== 18

now/zone
== 8:00:00

now/utc
== 8-Jul-2017/10:32:25

8. Jiné funkce, související s datumem

8.1. Random

Syntaxe

random <date>

<date> : hodnota typu date!

Popis

Vrací náhodné datum pro zadaný argument jako horní limit. Nemá-li argument složku času či časového pásma, nemá ji ani vracený výsledek.

Příklady

random 09/07/2017
== 18-May-1972

random 09/07/2017
== 13-Aug-0981

random 09/07/2017/12:00:00+8
== 28-Feb-0341/17:57:12+04:00

random 09/07/2017/12:00:00+8
== 13-Dec-1062/5:09:12-00:30

results matching ""

    No results matching ""