Soru Greenwich Mean Time'ı PHP'de nasıl alabilirim?


EST'ye ayarlanmış bir sunucum var ve veritabanındaki tüm kayıtlar EST'ye ayarlandı. GMT'ye nasıl ayarlanacağını bilmek istiyorum. Kullanıcılarıma bir saat dilimi seçeneği sunmak istiyorum.


44
2018-05-12 07:30


Menşei




Cevaplar:


Hangi GMT saat dilimi sunucu olursa olsun, burada herhangi bir saat dilimi için zaman ve tarih almak için son derece kolay bir yoldur. Bu ile yapılır time() ve gmdate() fonksiyonlar. gmdate() işlevi normalde bize GMT zamanını verir, ancak time() GMT + N veya GMT-N alabildiğimiz gibi, herhangi bir GMT saat dilimi için zaman alabileceğimiz anlamına gelir.

Örneğin, GMT + 5 için zaman ayırmanız gerekiyorsa bunu aşağıdaki gibi yapabilirsiniz:

<?php 
  $offset=5*60*60; //converting 5 hours to seconds.
  $dateFormat="d-m-Y H:i";
  $timeNdate=gmdate($dateFormat, time()+$offset);
?>

Şimdi GMT-5 için zaman ayırmanız gerekiyorsa, ofseti sadece time() GMT-4 için zaman alıyoruz aşağıdaki örnekte olduğu gibi, buna eklemek yerine

<?php 
  $offset=4*60*60; //converting 4 hours to seconds.
  $dateFormat="d-m-Y H:i"; //set the date format
  $timeNdate=gmdate($dateFormat, time()-$offset); //get GMT date - 4
?>

47
2018-05-12 07:39



Cevabınız için teşekkür ederim - drikoda
Bu iyi bir örnektir ... ama çıkarılması gereken veya gmdate süresine eklenmesi gereken zamanı nasıl bilebilirim? - shasi kanth
Bu cevap yanlış, çünkü time () işlevi sunucu yerel saatini alacaktır. UTC almaz, bu yüzden sunucu saatinin ne olduğunu bilmiyorsanız, beklenen saat dilimi saatini alamazsınız. - rram
Bu cevap eski ve tuhaf sonuçlar üretecek - Tivie
Bu, GMT ofsetini sabit kodlamanızı gerektirir. $offset=5*60*60 kodu. Özellikle gün ışığı tasarruflarını veya zaman dilimlerini kapsayan sunucu kümelerini hesaba katmanız gerekiyorsa, ideal değildir. - Mark


İsterim şiddetle Farklı bir saat dilimine benzemesini sağlamak için UNIX zaman damgalarıyla uğraşmaktan kaçınmanızı öneririz. Bu, zor yoldan öğrendiğim bir ders, çok fazla zaman.

Bir zaman damgası 1 Ocak 1970, GMT Gece Yarısından bu yana geçen saniye sayısıdır. Dünyanın neresinde olursanız olun, belirli bir zaman damgası, zaman dilimlerinden bağımsız olarak, tam olarak aynı anı temsil eder. Evet, zaman damgası "0" Avustralya'da 10 am 1/1/70, Londra'da 1/1/70 ve LA'da 5 / 31/12/69 anlamına gelir, ancak bu sadece değer ekleyip çıkarabileceğiniz anlamına gelmez doğruluk.

Beni her yıl çok uzun zamandır dolduran altın örnek, gün ışığından yararlanmaların mahsuplaşacağı zamandı. Gün ışığından yararlanma, dünyanın belirli bölgelerinde mevcut olmayan "saat zamanları" anlamına gelir. Örneğin, ABD'nin çoğu bölgesinde, 2 Nisan 2006'da saat 02:01 gibi bir zaman yoktu.

Yeterince yarı anlaşılabilir rant olsa da. Tavsiyem, tarihlerini veritabanında zaman damgaları olarak saklamak ve sonra ...

Örneğin,

$timestamp = time();

echo "BRISBANE: " . date('r', $timestamp) . "\n";
echo "     UTC: " . gmdate('r', $timestamp) . "\n";
date_default_timezone_set('Africa/Johannesburg');
echo "  JOBURG: " . date('r', $timestamp) . "\n";

// BRISBANE: Tue, 12 May 2009 18:28:20 +1000
//      UTC: Tue, 12 May 2009 08:28:20 +0000
//   JOBURG: Tue, 12 May 2009 10:28:20 +0200

Bu, değerlerinizi temiz tutacaktır (ofsetlerin eklenmesi konusunda endişelenmenize gerek kalmaz ve kaydetmeden önce çıkarmanız gerekmez), tüm Gün Işığı Tasarruf kurallarına saygı gösterir ve ayrıca yerin saat dilimini de aramak zorunda kalmazsınız. İstediğiniz.


68
2018-05-12 08:32



