Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Pobranie strefy czasowej, która teraz ma północ
phpion
post
Post #1





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Witam,
mam problem natury logicznej: w jaki sposób pobrać offset strefy czasowej, która w aktualnej godzinie ma północ? Kombinowałem na różne sposoby, posiłkowałem się tym ale cały czas nie ogarniam tego :| Googlowanie niestety również nic nie pomogło.

Pozdrawiam,
pion
Powód edycji: [phpion]: Przeniosłem do algorytmów
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 9)
wookieb
post
Post #2





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Hmm
-24 + aktualna godzina + aktualny offset strefy czasowej.
Jeżeli wynik jest mniejszy lub równe od -12 to dodajemy do niego 24.

Np dla teraz (godzina 12, strefa czasowa +1) wychodzi -11 (i to się zgadza).



godzina 10, strega czasowa + 1, wychodzei - 13 . Ale skoro jest jest mniejsze od -12 więc... -13 + 24 = GMT + 11. I to się zgadza.
Go to the top of the page
+Quote Post
phpion
post
Post #3





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




A teraz sprawdź dla godziny 01:00. Biorąc pod uwagę, że serwer stoi w Polsce (przesunięcie +1) powinniśmy otrzymać w wyniku 0 (o tej godzinie północ jest w Irlandii), a mamy 2.

@thek: Widzę, że tu jesteś - pomóż (IMG:style_emoticons/default/smile.gif)

Na razie z wykorzystaniem http://www.timezoneconverter.com/cgi-bin/tzc.tzc zrobiłem sobie mapę - może komuś się przyda:
  1. $map = array(
  2. '0' => 1,
  3. '0.5' => NULL,
  4. '1' => 0,
  5. '1.5' => 0.5,
  6. '2' => -1,
  7. '2.5' => -1.5,
  8. '3' => -2,
  9. '3.5' => -2.5,
  10. '4' => -3,
  11. '4.5' => -3.5,
  12. '5' => -4,
  13. '5.5' => -4.5,
  14. '6' => -5,
  15. '6.5' => -5.5,
  16. '7' => -6,
  17. '7.5' => -6.5,
  18. '8' => -7,
  19. '8.5' => -7.5,
  20. '9' => -8,
  21. '9.5' => -8.5,
  22. '10' => -9,
  23. '10.5' => NULL,
  24. '11' => 14, // nowy dzien
  25. '11.5' => 13.5,
  26. '12' => 13,
  27. '12.5' => 12.5,
  28. '13' => 12,
  29. '13.5' => 11.5,
  30. '14' => 11,
  31. '14.5' => 10.5,
  32. '15' => 10,
  33. '15.5' => 9.5,
  34. '16' => 9,
  35. '16.5' => 8.5,
  36. '17' => 8,
  37. '17.5' => 7.5,
  38. '18' => 7,
  39. '18.5' => 6.5,
  40. '19' => 6,
  41. '19.5' => 5.5,
  42. '20' => 5,
  43. '20.5' => 4.5,
  44. '21' => 4,
  45. '21.5' => 3.5,
  46. '22' => 3,
  47. '22.5' => 2.5,
  48. '23' => 2,
  49. '23.5' => 1.5
  50. );

