it-swarm.com.de

Wie zeige ich ein Datum in der richtigen Zeitzone?

Ich habe ein Datetime Range-Feld (field_date) in einem Inhaltstyp. Sobald ich meinen Inhaltstyp erstellt habe, lege ich das Startdatum wie folgt fest:

2017-02-27 19:30:01

(enter image description here

Jetzt möchte ich den Wert abrufen und das Datum in einem anderen Format anzeigen. Versuchen Sie daher, den folgenden Code zu verwenden:

// Loading the node.
$node = Node::load(2100);
// Getting the start date value.
$date = $node->field_date->value;
// Printing to see what is the output.
dpm($node->field_date->value);
$date = strtotime($date);
// Printing my timezone.
dpm(drupal_get_user_timezone());
// Applying my custom format.
$date = \Drupal::service('date.formatter')->format($date, 'custom', 'Y-m-d H:i:s', drupal_get_user_timezone());
// Printing to see the output.
dpm($date);

Dies ist meine Ausgabe:

// It's fine.
2017-02-28T00:30:01
// Its fine.
America/New_York
// This is not what I waiting for. I'm waiting here: 2017-02-27 19:30:01
2017-02-28 00:30:01

Wie kann man ein Datum in der richtigen Zeitzone anzeigen?

20

Ich vermute, das Problem hat mit einigen Nuancen von strtotime() zu tun.

strtotime() kann nahezu jede Zeichenfolge in einen Unix-Zeitstempel konvertieren. Das Problem ist, dass, wenn die Zeichenfolge keine explizite Zeitzone enthält, das verwendet wird, was durch date_default_timezone_get() festgelegt wird. Dies sollte jedoch vom aktuellen Benutzer festgelegt werden (dies wird vom Konto-Proxy festgelegt). Die Zeichenfolge, die Sie aus $node->field_date->value Herausziehen, befindet sich jedoch implizit in UTC. Mit anderen Worten, ich denke, die Zeichenfolge wird analysiert, indem strtotime() wie in 'America/New_York' und nicht in 'UTC' interpretiert wird.

Die gute Nachricht ist, dass Sie Ihre Situation erheblich vereinfachen können. Das Feldelement für einen Datumsbereich besteht aus vier Teilen

  • 'Wert' ist das Startdatum als Zeichenfolge in UTC
  • 'start_date' ist ein DrupalDateTime-Objekt, das 'value' darstellt.
  • 'end_value' ist das Enddatum als Zeichenfolge in UTC
  • 'end_date' ist ein DrupalDateTime-Objekt, das 'end_value' darstellt.

Für ein einfaches Datums- und Uhrzeitfeld sind sie

  • 'Wert' ist das Datum als Zeichenfolge in UTC
  • 'date' ist ein DrupalDateTime-Objekt, das 'value' darstellt.

Sie können also direkt mit dem Objekt DrupalDateTime() arbeiten. Darüber hinaus sollte dieser date.formatter - Dienst die richtige Zeitzone abrufen, die vom Benutzer verwendet wird, der die Seite standardmäßig anzeigt (zusätzlich zur Verwendung der aktiven Sprache des Benutzers).

Ich vermute, dass so etwas funktionieren wird

$node = Node::load(2100);
$start_date = $node->field_date->start_date;
$formatted = \Drupal::service('date.formatter')->format(
  $start_date->getTimestamp(), 'custom', 'Y-m-d H:i:s P'
);

Hinweis Ich habe dort den Platzhalter im P-Format hinzugefügt, damit Sie sehen können, welche Zeitzone das System für verwendet hält.

Stellen Sie sicher, dass Sie unter admin/config/regional/settings die richtige Zeitzone eingerichtet haben und dass Ihre Benutzerzeitzone Ihren Erwartungen entspricht. Stellen Sie außerdem sicher, dass in Ihrer php.ini die richtige Zeitzone eingestellt ist (dies ist die Einstellung date.timezone). Seltsame Dinge passieren, wenn dies nicht festgelegt ist (und ich kann mich nicht erinnern, ob dies eine Warnung im Installationsprogramm oder im Statusbericht verursacht, wenn es nicht festgelegt ist. Ich erinnere mich an das Problem, aber nicht daran, ob es aufgetreten ist engagiert sein).

24
mpdonadio

Basierend auf Behandlung der Zeitzonenkonvertierung mit PHP DateTime Ich habe meinen Code folgendermaßen geändert:

$node = Node::load(2100);
$userTimezone = new DateTimeZone(drupal_get_user_timezone());
$gmtTimezone = new DateTimeZone('GMT');
$myDateTime = new DateTime($node->field_date->value, $gmtTimezone);
$offset = $userTimezone->getOffset($myDateTime);
$myInterval = DateInterval::createFromDateString((string)$offset . 'seconds');
$myDateTime->add($myInterval);
$result = $myDateTime->format('Y-m-d H:i:s');
dpm($result);

Und jetzt ist mein Ausgabedatum in Ordnung:

2017-02-27 19:30:01

Das funktioniert. Ich bin mir jedoch sicher, dass es eine Möglichkeit gibt, dies mit der API Drupal API) zu tun.

6

Normalerweise löse ich es so:

node = Node::load(1);    
$date_original= new DrupalDateTime( $node->field_date->value , 'UTC' );     
$result = \Drupal::service('date.formatter')->format( $date_original->getTimestamp(), 'custom', 'Y-m-d H:i:s'  );    
dpm( $result );
4
Ytacol

Das hat bei mir funktioniert:

// Take the timestamp.
$timestamp = $form_state->getValue($form_field)->getTimestamp();
// Convert to UTC - the way its saved in database.
$date = DrupalDateTime::createFromTimestamp($timestamp, 'UTC');
// Add on the current entity.
$this->entity->{$db_field}->value = $date->format("Y-m-d\TH:i:s");
2
Dan Poenaru

Dieser Code funktioniert für mich.

// set use timezone
userTimezone = new DateTimeZone(drupal_get_user_timezone());
// set gmt timezone
$gmtTimezone = new DateTimeZone('GMT');
// Take the timestamp.
$start_date = $val['field_start_time_value'];    
$startDateTime = new DateTime($start_date, $gmtTimezone);
$offset = $userTimezone->getOffset($startDateTime);
$startInterval = DateInterval::createFromDateString((string)$offset . 'seconds');
$startDateTime->add($startInterval);
$result = $startDateTime->format('Y-m-d H:i:s');
1
Arun Mishra

Ich benutze dieses Snippet, um mit Daten zu arbeiten:

<?php
class MyApp extends ControllerBase
{
    public function output() 
    {
        $dtime = DateTime::createFromFormat("d/m/Y - H:I:s", "22/12/1999 - 22:55:12", $this->getDateTimeZone());
        $time = $dtime->format('r');
        // My code goes here
    }

    private function getDateTimeZone()
    {
        return new DateTimeZone(drupal_get_user_timezone());
    }
}

Weitere Informationen zu dem Datetime-Objekt hier

0
Ben Cassinat

Keine dieser anderen Antworten hat bei mir funktioniert. Dies ist, was ich schließlich endete:

$range_start = DrupalDatetime::createFromTimestamp((int)$start_date); // unix timestamp
$range_start->setTimezone(new \Datetimezone('EST'));
$node->field_date_range->value = format_date(
  $range_start->getTimestamp() , 'custom', 'Y-m-d\TH:i:s', 'EST');
0
user1359