"En azından zaman dilimi ofseti değişene kadar, ister Yaz Saati ne olursa olsun, ne olursa olsun." ... ve benim çözümümün cesaretini mi arıyorsun? - nickf
"bu yeteneğe sahip bir PHP kütüphanesi" - yerleşik. "politikacılar kuralları değiştirirse" - iyi: kodunuzun herhangi birini değiştirmek zorunda kalmazsınız - PHP güncellenirse, o zaman sadece çalışır. “Yerel tarihi alan başka bir kodunuz varsa” - durulayın ve tekrarlayın. - nickf
Nickf çok doğru acıyor. Zaman dilimi ofset hesaplamalarını kendiniz yapmaktan kaçınmak için bir kütüphane veya işletim sistemi çağrısı, HERHANGİ BİR İHTİME'ye güvenmek istiyorsunuz. Nickf'e benzer şekilde, bunu da zor yoldan öğrendim. - Mike Chamberlain
Burası burası! Bu sorunu ele alan herkes bu çözümü kullanmalıdır. Her iki cevap da iyi ama bu ikisi daha iyi. Sadece n3wbs karıştırabileceği için yanlış bir çözüm yapmaz. Teşekkürler Nickf! Yan not: nickf, 78k'ya sahip ve p01nd3xt3r 62'ye sahip. Bu, hem kullanıcılar hem de masaya ne getirdikleri hakkında çok şey söylüyor. - Max Felker
@ J.Bruni tam olarak sorun neydi? Hemen hemen her programlama dili (artı bildiğim her SQL uygulaması), bir zaman damgasını tarih ve saate dönüştürmek için yerleşik yöntemlere sahiptir. - nickf


Tarihin ('Z') ikinci bir argüman olarak zaman damgasını tarih verdiğiniz bir veritabanında depolanan bir tarihi dönüştürmek için kullanıyorsanız, aksi takdirde sonuçlarınızın doğru olmayacağını unutmayın.

Örneğin.

İngiltere'de, bazen tarih ('Z') 3600 verecek, bazen 0 verecektir.

echo date('Z', strtotime('2012-01-01'));

0 verir

echo date('Z', strtotime('2012-07-01'));

3600 verir

Yani sadece strtotime ($ dbDateValue) - tarih ('Z') kullanarak yanlış olabilir

Yerine kullanmak:

$dbDateTimestamp = strtotime($dbDateValue); // where $dbDateValue something like 2012-01-01 22:34:00

$utcTimestamp = strtotime($dbDateTimestamp) - date('Z', $dbDateTimestamp);

Bu elbette PHP'ye ve veritabanına her ikisi de aynı zaman dilimi için ayarlanmış.


4
2017-07-12 11:32





İşte GMT'den farklı saat dilimlerinin listesi, umarım bu yardımcı olur!

echo '<pre>';
$zones_array = array();        
$timestamp = time();         
# to maintain the original timezone, store before
$default_timezone = date_default_timezone_get();
foreach (timezone_identifiers_list() as $key => $zone) {    
    date_default_timezone_set($zone);
    $zones_array[$key]['zone'] = $zone;
    $zones_array[$key]['diff_from_GMT'] = date('P', $timestamp);
}
# to maintain the original timezone, re-set after
date_default_timezone_set($default_timezone);    
print_r($zones_array);

Teşekkürler!


3
2018-02-17 13:06



Kullanıcılar düzenlemeleri reddediyor mu, yoksa yalnızca spam onaylayan kişiler mi? Ben ... "Bu düzenleme yanlış veya varolan gönderiye yanıt vermek veya yorum yapmak için bir girişim" şeklinde olurdu. - ficuscr
Kusuru görmüyorum, belli olabilir misin? - Vitor Tyburski
Gördün mü? Bazı anlayışları araştırıyordum ve bunu görmeyi bıraktım ve düzeltmenin en iyisi olduğunu düşündüm. Yani, sadece dikkat çekmek istediğimi söylüyorsun. Çözüm için olsaydı ... Peki açıklayabilir misin? Öğrenmekten mutlu olurum ... - Vitor Tyburski


Bu sorudan, zaman damgasını ihtiyaç duyulan bir zaman dilimini dönüştürmek için alternatif bir işlev yazmaktan ilham aldım.

Bu nedenle, DOĞRU prosedürü kayıt, görüntüleme (dönüştürme) süresini adım:

