PHP Timestamp w DateTime

94

Czy wiesz, jak mogę przekonwertować to na strtotime lub podobny typ wartości, aby przejść do obiektu DateTime ?

Data, którą mam:

Mon, 12 Dec 2011 21:17:52 +0000

Co próbowałem:

$time = substr($item->pubDate, -14);
$date = substr($item->pubDate, 0, strlen($time));

$dtm = new DateTime(strtotime($time));
$dtm->setTimezone(new DateTimeZone(ADMIN_TIMEZONE));
$date = $dtm->format('D, M dS');
$time = $dtm->format('g:i a');

Powyższe nie jest poprawne. Jeśli przeglądam wiele różnych dat, wszystkie są tej samej daty.

JREAM
źródło

Odpowiedzi:

164

Nie musisz zamieniać ciągu znaków w znacznik czasu, aby utworzyć DateTimeobiekt (w rzeczywistości jego konstruktor nawet nie pozwala ci tego zrobić, jak możesz to stwierdzić). Możesz po prostu wprowadzić swój ciąg daty do DateTimekonstruktora tak, jak jest:

// Assuming $item->pubDate is "Mon, 12 Dec 2011 21:17:52 +0000"
$dt = new DateTime($item->pubDate);

Biorąc to pod uwagę, jeśli masz znacznik czasu, którego chcesz użyć zamiast ciągu, możesz to zrobić za pomocą DateTime::setTimestamp():

$timestamp = strtotime('Mon, 12 Dec 2011 21:17:52 +0000');
$dt = new DateTime();
$dt->setTimestamp($timestamp);

Edycja (07.05.2014):

I faktycznie nie był świadomy tego w momencie, ale DateTimekonstruktor robi wsparcia tworzenia instancji bezpośrednio ze znaczników czasu. Zgodnie z tą dokumentacją wszystko, co musisz zrobić, to poprzedzić znacznik czasu @znakiem:

$timestamp = strtotime('Mon, 12 Dec 2011 21:17:52 +0000');
$dt = new DateTime('@' . $timestamp);
FtDRbwLXw6
źródło
To działa świetnie. Próbowałem tego wcześniej, ale chyba nie dałem temu wystarczającej szansy !!! dzięki :))
JREAM
18
Pamiętaj o tym new DateTime('@' . $timestamp) i $dt = new DateTime(); $dt->setTimestamp($timestamp)nie zajmuj się strefami czasowymi w ten sam sposób. Zobacz moją odpowiedź @ stackoverflow.com/questions/12038558/ ..., aby uzyskać więcej informacji.
John Slegers,
43

Chociaż @drrcknlsn ma rację, twierdząc, że istnieje wiele sposobów konwersji ciągu czasu na datę i godzinę, ważne jest, aby zdać sobie sprawę, że te różne sposoby nie dotyczą stref czasowych w ten sam sposób.


Opcja 1 : DateTime('@' . $timestamp)

Rozważ następujący kod:

date_format(date_create('@'. strtotime('Mon, 12 Dec 2011 21:17:52 +0800')), 'c');

strtotimeNieco eliminuje strefy czasowej, a date_createfunkcja przyjmuje GMT ( Europe/Brussels).

W związku z tym wynik będzie następujący, bez względu na to, na którym serwerze go uruchomię:

2011-12-12T13:17:52+00:00

Opcja 2 : date_create()->setTimestamp($timestamp)

Rozważ następujący kod:

date_format(date_create()->setTimestamp(strtotime('Mon, 12 Dec 2011 21:17:52 +0800')), 'c');

Można się spodziewać, że da to taki sam wynik. Jeśli jednak wykonam ten kod z serwera belgijskiego, otrzymam następujący wynik:

2011-12-12T14:17:52+01:00

W przeciwieństwie do date_createfunkcji setTimestampmetoda zakłada strefę czasową serwera ( 'Europe/Brussels'w moim przypadku) zamiast GMT.


Jawne ustawienie strefy czasowej

Jeśli chcesz mieć pewność, że dane wyjściowe odpowiadają strefie czasowej danych wejściowych, najlepiej ustawić to jawnie.

Rozważ następujący kod:

date_format(date_create('@'. strtotime('Mon, 12 Dec 2011 21:17:52 +0800'))->setTimezone(new DateTimeZone('Asia/Hong_Kong')), 'c')

Teraz rozważ również następujący kod:

date_format(date_create()->setTimestamp(strtotime('Mon, 12 Dec 2011 21:17:52 +0800'))->setTimezone(new DateTimeZone('Asia/Hong_Kong')), 'c')

Ponieważ jawnie ustawiliśmy strefę czasową danych wyjściowych tak, aby pasowały do ​​strefy wejściowej, obie utworzą takie same (poprawne) dane wyjściowe:

2011-12-12T21:17:52+08:00
John Slegers
źródło
27

Prawdopodobnie najprostsze rozwiązanie to po prostu:

DateTime::createFromFormat('U', $timeStamp);

Gdzie „U” oznacza epokę Uniksa. Zobacz dokumentację: http://php.net/manual/en/datetime.createfromformat.php

forsberg
źródło
3
Ta metoda również ignoruje strefę czasową
Bouke Versteegh
2
@BoukeVersteegh, a który nie?
forsberg
2
@BoukeVersteegh To jest uniksowy znacznik czasu !, który uwalnia Cię od problemów ze strefami czasowymi podczas tworzenia obiektu . po prostu użyj, ->setTimezoneaby ustawić preferowaną strefę czasową, zanim zadzwonisz->format()
Księgowy م
1
@BoukeVersteegh Sprawdź tę ważną uwagę z podręcznika PHP "Parametr $ timezone i bieżąca
Księgowy م
1
Znaczniki czasu w Uniksie nie mają stref czasowych, z definicji zawsze są to UTC
the_nuts
0

to jest moje rozwiązanie:

    function changeDateTimezone($date, $from='UTC', $to='Asia/Tehran', $targetFormat="Y-m-d H:i:s")
    {
        $date = new DateTime($date, new DateTimeZone($from));
        $date->setTimeZone(new DateTimeZone($to));
        return $date->format($targetFormat);
    }
pomysłowy
źródło