コンテンツタイプに日時範囲フィールド(field_date)があります。コンテンツタイプを作成したら、開始日を次のように設定します。
2017-02-27 19:30:01
次に、値を取得して日付を別の形式で表示したいので、次のコードを使用してみます。
// 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);
これは私の出力です:
// 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
では、正しいタイムゾーンで日付を表示するにはどうすればよいですか?
問題は strtotime()
のニュアンスの一部に関係しているのではないかと思います。
strtotime()
は、ほぼすべての文字列を取り、それをUnixタイムスタンプに変換できます。問題は、文字列に明示的なタイムゾーンが含まれていない場合、文字列は date_default_timezone_get()
によって設定されたものを使用することです。ただし、現在のユーザーから設定する必要があります(アカウントプロキシによって設定されます)。ただし、_$node->field_date->value
_から引き出している文字列は、暗黙的にUTCにあります。つまり、文字列はstrtotime()
によって解析されていると思います。これは、 'UTC'ではなく 'America/New_York'として解釈されているためです。
良いニュースは、状況を大幅に簡素化できることです。日付範囲のフィールドアイテムは4つの部分で構成されます
プレーンな日付時刻フィールドの場合、
したがって、 DrupalDateTime()
オブジェクトを直接操作できます。さらに、その_date.formatter
_サービスは、(ユーザーのアクティブな言語の使用に加えて)デフォルトでページを表示しているユーザーが使用している適切なタイムゾーンを取得する必要があります。
このようなものがうまくいくと思います
_$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'
);
_
ここに「P」形式のプレースホルダーを追加したので、システムがどのタイムゾーンを使用していると考えているかを確認できます。
Admin/config/regional/settingsで適切なタイムゾーンが設定されていること、およびユーザーのタイムゾーンが想定どおりであることを確認してください。また、php.iniに適切なタイムゾーンが設定されていることを確認してください(これは_date.timezone
_設定です)。これが設定されていないときに奇妙なことが起こります(そして、頭から離れて、それが設定されていないときにインストーラーまたはステータスレポートに警告を引き起こしたかどうか覚えていません。問題を覚えていますが、それが関与する)。
に基づいてPHP DateTime でタイムゾーン変換を処理します。コードを次のように変更しました:
$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);
そして今私の出力日はそれでいいです:
2017-02-27 19:30:01
これは機能します。しかし、Drupal APIを使用してこれを行う方法があると確信しています。
私は通常、この方法で解決します。:
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 );
これは私のために働きました:
// 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");
このコードは私のために働いています。
// 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');
私はこのスニペットを使用して日付を操作します:
<?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());
}
}
これらの他の答えはどれも私にとってうまくいきませんでした。これは最終的に私が終わったものです:
$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');