Virtlab:TimeUsage
Z VirtlabWiki
(Rozdíly mezi verzemi)
Verze z 05:55, 10. 8. 2007 Gry72 (Diskuse | příspěvky) ← Předchozí porovnání |
Aktuální verze Dol72 (Diskuse | příspěvky) (→Linux - nenápadný půvab dpkg-reconfigure tzdata) |
||
Řádka 1: | Řádka 1: | ||
- | Je předpokládána distribuce lokalit Virtlabu v různých timezones. Předpokládáme, že všechny zúčastněné servery (OS) poběží v UTC (vztah s Unix Timestamps musí být vyjasněn, možná diference nějakých sekund). Veškeré interakce mezi komponentami předávají jako parametr čas v UTC, v UTC se také vnitřně pracuje a loguje, pouze webové rozhraní uživateli prezentuje výstupy a akceptuje vstupy s ohledem na timezone nastavenou pro daného uživatele. | + | == Vysvětlení pojmů a nejasností == |
+ | === Základní fakta === | ||
+ | * '''jediné''' časové jednotky, které jsou "neměnné" jsou '''SEKUNDY''' ('''MINUTY''' a '''HODINY''') - definované v soustavě jednotek SI. Ve všech dále zmiňovaných časových soustavách ''tikají'' tedy stejně rychle! | ||
+ | * moderní čas se měří podle atomových hodin | ||
+ | * jednotky jako '''DEN''' a '''ROK''' jsou odvozený od pohybu Země (rotace kolem osy a kolem Slunce), ale ta '''NENÍ KONSTANTNÍ'''. Pro korekci časů byly zavedeny '''LEAP SECONDS''' - přestupné sekundy, o jejichž přičtení rozhoduje [http://www.iers.org/ Mezinárodní služba pro rotaci Zeměkoule a vztažné soustavy] - viz dále. | ||
+ | === Jednotlivé časové soustavy === | ||
+ | ;UT1: měří čas na základě rotace Země a dalších vesmírných těles, proto '''DEN''' nemá přesně 86400s! Rotace Země se zpomaluje, a tak se den prodlužuje. | ||
+ | ;TAI: mezinárodní atomový čas. '''DEN'' má přesně 86400s!! | ||
+ | ;UTC: mezinárodní koordinovaný čas. Sekundy tikají stejně jako u TAI, ale pokud je rozdíl '''UT1-UTC''' dostatečně velký, bude mít silvestr o jednu sekundu více, takže na hodinách byste mohli viděl údaj jako: '''23:59:60.25'''. Rozdíl mezi '''TAI-UTC''' je dnes více než 32s. | ||
+ | ;GMT: ''Greenwich Mean Time''. Původně šlo o astronomický čas (viz UT1), ale dnes jeho zímní varianta odpovídá přesně UTC | ||
+ | ;Unix time: jde o počet sekund od '''00:00:00 UTC 1.1.1970'''. LEAP SECONDS se '''nepřičítají'''. Unixtimestamp je stejná všude na Zemi (nepodléhá časovým zónám). | ||
+ | |||
+ | === Časová pásma === | ||
+ | závisí na geografické poloze na Zemi. Udává je jako offset k UTC (od -12h do +14h) | ||
+ | |||
+ | == Jak na čas v jednotlivých jazycích a systémech == | ||
+ | === Linux === | ||
+ | ;hwclock: zobrazuje a nastavuje CMOS hodiny na desce | ||
+ | ;tzconfig: nastavuje časovou zónu | ||
+ | ;dpkg-reconfigure tzdata: ještě více nastavuje časovou zónu | ||
+ | ;/etc/timezone: obsahuje název aktuálně nastavené časové zóny | ||
+ | ;date: zobrazí čas s ohledem na časovou zónu | ||
+ | |||
+ | === PHP === | ||
+ | ;time() [http://cz.php.net/time]: vrátí aktuální Unixtimestamp | ||
+ | ;date(...) [http://cz.php.net/date]: vrátí čas formátovaný podle uvedených parametrů - vstupem je Unixtimestamp. '''Aplikuje''' se nastavení časového pásma. | ||
+ | ;strftime(...) [http://cz.php.net/strftime]: stejně jako u '''date'''. Formátovací jazyk je ale jiný. Podobu výpisu lze ovlivnit ještě nastavením národních specifik (December/Prosinec, ...) | ||
+ | ;date_default_timezone_set(...) [http://cz2.php.net/date_default_timezone_set]: explicitně nastaví časovou zónu, kterou budou funkce používat. Pokud není nastaveno, použije se nastavení systému. | ||
+ | |||
+ | |||
+ | Viz také odkazy - funkce Ivana Doležala. | ||
+ | |||
+ | === MySQL === | ||
+ | ;NOW() : vrátí aktuální čas (podle nastavení časové zóny, viz dále) ve formátu ''YYYY-MM-DD HH:MM:SS'' | ||
+ | ;UNIX_TIMESTAMP(...) : převede vložený čas na Unixtimestamp (např.: UNIX_TIMESTAMP(NOW()) ) | ||
+ | ;UTC_TIMESTAMP() : vrátí aktuální čas v UTC ve formátu ''YYYY-MM-DD HH:MM:SS'' | ||
+ | ;SET time_zone='+0:00' [http://dev.mysql.com/doc/refman/5.0/en/time-zone-support.html] : nastaví časovou zónu (hodnota je offset k UTC), nastavení funguje po dobu spojení, defaultně se používá nastavení SYSTEm, kdy se použije nastavení systému | ||
+ | |||
+ | === C === | ||
+ | ;time [http://linux.die.net/man/2/time]: vrací aktuální Unixtimestamp | ||
+ | ;gmtime [http://linux.die.net/man/3/gmtime]: z Unixtimestamp vyrobí strukturu v UTC | ||
+ | ;localtime : z Unixtimestamp vyrobí strukturu podle nastavení systému | ||
+ | ;ctime : z Unixtimestamp vyrobí textový řetězec | ||
+ | |||
+ | == NTP == | ||
+ | Používá UTC. Ve zprávách se posílá množství sekund uplynutých od 00:00:00 1.1.1900. Používá 64bitovou časovou známku - 32bit na počet sekund a 32bit na desetinnou část počtu sekund - (k přetočení tak dochází každých 136let) - další verze přinesou 128bitovou známku. | ||
+ | |||
+ | == Ukázka == | ||
+ | * hodiny v BIOSu nastaveny na čas odpovídající UTC | ||
+ | * /etc/timezone - nastaveno na '''Europe/Moscow''', kde je o ''dvě hodiny více než u nás'' (aby bylo vidět rozdíly) | ||
+ | * když tohle píšu (v Ostravě), tak je přibližně: 20:30CEST - 18:30UTC - 22:30MSD '''(Praha - Londýn - Moskva)''' | ||
+ | |||
+ | === Linux === | ||
+ | <pre> | ||
+ | stilgar:/tmp# date | ||
+ | So zář 8 22:28:54 MSD 2007 | ||
+ | |||
+ | stilgar:/tmp# date --utc | ||
+ | So zář 8 18:29:13 UTC 2007 | ||
+ | |||
+ | stilgar:/tmp# hwclock --show | ||
+ | So 8. září 2007, 18:30:03 MSD -0.381898 seconds | ||
+ | |||
+ | stilgar:/tmp# hwclock --show --utc | ||
+ | So 8. září 2007, 22:31:22 MSD -0.145474 seconds | ||
+ | </pre> | ||
+ | |||
+ | === PHP === | ||
+ | |||
+ | Viz také odkazy - funkce Ivana Doležala. | ||
+ | |||
+ | ==== source ==== | ||
+ | <pre> | ||
+ | <?php | ||
+ | $strftime_dateformat = '%H:%M:%S %d.%m.%Y'; | ||
+ | $date_dateformat = 'H:i:s d.m.Y'; //HH:MM:SS DD:MM:YY | ||
+ | |||
+ | print("No settings:\n"); | ||
+ | $now = time(); | ||
+ | print( $now . "\n"); | ||
+ | print( strftime($strftime_dateformat, $now) . "\n"); | ||
+ | print( date($date_dateformat, $now) . "\n"); | ||
+ | |||
+ | date_default_timezone_set('GMT'); | ||
+ | print("timezone GMT:\n"); | ||
+ | $now = time(); | ||
+ | print( $now . "\n"); | ||
+ | print( strftime($strftime_dateformat, $now) . "\n"); | ||
+ | print( date($date_dateformat, $now) . "\n"); | ||
+ | |||
+ | print("timezone Europe/Prague:\n"); | ||
+ | date_default_timezone_set('Europe/Prague'); | ||
+ | $now = time(); | ||
+ | print( $now . "\n"); | ||
+ | print( strftime($strftime_dateformat, $now) . "\n"); | ||
+ | print( date($date_dateformat, $now) . "\n"); | ||
+ | ?> | ||
+ | </pre> | ||
+ | |||
+ | ==== výstup ==== | ||
+ | <pre> | ||
+ | No settings: | ||
+ | 1189276494 | ||
+ | 22:34:54 08.09.2007 | ||
+ | 22:34:54 08.09.2007 | ||
+ | |||
+ | timezone GMT: | ||
+ | 1189276494 | ||
+ | 18:34:54 08.09.2007 | ||
+ | 18:34:54 08.09.2007 | ||
+ | |||
+ | timezone Europe/Prague: | ||
+ | 1189276494 | ||
+ | 20:34:54 08.09.2007 | ||
+ | 20:34:54 08.09.2007 | ||
+ | </pre> | ||
+ | |||
+ | === SQL === | ||
+ | <pre> | ||
+ | mysql> SELECT NOW(), UNIX_TIMESTAMP(NOW()), UTC_TIMESTAMP(); | ||
+ | +---------------------+-----------------------+---------------------+ | ||
+ | | NOW() | UNIX_TIMESTAMP(NOW()) | UTC_TIMESTAMP() | | ||
+ | +---------------------+-----------------------+---------------------+ | ||
+ | | 2007-09-08 22:57:31 | 1189277851 | 2007-09-08 18:57:31 | | ||
+ | +---------------------+-----------------------+---------------------+ | ||
+ | 1 row in set (0.00 sec) | ||
+ | |||
+ | mysql> SET time_zone='+0:00'; | ||
+ | Query OK, 0 rows affected (0.00 sec) | ||
+ | |||
+ | mysql> SELECT NOW(), UNIX_TIMESTAMP(NOW()), UTC_TIMESTAMP(); | ||
+ | +---------------------+-----------------------+---------------------+ | ||
+ | | NOW() | UNIX_TIMESTAMP(NOW()) | UTC_TIMESTAMP() | | ||
+ | +---------------------+-----------------------+---------------------+ | ||
+ | | 2007-09-08 18:58:00 | 1189277880 | 2007-09-08 18:58:00 | | ||
+ | +---------------------+-----------------------+---------------------+ | ||
+ | 1 row in set (0.00 sec) | ||
+ | |||
+ | mysql> SET time_zone='+2:00'; | ||
+ | Query OK, 0 rows affected (0.00 sec) | ||
+ | |||
+ | mysql> SELECT NOW(), UNIX_TIMESTAMP(NOW()), UTC_TIMESTAMP(); | ||
+ | +---------------------+-----------------------+---------------------+ | ||
+ | | NOW() | UNIX_TIMESTAMP(NOW()) | UTC_TIMESTAMP() | | ||
+ | +---------------------+-----------------------+---------------------+ | ||
+ | | 2007-09-08 20:58:11 | 1189277891 | 2007-09-08 18:58:11 | | ||
+ | +---------------------+-----------------------+---------------------+ | ||
+ | 1 row in set (0.00 sec) | ||
+ | </pre> | ||
+ | |||
+ | === C === | ||
+ | ==== source ==== | ||
+ | <pre> | ||
+ | #include <stdio.h> | ||
+ | #include <time.h> | ||
+ | |||
+ | int main() { | ||
+ | time_t cas1; | ||
+ | struct tm *cas2; | ||
+ | char *cas3; | ||
+ | |||
+ | cas1 = time(NULL); | ||
+ | printf("%d\n", cas1); | ||
+ | |||
+ | cas2 = gmtime(&cas1); | ||
+ | printf("%d:%d:%d %d.%d.%d\n", cas2->tm_hour, cas2->tm_min, cas2->tm_sec, cas2->tm_mday, cas2->tm_mon, cas2->tm_year); | ||
+ | |||
+ | cas2 = localtime(&cas1); | ||
+ | printf("%d:%d:%d %d.%d.%d\n", cas2->tm_hour, cas2->tm_min, cas2->tm_sec, cas2->tm_mday, cas2->tm_mon, cas2->tm_year); | ||
+ | |||
+ | cas3 = ctime(&cas1); | ||
+ | printf("%s\n", cas3); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | ==== výstup ==== | ||
+ | * pozn.: v Ostravě je 22:06 | ||
+ | <pre> | ||
+ | 20:6:51 8.8.107 | ||
+ | 0:6:51 9.8.107 | ||
+ | Sun Sep 9 00:06:51 2007 | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | |||
+ | == Odkazy == | ||
+ | * [[Řešení časových zón od Ivana Doležala]] | ||
* [http://www.csgnetwork.com/time2unixdscalc.html Standard Time To UNIX Timestamp Calculator] | * [http://www.csgnetwork.com/time2unixdscalc.html Standard Time To UNIX Timestamp Calculator] | ||
* [http://www.csgnetwork.com/unixds2timecalc.html UNIX Timestamp To Standard Time Calculator] | * [http://www.csgnetwork.com/unixds2timecalc.html UNIX Timestamp To Standard Time Calculator] | ||
+ | |||
+ | * [http://en.wikipedia.org/wiki/Unix_time Unix time] | ||
+ | * [http://en.wikipedia.org/wiki/Leap_second Leap second] | ||
+ | * [http://en.wikipedia.org/wiki/Coordinated_Universal_Time Coordinated Universal Time] | ||
+ | * [http://en.wikipedia.org/wiki/Greenwich_Mean_Time Greenwich Mean Time] | ||
+ | * [http://en.wikipedia.org/wiki/Universal_Time Universal Time] | ||
+ | * [http://en.wikipedia.org/wiki/International_Atomic_Time International Atomic Time] | ||
+ | * [http://en.wikipedia.org/wiki/Image:Leapsecond.ut1-utc.svg Rozdíl '''UT1-UTC'''] | ||
+ | * [http://en.wikipedia.org/wiki/List_of_time_zones List of time zones] | ||
+ | * [http://en.wikipedia.org/wiki/List_of_tz_zones_by_name List of time zones - by name] | ||
+ | * [http://en.wikipedia.org/wiki/List_of_tz_zones_by_country List of time zones - by country] | ||
+ | * [http://en.wikipedia.org/wiki/Network_Time_Protocol Network Time Protocol] | ||
+ | |||
+ | [[Kategorie:HOW-TO]] | ||
+ | [[Kategorie:PHP]] | ||
+ | [[Kategorie:C/Cpp]] |
Aktuální verze
Obsah |
[editovat]
Vysvětlení pojmů a nejasností
[editovat]
Základní fakta
- jediné časové jednotky, které jsou "neměnné" jsou SEKUNDY (MINUTY a HODINY) - definované v soustavě jednotek SI. Ve všech dále zmiňovaných časových soustavách tikají tedy stejně rychle!
- moderní čas se měří podle atomových hodin
- jednotky jako DEN a ROK jsou odvozený od pohybu Země (rotace kolem osy a kolem Slunce), ale ta NENÍ KONSTANTNÍ. Pro korekci časů byly zavedeny LEAP SECONDS - přestupné sekundy, o jejichž přičtení rozhoduje Mezinárodní služba pro rotaci Zeměkoule a vztažné soustavy - viz dále.
[editovat]
Jednotlivé časové soustavy
- UT1
- měří čas na základě rotace Země a dalších vesmírných těles, proto DEN nemá přesně 86400s! Rotace Země se zpomaluje, a tak se den prodlužuje.
- TAI
- mezinárodní atomový čas. 'DEN má přesně 86400s!!
- UTC
- mezinárodní koordinovaný čas. Sekundy tikají stejně jako u TAI, ale pokud je rozdíl UT1-UTC dostatečně velký, bude mít silvestr o jednu sekundu více, takže na hodinách byste mohli viděl údaj jako: 23:59:60.25. Rozdíl mezi TAI-UTC je dnes více než 32s.
- GMT
- Greenwich Mean Time. Původně šlo o astronomický čas (viz UT1), ale dnes jeho zímní varianta odpovídá přesně UTC
- Unix time
- jde o počet sekund od 00:00:00 UTC 1.1.1970. LEAP SECONDS se nepřičítají. Unixtimestamp je stejná všude na Zemi (nepodléhá časovým zónám).
[editovat]
Časová pásma
závisí na geografické poloze na Zemi. Udává je jako offset k UTC (od -12h do +14h)
[editovat]
Jak na čas v jednotlivých jazycích a systémech
[editovat]
Linux
- hwclock
- zobrazuje a nastavuje CMOS hodiny na desce
- tzconfig
- nastavuje časovou zónu
- dpkg-reconfigure tzdata
- ještě více nastavuje časovou zónu
- /etc/timezone
- obsahuje název aktuálně nastavené časové zóny
- date
- zobrazí čas s ohledem na časovou zónu
[editovat]
PHP
- time() [1]
- vrátí aktuální Unixtimestamp
- date(...) [2]
- vrátí čas formátovaný podle uvedených parametrů - vstupem je Unixtimestamp. Aplikuje se nastavení časového pásma.
- strftime(...) [3]
- stejně jako u date. Formátovací jazyk je ale jiný. Podobu výpisu lze ovlivnit ještě nastavením národních specifik (December/Prosinec, ...)
- date_default_timezone_set(...) [4]
- explicitně nastaví časovou zónu, kterou budou funkce používat. Pokud není nastaveno, použije se nastavení systému.
Viz také odkazy - funkce Ivana Doležala.
[editovat]
MySQL
- NOW()
- vrátí aktuální čas (podle nastavení časové zóny, viz dále) ve formátu YYYY-MM-DD HH:MM:SS
- UNIX_TIMESTAMP(...)
- převede vložený čas na Unixtimestamp (např.: UNIX_TIMESTAMP(NOW()) )
- UTC_TIMESTAMP()
- vrátí aktuální čas v UTC ve formátu YYYY-MM-DD HH:MM:SS
- SET time_zone='+0
- 00' [5] : nastaví časovou zónu (hodnota je offset k UTC), nastavení funguje po dobu spojení, defaultně se používá nastavení SYSTEm, kdy se použije nastavení systému
[editovat]
C
- time [6]
- vrací aktuální Unixtimestamp
- gmtime [7]
- z Unixtimestamp vyrobí strukturu v UTC
- localtime
- z Unixtimestamp vyrobí strukturu podle nastavení systému
- ctime
- z Unixtimestamp vyrobí textový řetězec
[editovat]
NTP
Používá UTC. Ve zprávách se posílá množství sekund uplynutých od 00:00:00 1.1.1900. Používá 64bitovou časovou známku - 32bit na počet sekund a 32bit na desetinnou část počtu sekund - (k přetočení tak dochází každých 136let) - další verze přinesou 128bitovou známku.
[editovat]
Ukázka
- hodiny v BIOSu nastaveny na čas odpovídající UTC
- /etc/timezone - nastaveno na Europe/Moscow, kde je o dvě hodiny více než u nás (aby bylo vidět rozdíly)
- když tohle píšu (v Ostravě), tak je přibližně: 20:30CEST - 18:30UTC - 22:30MSD (Praha - Londýn - Moskva)
[editovat]
Linux
stilgar:/tmp# date So zář 8 22:28:54 MSD 2007 stilgar:/tmp# date --utc So zář 8 18:29:13 UTC 2007 stilgar:/tmp# hwclock --show So 8. září 2007, 18:30:03 MSD -0.381898 seconds stilgar:/tmp# hwclock --show --utc So 8. září 2007, 22:31:22 MSD -0.145474 seconds
[editovat]
PHP
Viz také odkazy - funkce Ivana Doležala.
[editovat]
source
<?php $strftime_dateformat = '%H:%M:%S %d.%m.%Y'; $date_dateformat = 'H:i:s d.m.Y'; //HH:MM:SS DD:MM:YY print("No settings:\n"); $now = time(); print( $now . "\n"); print( strftime($strftime_dateformat, $now) . "\n"); print( date($date_dateformat, $now) . "\n"); date_default_timezone_set('GMT'); print("timezone GMT:\n"); $now = time(); print( $now . "\n"); print( strftime($strftime_dateformat, $now) . "\n"); print( date($date_dateformat, $now) . "\n"); print("timezone Europe/Prague:\n"); date_default_timezone_set('Europe/Prague'); $now = time(); print( $now . "\n"); print( strftime($strftime_dateformat, $now) . "\n"); print( date($date_dateformat, $now) . "\n"); ?>
[editovat]
výstup
No settings: 1189276494 22:34:54 08.09.2007 22:34:54 08.09.2007 timezone GMT: 1189276494 18:34:54 08.09.2007 18:34:54 08.09.2007 timezone Europe/Prague: 1189276494 20:34:54 08.09.2007 20:34:54 08.09.2007
[editovat]
SQL
mysql> SELECT NOW(), UNIX_TIMESTAMP(NOW()), UTC_TIMESTAMP(); +---------------------+-----------------------+---------------------+ | NOW() | UNIX_TIMESTAMP(NOW()) | UTC_TIMESTAMP() | +---------------------+-----------------------+---------------------+ | 2007-09-08 22:57:31 | 1189277851 | 2007-09-08 18:57:31 | +---------------------+-----------------------+---------------------+ 1 row in set (0.00 sec) mysql> SET time_zone='+0:00'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT NOW(), UNIX_TIMESTAMP(NOW()), UTC_TIMESTAMP(); +---------------------+-----------------------+---------------------+ | NOW() | UNIX_TIMESTAMP(NOW()) | UTC_TIMESTAMP() | +---------------------+-----------------------+---------------------+ | 2007-09-08 18:58:00 | 1189277880 | 2007-09-08 18:58:00 | +---------------------+-----------------------+---------------------+ 1 row in set (0.00 sec) mysql> SET time_zone='+2:00'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT NOW(), UNIX_TIMESTAMP(NOW()), UTC_TIMESTAMP(); +---------------------+-----------------------+---------------------+ | NOW() | UNIX_TIMESTAMP(NOW()) | UTC_TIMESTAMP() | +---------------------+-----------------------+---------------------+ | 2007-09-08 20:58:11 | 1189277891 | 2007-09-08 18:58:11 | +---------------------+-----------------------+---------------------+ 1 row in set (0.00 sec)
[editovat]
C
[editovat]
source
#include <stdio.h> #include <time.h> int main() { time_t cas1; struct tm *cas2; char *cas3; cas1 = time(NULL); printf("%d\n", cas1); cas2 = gmtime(&cas1); printf("%d:%d:%d %d.%d.%d\n", cas2->tm_hour, cas2->tm_min, cas2->tm_sec, cas2->tm_mday, cas2->tm_mon, cas2->tm_year); cas2 = localtime(&cas1); printf("%d:%d:%d %d.%d.%d\n", cas2->tm_hour, cas2->tm_min, cas2->tm_sec, cas2->tm_mday, cas2->tm_mon, cas2->tm_year); cas3 = ctime(&cas1); printf("%s\n", cas3); return 0; }
[editovat]
výstup
- pozn.: v Ostravě je 22:06
20:6:51 8.8.107 0:6:51 9.8.107 Sun Sep 9 00:06:51 2007
[editovat]