Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Pobranie strefy czasowej, która teraz ma północ
Forum PHP.pl > Forum > PHP
phpion
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
wookieb
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.
phpion
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óż 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 wink.gif
wookieb
  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];
phpion
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?
wookieb
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".
phpion
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 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.
thek
OK... lecę... taki kod wymodziłem 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 smile.gif

Sorki za małego byka przy wyświetlaniu 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.
phpion
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.
thek
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 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 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 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ę.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.