php tarih saatini UTC'ye çevirir


90

Herhangi bir kitaplık kullanmadan HİÇBİR ŞEKİLDE bir tarih zaman damgasını UTC'ye (sunucunun bulunduğu saat diliminden) dönüştürmek için kolay bir yola ihtiyacım var.

Yanıtlar:


30

GetTimezone ve setTimezone deneyin, örneğe bakın

(Ama bu bir Sınıf kullanıyor)

GÜNCELLEME:

Herhangi bir ders olmadan şöyle bir şey deneyebilirsiniz:

$the_date = strtotime("2010-01-19 00:00:00");
echo(date_default_timezone_get() . "<br />");
echo(date("Y-d-mTG:i:sz",$the_date) . "<br />");
echo(date_default_timezone_set("UTC") . "<br />");
echo(date("Y-d-mTG:i:sz", $the_date) . "<br />");

NOT: Saat dilimini de orijinaline geri ayarlamanız gerekebilir.


56
gmdateVarsayılan saat dilimini UTC olarak değiştirmek yerine kullanmalısınız . Çünkü gmdateotomatik olarak UTC kullanır.
dürtmek

30
-1 çünkü bunun için genel varsayılan saat dilimini değiştirmek istemezsiniz. Sadece istenmeyen yan etkiler ister.
Ward Bekker

@Phill Burada 'sz' nedir?
Shahid Karimi

2
Sanırım "Yd-mTG ..." yerine "Ym-dTG ..." olmalı
Alex Angelico

Laravel projesinde benim için çalışmıyor. Aynı tarihte dönüşü
Dharmender Tuli

109

Verilen dizeden (yerel saat olarak yorumlanan) bir zaman damgası oluşturmak için strtotime'ı kullanın ve bunu, UTC tarihi geri biçimlendirilmiş olarak almak için gmdate kullanın.

Misal

İstendiği gibi, işte basit bir örnek:

echo gmdate('d.m.Y H:i', strtotime('2012-06-28 23:55'));

2
@cherouvim Gerekli olduğunu düşünmüyorum, ama yine de bir tane ekledi… Umarım yardımcı olur.
dürtmek

5
gmdate (), uzun zaman önce tökezlemiş olmayı dilediğim PHP işlevlerinden biridir. nl2br, kimse?
Charlie Schliesser

1
GMT ve UTC her zaman aynı değildir.
Jay Sheth

@JaySheth Pratik olarak, UTC ve GMT eşanlamlıdır.
dürtmek

1
@poke GMT gün ışığından yararlanma saatine saygı duyar, UTC buna saygı göstermez ve bu yüzden kullanılır, bu yüzden başka hiçbir şeyi hesaba katmanız gerekmez
Necro

72

DateTime kullanarak:

$given = new DateTime("2014-12-12 14:18:00");
echo $given->format("Y-m-d H:i:s e") . "\n"; // 2014-12-12 14:18:00 Asia/Bangkok

$given->setTimezone(new DateTimeZone("UTC"));
echo $given->format("Y-m-d H:i:s e") . "\n"; // 2014-12-12 07:18:00 UTC

Soru, bir zaman damgasını bir zaman damgasına dönüştürdüğünü ve DateTime'ın giriş olarak bir zaman damgasını kabul etmediğini söylüyor. Onu bir şekilde bir dizeye dönüştürmeniz ve sonra geri dönüştürmeniz gerekir.
felwithe


14

YYYY-MM-HH dd: mm: ss biçiminde bir tarihiniz varsa, php'yi "datetime dizgenizin" sonuna bir UTC ekleyerek kandırabilir ve dönüştürmek için strtotime'ı kullanabilirsiniz.

date_default_timezone_set('Europe/Stockholm');
print date('Y-m-d H:i:s',strtotime("2009-01-01 12:00"." UTC"))."\n";
print date('Y-m-d H:i:s',strtotime("2009-06-01 12:00"." UTC"))."\n";

Bu şunu yazdıracaktır:

2009-01-01 13:00:00
2009-06-01 14:00:00

Ve gördüğünüz gibi gün ışığından yararlanma saati sorununu da hallediyor.

Çözmenin biraz tuhaf yolu .... :)


OP'nin neden önerinizi :D
seçmediğini

@php_nub_qq muhtemelen tüm komut dosyası için zaman dilimini değiştirerek çalıştığından, istenmeyebilir ve istenmeyen sonuçlara yol açabilir.
felwithe