Za bardzo nie miałem tego jeszcze jak przetestować, ale powinno być ok. Kluczem jest godzina (np. 10 oznacza 10:00, 10.5 to 10:30), a wartością offset. Trochę niepokoi mnie godzina 00:30 i 01:30 - wygląda jakby północ mogła być w 2 strefach czasowych (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
wookieb
post
Post #4





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




  1. $godzina = 1; // dla GMT 0
  2. $strefa_czasowa = 1; // strefa czasowa czyli dla 01:00 w GMT + 1 będzie 02:00
  3. // resztę możesz wyliczyć.
  4. $range = array_merge(range(0, -12), range(11, 1));
  5.  
  6. echo $range[($godzina + $strefa_czasowa)%12];
Go to the top of the page
+Quote Post
phpion
post
Post #5





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Hmmm, nie bardzo potrafię tego użyć. Jakie wartości podstawić pod $godzina i $strefa_czasowa by będąc aktualnie w strefie GMT+1 i mając godzinę 01:00 otrzymać offset strefy 0?
Go to the top of the page
+Quote Post
wookieb
post
Post #6





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




Ta "funkcja" zwraca Ci info w jakiej strefie czasowej jest aktualnie północ.
Tak więc po przeróbkach
  1. $godzina = 4;
  2. $strefa_czasowa = 1;
  3. $godzina_dla_gmt0 = $godzina - $strefa_czasowa;
  4. if ($godzina_dla_gmt0 < 0 || $godzina_dla_gmt0 > 24) {
  5. $godzina_dla_gmt0 = abs(24 - $godzina_dla_gmt0);
  6. }
  7. $range = array_merge(range(0, -12), range(11, 1));
  8.  
  9. $strefa_z_polnoca = $range[($godzina_dla_gmt0+ $strefa_czasowa)%12];
  10.  
  11. $offset = $strefa_czasowa + $strefa_z_polnoca;
  12. echo $offset;
  13.  


Przenoszę do "php".
Go to the top of the page
+Quote Post
phpion
post
Post #7





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Wywala się np. dla:
  1. $godzina = 0;
  2. $strefa_czasowa = 1;

Powinno zwrócić 1, a zwraca -1. Ale walić to, dzięki za zainteresowanie - zostawię sobie tą tablicę i spokój (IMG:style_emoticons/default/smile.gif)

PS: Sam przeniosłem do Algorytmów bo sądziłem, że w końcu powstanie gotowa funkcja. Ale ok, niechaj będzie PHP.
Go to the top of the page
+Quote Post
thek
post
Post #8





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




OK... lecę... taki kod wymodziłem (IMG:style_emoticons/default/wink.gif)
  1. <?php
  2. //ustawiamy datę i strefę czasową naszą
  3. $date = new DateTime( '2011-06-28', new DateTimeZone('Europe/Warsaw' ) );
  4. //ustawiamy godzinę dla nas
  5. $date->setTime(12,0);
  6. //łapiemy timestamp (uwaga... PHP 5.3!)
  7. $timestamp = $date->getTimestamp();
  8. //dla testów sprawdzamy godzinę
  9. echo $date->format('Y-m-d H:i:s');
  10. //łapiemy godzinę, która dla tego timestamp jest w UTC
  11. //To będzie nasz czas minus offset stref. PHP samo czas UTC wyłapie po timestamp... nie musimy nic minusować i dodawać.
  12. $utc = date('H', $timestamp);
  13. //Strefy czasowe rozciągają się od UTC+14 do UTC-12
  14. //tu sprawdzamy czy w przyszłości załapiemy sie na północ...
  15. //(innymi słowy) czy są strefy czasowe gdzie jest już północ z 28 na 29
  16. if( ($utc+14) >= 24 ) {
  17. echo '<br />Jest strefa z polnoca w przyszlosci: ';
  18. //liczymy offset
  19. $diff_for = 24-$utc;
  20. //i mamy strefę
  21. echo '2011-01-29T00:00:00+'.str_pad($diff_for, 2, "0", STR_PAD_LEFT).':00';
  22. $future = new DateTime( '2011-01-29 00:00:00+'.str_pad($diff_for, 2, "0", STR_PAD_LEFT).':00' );
  23. //teraz tylko wyłap jaka strefa czasowa to ma ;)
  24. }
  25. //tu sprawdzamy czy w przeszłości załapiemy sie na północ...
  26. //(innymi słowy) czy są strefy czasowe gdzie północ z 28 dopiero teraz jest
  27. if( ($utc-12) <= 0 ) {
  28. echo '<br />Jest strefa z polnoca w przeszlosci: ';
  29. //liczymy offset, ale nie musimy... mamy go jako $utc ;)
  30. $diff_back = -$utc;
  31. echo '2011-01-28T00:00:00-'.str_pad($utc, 2, "0", STR_PAD_LEFT).':00';
  32. $past = new DateTime( '2011-01-28 00:00:00-'.str_pad($utc, 2, "0", STR_PAD_LEFT).':00' );
  33. //teraz tylko wyłap jaka strefa czasowa to ma ;)
  34. }
  35. ?>


PS... Zwróćcie uwagę, że jednego dnia moga być daty z północą w PRZYSZŁOŚCI i PRZESZŁOŚCI!
Dla naszej strefy czasowej wypada to około połuudnia... Pewnie bym tego nie zauważył, ale Wiki stwierdziła, że z racji przesunięć, zakres jest nie od -12/+12, ale -12/+14 (IMG:style_emoticons/default/smile.gif)

Sorki za małego byka przy wyświetlaniu (IMG:style_emoticons/default/wink.gif) Dla 1 w nocy poda datę o dzień w przód, choć strefę czasową podaje wtedy prawidłowo... Gdyż date('H', $timestamp ) zwróci 23. Zakwalifikuje więc datę do przyszłości, choć offset będzie prawidłowy w wyniku. tak więc by nie mylić, zwracaj tylko uwagę na offset. I porównuj do naszego offsetu dla strefy czasowej.
Powód edycji: [thek]: EDIT
Go to the top of the page
+Quote Post
phpion
post
Post #9





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Chyba znowu nie do końca działa poprawnie. Podaj jako godzinę 0 - powinno zwrócić 1, a zwraca 0, dla godziny 1 powinno zwrócić 0, a zwraca -1. Ja już sobie to daruję, mam tablicę i starczy.
Go to the top of the page
+Quote Post
thek
post
Post #10





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Oba kody więc mają byka... Mój wali się w dniach, ale jest bezbłędny co do offsetów, a u wookieb'a na odwrót (IMG:style_emoticons/default/biggrin.gif)

Wersja php 5.3.5
$date = new DateTime( '2011-06-28', new DateTimeZone('Europe/Warsaw' ) );
$date->setTime(0,0);

Output:
Cytat
2011-06-28 00:00:00
Jest strefa z polnoca w przyszlosci: 2011-01-29T00:00:00+02:00

I jest to prawda... tylko że nie 29, ale 28 (IMG:style_emoticons/default/smile.gif) Ponieważ dla północy naszego czasu jesteśmy w strefie prawidłowo wyliczonej. Na chwilę obecną mamy bowiem DST, czyli nie +1, ale +2 w porównaniu do UTC. Zresztą można to prosto sprawdzić...
$date->getOffset() zwrócić powinien 7200 sekund różnicy, czyli 2 godziny...

Daj 1 w nocy:

Output:
2011-06-28 01:00:00
Jest strefa z polnoca w przyszlosci: 2011-01-29T00:00:00+01:00

Daj 2 w nocy:

Output:
2011-06-28 02:00:00
Jest strefa z polnoca w przeszlosci: 2011-01-28T00:00:00-00:00

Bingo... Zniwelowaliśmy wpływ Strefy czasowej, która wynosi +02:00

Jedyna rzecz której temu kawałkowi kodu brakuje to prawidłowe wyłapanie daty... Trzeba bowiem dzień ustalać pod kątem offsetu strefy czasowej w $date

A teraz dla porównania: nasz 17:

2011-06-28 17:00:00
Jest strefa z polnoca w przyszlosci: 2011-01-29T00:00:00+09:00
Czemu tak? 17+9 = 26... Ale jesteśmy w +2 czyli tyle na minus -> 24... Jest północ? Jest (IMG:style_emoticons/default/smile.gif)

I dla efektu... 14
2011-06-28 14:00:00
Jest strefa z polnoca w przyszlosci: 2011-01-29T00:00:00+12:00
Jest strefa z polnoca w przeszlosci: 2011-01-28T00:00:00-12:00
Północ dziś i jutro jak zwrotka. Sam sprawdź.

Dla 13 Wookieb odrzuci datę w przyszłości... Ponieważ dla niego +13 nie pasuje z racji modulo. Ale myślę, że trochę przeróbek i gdyby uwzględnił zakres -12/+14 to by wychwycił ową zgubioną strefę.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 25.08.2025 - 04:07