Virtlab:TimeUsage

Z VirtlabWiki

(Rozdíly mezi verzemi)
Přejít na: navigace, hledání
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

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 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() [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.

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

Viz také odkazy - funkce Ivana Doležala.

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

  • 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


Odkazy

Osobní nástroje