@felwithe Sadece gösteri amaçlı olan ilk satırı
atlasanız olmaz

11

Yerel saat dilimi dizesini UTC dizesine dönüştürün.
örneğin Yeni Zelanda Saat Dilimi

$datetime = "2016-02-01 00:00:01";
$given = new DateTime($datetime, new DateTimeZone("Pacific/Auckland"));
$given->setTimezone(new DateTimeZone("UTC"));
$output = $given->format("Y-m-d H:i:s"); 
echo ($output);
  • NZDT: UTC + 13: 00
    eğer $ datetime = "2016-02-01 00:00:01", $ output = "2016-01-31 11:00:01";
    $ datetime = "2016-02-29 23:59:59" ise, $ output = "2016-02-29 10:59:59";
  • NZST: UTC + 12: 00
    , $ datetime = "2016-05-01 00:00:01", $ output = "2016-04-30 12:00:01";
    $ datetime = "2016-05-31 23:59:59" ise, $ output = "2016-05-31 11:59:59";

https://en.wikipedia.org/wiki/Time_in_New_Zealand


6

PHP 5.2.0'dan beri mevcut olan PHP'nin DateTime sınıfını kullanmaktan çekinmiyorsanız, durumunuza uyan birkaç senaryo vardır:

  1. $givenDtUTC'ye dönüştürmek istediğiniz bir DateTime nesneniz varsa, bu onu UTC'ye dönüştürecektir:

    $givenDt->setTimezone(new DateTimeZone('UTC'));
    
  2. Orijinale $givenDtdaha sonra ihtiyaç duyarsanız, alternatif olarak, klonlanan nesneyi dönüştürmeden önce belirli DateTime nesnesini klonlamak isteyebilirsiniz:

    $utcDt = clone $givenDt;
    $utcDt->setTimezone(new DateTimeZone('UTC'));
    
  3. Yalnızca bir tarih saat dizeniz varsa, örneğin $givenStr = '2018-12-17 10:47:12', önce bir tarih saat nesnesi oluşturursunuz ve sonra onu dönüştürürsünüz. Bunun $givenStrPHP'nin yapılandırılmış zaman diliminde olduğunu varsaydığına dikkat edin .

    $utcDt = (new DateTime($givenStr))->setTimezone(new DateTimeZone('UTC'));
    
  4. Verilen tarih saat dizesi PHP yapılandırmanızdakinden farklı bir zaman dilimindeyse, doğru saat dilimini sağlayarak tarih saat nesnesini oluşturun ( PHP'nin desteklediği saat dilimlerinin listesine bakın ). Bu örnekte, Amsterdam'daki yerel saat dilimini varsayıyoruz:

    $givenDt = new DateTime($givenStr, new DateTimeZone('Europe/Amsterdam'));
    $givenDt->setTimezone(new DateTimeZone('UTC'));
    

4

Olarak strtotime belirli giriş biçimi gerektirir DateTime :: createFromFormat kullanılabilir ( php 5.3+ gereklidir )

// set timezone to user timezone
date_default_timezone_set($str_user_timezone);

// create date object using any given format
$date = DateTime::createFromFormat($str_user_dateformat, $str_user_datetime);

// convert given datetime to safe format for strtotime
$str_user_datetime = $date->format('Y-m-d H:i:s');

// convert to UTC
$str_UTC_datetime = gmdate($str_server_dateformat, strtotime($str_user_datetime));

// return timezone to server default
date_default_timezone_set($str_server_timezone);

4

Bazen bu yöntemi kullanıyorum:

// It is not importnat what timezone your system is set to.
// Get the UTC offset in seconds:
$offset = date("Z");

// Then subtract if from your original timestamp:
$utc_time = date("Y-m-d H:i:s", strtotime($original_time." -".$offset." Seconds"));

Çalışır bütün EN zaman.


3
Burada iki sorun var. Öncelikle çıkarmamalısınız ofseti eklemelisiniz. İkinci olarak, yerel saat dilimi şu anda DST'deyse ve istenen tarih DST'de değilse bu işe yaramaz. Dengeleme bir saat farkla kaybolur. Ya da tam tersi. Yani evet, bu Çoğunlukla işe yarıyor, ama her zaman değil.
ajon



0

Deneyin

yankı tarihi ('F g E', strtotime ('2010-01-19 00:00:00'));

çıktı:

19 Ocak 2010

diğer çıktıları görmek için format zamanını değiştirmelisiniz


0

Herhangi bir saat diliminden diğerine herhangi bir zaman damgasını biçimlendirmek için genel amaçlı normalleştirme işlevi. İlişkisel bir veritabanında farklı zaman dilimlerindeki kullanıcıların tarih damgalarını depolamak için çok kullanışlıdır. Veritabanı karşılaştırmaları için zaman damgasını UTC olarak saklayın vegmdate('Y-m-d H:i:s')

/**
 * Convert Datetime from any given olsonzone to other.
 * @return datetime in user specified format
 */

function datetimeconv($datetime, $from, $to)
{
    try {
        if ($from['localeFormat'] != 'Y-m-d H:i:s') {
            $datetime = DateTime::createFromFormat($from['localeFormat'], $datetime)->format('Y-m-d H:i:s');
        }
        $datetime = new DateTime($datetime, new DateTimeZone($from['olsonZone']));
        $datetime->setTimeZone(new DateTimeZone($to['olsonZone']));
        return $datetime->format($to['localeFormat']);
    } catch (\Exception $e) {
        return null;
    }
}

Kullanım:

$from = ['localeFormat' => "d/m/Y H:i A", 'olsonZone' => 'Asia/Calcutta'];

$to = ['localeFormat' => "Y-m-d H:i:s", 'olsonZone' => 'UTC'];

datetimeconv("14/05/1986 10:45 PM", $from, $to); // returns "1986-05-14 17:15:00"

0

alternatif olarak şunu deneyebilirsiniz:

<?php echo (new DateTime("now", new DateTimeZone('Asia/Singapore')))->format("Y-m-d H:i:s e"); ?>

bu çıktı:

2017-10-25 17:13:20 Asya / Singapur

Yalnızca salt okunur bir tarihi görüntülemek istiyorsanız, bunu bir metin giriş kutusunun değer özelliği içinde kullanabilirsiniz.

Bölgenizi / ülkenizi göstermek istemiyorsanız 'e'yi kaldırın.


0

Almak için aşağıdaki adımları izleyin UTC zamanı arasında herhangi diliminin kullanıcının yerel sistemde set (web uygulamaları UTC farklı saat dilimleri kaydetmek için bu gerekli olacaktır):

  1. Javascript (istemci tarafı):

    var dateVar = new Date();
    var offset = dateVar.getTimezoneOffset();
    //getTimezoneOffset - returns the timezone difference between UTC and Local Time
    document.cookie = "offset="+offset;
    
  2. Php (sunucu tarafı):

    public function convert_utc_time($date)
    {
        $time_difference = isset($_COOKIE['offset'])?$_COOKIE['offset']:'';
        if($time_difference != ''){
            $time = strtotime($date);
            $time = $time + ($time_difference*60); //minutes * 60 seconds
            $date = date("Y-m-d H:i:s", $time);
        } //on failure of js, default timezone is set as UTC below
        return $date;
    }
    ..
    ..
    //in my function
    $timezone = 'UTC';
    $date = $this->convert_utc_time($post_date); //$post_date('Y-m-d H:i:s')
    echo strtotime($date. ' '. $timezone)
    

-1

Phill Pafford'un cevabında bir gelişme olarak ('Yd-mTG: i: sz' ifadesini anlamadım ve saat dilimine geri dönmeyi önerdi). Bu yüzden bunu öneriyorum (HMTL formatını düz / metin olarak değiştirerek karmaşık hale getirdim ...):

<?php
header('content-type: text/plain;');
$my_timestamp = strtotime("2010-01-19 00:00:00");

// stores timezone
$my_timezone = date_default_timezone_get();
echo date(DATE_ATOM, $my_timestamp)."\t ($my_timezone date)\n";

// changes timezone
date_default_timezone_set("UTC");
echo date("Y-m-d\TH:i:s\Z", $my_timestamp)."\t\t (ISO8601 UTC date)\n";
echo date("Y-m-d H:i:s", $my_timestamp)."\t\t (your UTC date)\n";

// reverts change
date_default_timezone_set($my_timezone);
echo date(DATE_ATOM, $my_timestamp)."\t ($my_timezone date is back)\n"; 
?>

2
Bunun Phil'in cevabını nasıl geliştirdiğini açıklamak için cevabınızı düzenlemelisiniz . Kodda neyi değiştirdiniz ve neden daha iyi?
Cody Grey

Varsayılan PHP saat dilimini iki zaman damgasını dönüştürmek için değiştirmek işe yarayan bir hack'tir, ancak zarif bir çözüm değildir.
The Coprolal
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.