1) record timestamp with time()
2) If you need to get a different timezone, use:
   2.1) Class based:
       2.1.1) DateTime class + setTimezone
       or
       2.1.2) date_default_timezone_set() and then date()

       2.1.1) is better and more flexible than 2.1.2)

    Function:

      function getLTime_class($ts, $uTZ, $format_str="Y.m.d H:i", $sTZ="America/Toronto"){
        // $ts - timestamp recorded with time(); if have date => convert to timestamp: strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone);
        // $uTZ - TZ string (ex: 'America/Toronto'); convert timestamp to this TimeZone
        // $sTZ - TZ string (ex: 'America/Toronto'); convert timestamp from this TimeZone
        $TimeZone_server=new DateTimeZone($sTZ);
        $date_obj=new DateTime("@$ts", $TimeZone_server);
        $TimeZone_local=new DateTimeZone($uTZ);
        $date_obj->setTimeZone($TimeZone_local);
        return $date_obj->format($format_str);
      }

    Usage:

     $date_input=$_POST['date_input']; //read from POST
     $ts=strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone);
     $userTZ='America/Toronto'; //read from user params
     $result=getLTime_class($ts, $userTZ, 'Y-m-d H:i:s');


   2.2) Non-Class based:

Function:

      //this function replaces the function with DateTime class. It's faster. $uTZoffset is integer.
      function getLTime_nonclass($ts, $uTZoffset, $format_str="Y.m.d H:i"){
        // $ts - timestamp recorded with time(); if have date => convert to timestamp: strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone);
        // $uTZoffset - TZ offset (integer) $uTZoffset must consider DTS (for ex: in summer $uTZoffset=-4; in winter $uTZoffset=-5)
        $ts_offset=date('Z',$ts);
        if ($uTZoffset) $add_offset=$ts_offset-date('Z'); //when not UTC
        else $add_offset=0; //when UTC
        return date($format_str,$ts-$ts_offset+$uTZoffset*3600+$add_offset);
      }

    Usage:

     $date_input=$_POST['date_input']; //read from POST
     $ts=strtotime($date_input); //for ex strtotime('2012-02-17 12:00:00'); => 1345219200 - same value for summer and winter (for toronto timezone);
     $uTZoffset=-4; //read from user params. $uTZoffset - TZ offset (integer) $uTZoffset must consider DTS (for ex: in summer $uTZoffset=-4; in winter $uTZoffset=-5)
     $result=getLTime_nonclass($ts, $uTZoffset, 'Y-m-d H:i:s');

Sonuçlar:

$ date_input = 2012-08-17 12:00:00

Server date: summer (2013-08-26)
    getLTime_class      =>  $userTZ='America/Toronto'   =>  2012-08-17 12:00:00
    getLTime_nonclass   =>  $uTZoffset=-4               =>  2012-08-17 12:00:00
    getLTime_class      =>  $userTZ='UTC'               =>  2012-08-17 16:00:00
    getLTime_nonclass   =>  $uTZoffset=0                =>  2012-08-17 16:00:00

Server date: winter (2013-02-26)
    getLTime_class      =>  $userTZ='America/Toronto'   =>  2012-08-17 12:00:00
    getLTime_nonclass   =>  $uTZoffset=-5               =>  2012-08-17 12:00:00
    getLTime_class      =>  $userTZ='UTC'               =>  2012-08-17 16:00:00
    getLTime_nonclass   =>  $uTZoffset=0                =>  2012-08-17 16:00:00

$ date_input = 2012-02-17 12:00:00

Server date: summer (2013-08-26)
    getLTime_class      =>  $userTZ='America/Toronto'   =>  2012-02-17 12:00:00
    getLTime_nonclass   =>  $uTZoffset=-4               =>  2012-02-17 12:00:00
    getLTime_class      =>  $userTZ='UTC'               =>  2012-02-17 17:00:00
    getLTime_nonclass   =>  $uTZoffset=0                =>  2012-02-17 17:00:00

Server date: winter (2013-02-26)    
    getLTime_class      =>  $userTZ='America/Toronto'   =>  2012-02-17 12:00:00
    getLTime_nonclass   =>  $uTZoffset=-5               =>  2012-02-17 12:00:00
    getLTime_class      =>  $userTZ='UTC'               =>  2012-02-17 17:00:00
    getLTime_nonclass   =>  $uTZoffset=0                =>  2012-02-17 17:00:00 

LTime_nonclass'ın, dönüşümleri derslerden daha hızlı hale getirmeyi umuyordum. Tek istediğim getLTime_nonclass'ın getLTime_class için geçerli bir yedek olduğunu doğrulamak. Lütfen fikrinizi ifade etmek için çekinmeyin. Teşekkürler


1
2017-08-26 19:48





GMT + 0'da DB'de gerekli kayıt zamanı olduğunda çok fazla zaman var, ancak işlev zamanı () sunucunun zamanını döndürecektir. Bir sonraki işlevle olası çözümü:

/**
     * Converts a local Unix timestamp to GMT
     *
     * @param   int Unix timestamp
     * @return  int
     */
    function local_to_gmt($time = '')
    {
        if ($time === '')
        {
            $time = time();
        }

        return mktime(
            gmdate('G', $time),
            gmdate('i', $time),
            gmdate('s', $time),
            gmdate('n', $time),
            gmdate('j', $time),
            gmdate('Y', $time)
        );
    }

0
2018-05-24 14:18