Virtlab:TimeUsage
Z VirtlabWiki
| Verze z 20:10, 8. 9. 2007 Vav166 (Diskuse | příspěvky) (→Ukázka) ← Předchozí porovnání  | 
				Verze z 20:22, 8. 9. 2007 Vav166 (Diskuse | příspěvky) (→C) Následující porovnání →  | 
			||
| Řádka 37: | Řádka 37: | ||
| ;time [http://linux.die.net/man/2/time]: vrací aktuální Unixtimestamp | ;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 | ;gmtime [http://linux.die.net/man/3/gmtime]: z Unixtimestamp vyrobí strukturu v UTC | ||
| - | ;localtime : z Unixtimestamp vyrobi strukturu podle nastavení systému | + | ;localtime : z Unixtimestamp vyrobí strukturu podle nastavení systému | 
| + | ;ctime : z Unixtimestamp vyrobí textový řetězec | ||
| == NTP == | == NTP == | ||
Verze z 20:22, 8. 9. 2007
Obsah | 
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, které se přičítají podle potřeby - 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
 - /etc/timezone
 - obsahuje název aktuálně nastavené časové zóny
 - date
 - zobrazí čas s ohledem na časovou zónu
 
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.
 
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
 
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
 
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
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
PHP
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");
?>
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
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)
C
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;
}
výstup
20:6:51 8.8.107 0:6:51 9.8.107 Sun Sep 9 00:06:51 2007
Původní text této stránky
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.
