Dlaczego? Łatwiej bedzie mi to wyjasnic jesli wyjaśnijmy sobie jak dzialaja podstawowe funkcje czasu i daty.
podstawa jest tu oczywiscie time() - ktory zwraca nam tzw. znacznik (stamp) unixowy. Nie jest to zadna data, a raczej rodzaj kalendarza (dziala podobnie jak kalendarz astronomiczny, tyle ze mniej dokladnie), ktorego dana chwila jest zapisywana w postaci liczby calkowitej wyrazajacej ilosc sekund jakie minely od dnia 1 stycznia 1970 roku o godzinie 0.00 czasu GMT. I tu od razu nalezy unikac pokusy, ktorej ja sam swego czasu nie uniknalem, by dodawac roznice czasowa do tej funkcji. To najgorszy blad! Dowiedza sie o tym Ci, ktorzy zmienia serwer na serwer w innej strefie czasowej. Przy funkcji time() nie trzeba nic robic, poniewaz w kazdej strefie czasowej w jakiej moglby byc serwer zawsze zwroci te sama wartosc.
Problemem jest funkcja date(), ktora na podstawie znacznika zwraca nam date jaka byla(jest) w danej strefie. Musielibysmy uzyc funkcji gmdate(), ktora zwraca nam date zawsze ta sama, date strefy GMT. Wystraczyloby dodac tylko godzinke i byloby po robocie, ale... niestety strefa gmt nie pzrewiduje czasu letniego. Jesli jednak, co nie jest trudne, zrobimy to funkcja, to spotka nas zawod: jesli mamy serwer w stanach - czas letni tam jest wprowadzany tydzien pozniej niz u nas! To tez, choc trudniej, mozna spacyfikowac, ale dostaniemy juz funkcje potworka. Lepiej zrobic cos uniwersalnego. Dzieki czemy bedziemy mogli skakac latwo po strefach.
Zaczynamy:
tworzymy klase w osobnym pliku, ja go nazwalem jak klase udate.php
w nim ostwieramy klase i definiujemy zmienne:
[php]<?php
class udate
{
var $czl;
var $czl_styl_klient;
var $czl_styl_serwer;
var $strefa;
var $format;
}
?>[/php]
Teraz ustawimy wartosci standardowe. To znaczy dla tych, dla ktorychi nie okreslimy wartosci przy wywolaniu klasy. Robimy tzw. konstruktora czyli funkcje o takiej samej nazwie jak klasa. Dzieki temu bedzie ona sie wywolywac automatycznie:
[php]<?php
function udate()
{
$this->czl=1;
$this->czl_styl_klient="UE";
$this->czl_styl_serwer="UE";
$this->strefa=1;
$this->format="Y-m-d H:i";
}
?>[/php]
tu chyba wszytko jasne. Teraz musimy stworzyc funkcje, ktorymi bedziemy zmieniac nasze wartosci:
[php]<?php
function ustaw_czl($set)
{
if ($set==1 || $set==0)
{
$this->czl=$set;
}
else
{
$this->czl=$this->czl;
}
}
function ustaw_czl_styl_klient($set)
{
if ($set=="US" || $set=="UE")
{
$this->czl_styl_klient=$set;
}
else
{
$this->czl_styl_klient=$this->czl_styl_klient;
}
}
function ustaw_czl_styl_serwer($set)
{
if ($set=="US" || $set=="UE")
{
$this->czl_styl_serwer=$set;
}
else
{
$this->czl_styl_serwer=$this->czl_styl_serwer;
}
}
function ustaw_strefa($set)
{
if ($set<12 || $set>-12)
{
$this->strefa=$set;
}
else
{
$this->strefa=$this->strefa;
}
}
function ustaw_format($set)
{
$this->format=$set;
}
?>[/php]
Oprocz zmiennej $format, kazda inna ma ma zabezpiedczenie - jesli podamy mu wartosc spoza dopuszczalnego zakresu zwroci nam wartosci zdefinowane na poczatku.
Teraz przechodzimy do sedna. Glowna funkcja:
[php]<?php
function pokaz_date($stamp)
{
$chk_dls=date("I",$stamp);
$year=gmdate("Y",$stamp);
///
if ($this->czl_styl_klient=="UE")
{
$day=25;
while ($dow!="Sun")
{
$a=gmmktime (1,0,0,3,$day,$year);
$dow=gmdate("D",$a);
$day++;
}
$border=$a;
}
elseif($this->czl_styl_klient=="US")
{
$day=1;
while ($dow!="Sun")
{
$a=gmmktime (1,0,0,4,$day,$year);
$dow=gmdate("D",$a);
$day++;
}
$border=$a;
}
///
if ($this->czl==1)
{
if (($this->czl_styl_klient=="US" && $this->czl_styl_serwer=="US")||($this->czl_styl_klient=="UE" && $this->czl_styl_serwer=="UE"))
{
if ($chk_dls==1){$dat=gmdate($this->format,$stamp+(($this->strefa*3600)+3600));
}
else
{
$dat=gmdate($this->format,$stamp+($this->strefa*3600));
}
}
elseif($this->czl_styl_klient=="US" && $this->czl_styl_serwer=="UE")
{
if ($chk_dls==1 && $stamp>=$border)
{
$dat=gmdate($this->format,$stamp+(($this->strefa*3600)+3600));
}
else
{
$dat=gmdate($this->format,$stamp+($this->strefa*3600));
}
}
elseif($this->czl_styl_klient=="UE" && $this->czl_styl_serwer=="US")
{
if ($chk_dls==1 || ($stamp>=$border && $stamp<$border+(7*24*3600)))
{
$dat=gmdate($this->format,$stamp+(($this->strefa*3600)+3600));
}
else
{
$dat=gmdate($this->format,$stamp+($this->strefa*3600));
}
}
}
elseif($this->czl==0)
{
$dat=gmdate($this->format,$stamp+($this->strefa*3600));
}
print $dat;
}
?>[/php]
Wyjasnie po krotce co sie tu dzieje:
Teraz kilka przykladow. Bierzemy na tapete stamp z chwili przejscia na czas letni: 985482000 to 2001-03-25 02:00 wg czasu CET (np. Polska) a 2001-03-25 03:00 uwzgledniajac przejscie na czas letni. Byla to chwila kiedy z gdziny 2.00 przesunelismy zegarki na godzine 3.00
jesli mamy serwer w Polsce:
[php]<?php
include "udate.php";
$udate=new udate();
$udate->pokaz_date("985482000");
?>[/php]
zwroci nam: "2001-03-25 03:00"
jesli w stanach:
[php]<?php
include "udate.php";
$udate=new udate();
$udate->ustaw_czl(1);
$udate->ustaw_czl_styl_klient("UE");
$udate->ustaw_czl_styl_serwer("US");
$udate->ustaw_strefa(1);
$udate->pokaz_date("985482000");
?>[/php]
zwroci nam znowu "2001-03-25 03:00", uzylem wszytkich dostepnych medod w celach pokazowych, niektorych nie trzeba bylo, bo i tak zawieraja wartosci juz zadeklarowane w konstruktorze
a jaka jest godzina w NY?:
[php]<?php
include "udate.php";
$udate=new udate();
$udate->ustaw_czl(1);
$udate->ustaw_czl_styl_klient("US");
$udate->ustaw_czl_styl_serwer("UE");
$udate->ustaw_strefa(-5);
$udate->pokaz_date("985482000");
?>[/php]
otrzymamy date: "2001-03-24 20:00"
=====
oto jednolita klasa:
[php]<?php
class udate{
var $czl;
var $czl_styl_klient;
var $czl_styl_serwer;
var $strefa;
var $format;
function udate()
{
$this->czl=1;
$this->czl_styl_klient="UE";
$this->czl_styl_serwer="UE";
$this->strefa=1;
$this->format="Y-m-d H:i";
}
function ustaw_czl($set)
{
if ($set==1 || $set==0)
{
$this->czl=$set;
}
else
{
$this->czl=$this->czl;
}
}
function ustaw_czl_styl_klient($set)
{
if ($set=="US" || $set=="UE")
{
$this->czl_styl_klient=$set;
}
else
{
$this->czl_styl_klient=$this->czl_styl_klient;
}
}
function ustaw_czl_styl_serwer($set)
{
if ($set=="US" || $set=="UE")
{
$this->czl_styl_serwer=$set;
}
else
{
$this->czl_styl_serwer=$this->czl_styl_serwer;
}
}
function ustaw_strefa($set)
{
if ($set<12 && $set>-12)
{
$this->strefa=$set;
}
else
{
$this->strefa=$this->strefa;
}
}
function ustaw_format($set)
{
$this->format=$set;
}
function pokaz_date($stamp)
{
$chk_dls=date("I",$stamp);
$year=gmdate("Y",$stamp);
///
if ($this->czl_styl_klient=="UE")
{
$day=25;
while ($dow!="Sun")
{
$a=gmmktime (1,0,0,3,$day,$year);
$dow=gmdate("D",$a);
$day++;
}
$border=$a;
}
elseif($this->czl_styl_klient=="US")
{
$day=1;
while ($dow!="Sun")
{
$a=gmmktime (1,0,0,4,$day,$year);
$dow=gmdate("D",$a);
$day++;
}
$border=$a;
}
///
if ($this->czl==1)
{
if (($this->czl_styl_klient=="US" && $this->czl_styl_serwer=="US")||($this->czl_styl_klient=="UE" && $this->czl_styl_serwer=="UE"))
{
if ($chk_dls==1){$dat=gmdate($this->format,$stamp+(($this->strefa*3600)+3600));
}
else
{
$dat=gmdate($this->format,$stamp+($this->strefa*3600));
}
}
elseif($this->czl_styl_klient=="US" && $this->czl_styl_serwer=="UE")
{
if ($chk_dls==1 && $stamp>=$border)
{
$dat=gmdate($this->format,$stamp+(($this->strefa*3600)+3600));
}
else
{
$dat=gmdate($this->format,$stamp+($this->strefa*3600));
}
}
elseif($this->czl_styl_klient=="UE" && $this->czl_styl_serwer=="US")
{
if ($chk_dls==1 || ($stamp>=$border && $stamp<$border+(7*24*3600)))
{
$dat=gmdate($this->format,$stamp+(($this->strefa*3600)+3600));
}
else
{
$dat=gmdate($this->format,$stamp+($this->strefa*3600));
}
}
}
elseif($this->czl==0)
{
$dat=gmdate($this->format,$stamp+($this->strefa*3600));
}
print $dat;
}
}
?>[/php]

