web-dev-qa-db-ja.com

D6ユーザータイムゾーンオフセットをD7タイムゾーン文字列に変換する

Drupal 6ユーザーのタイムゾーンが-3600などの2番目のオフセットとして保存されます。= Drupal 7の場合、タイムゾーン文字列です。例:Europe /Berlin。Iユーザーのタイムゾーン設定をD7に移行しますが、タイムゾーンオフセットを文字列に変換する方法は明らかではありません。

私の現在の解決策は、タイムゾーン文字列から構築された完全なマッピングテーブルを作成することですが、それが最もエレガントではないと確信しています。

$d6_offset = -3600; // Input.
$zones = timezone_identifiers_list();
foreach ($zones as $zone) {
  $offset = format_date(time(), 'custom', 'Z', $zone);
  if (!isset($map[$offset])) {
    $map[$offset] = $zone;
  }
}
$d7_timezone = $map[$d6_offset]; // Output.

より良いワークフローを知っていますか?

2
itarato

次のコードを使用します。

_$map = array();

foreach (timezone_identifiers_list() as $zone) {
  if ($timezone = timezone_open($zone)) {
    if ($datetime = date_create("now", $timezone)) {
      if (($offset = $timezone->getOffset($datetime)) !== FALSE && !isset($map[$offset])) {
        $map[$offset][] = $zone;
      }
    }
  }
}
_

同じオフセットが異なるタイムゾーン識別に使用されることに注意してください。各オフセットの識別子のみを表示することは、ユーザーにとってあまり役に立ちません。

たとえば、ヨーロッパの場合、次のリストを表示します。 (リストは部分的です。)

  • ヨーロッパ/アムステルダム7200
  • ヨーロッパ/アテネ10800
  • ヨーロッパ/ダブリン3600

リストには、ヨーロッパ/ローマ、ヨーロッパ/マドリード、ヨーロッパ/マルタ、ヨーロッパ/キエフは表示されません。これは、表示した3つのエントリにオフセットがすでに使用されているためです。

より良いコードは次のようになります。

_function mymodule_get_timezones() {
  $map = &drupal_static(__FUNCTION__);

  if (isset($map)) {
    return $map;
  }

  foreach (timezone_identifiers_list() as $zone) {
    if ($timezone = timezone_open($zone)) {
      if ($datetime = date_create("now", $timezone)) {
        if (($offset = $timezone->getOffset($datetime)) !== FALSE && !isset($map[$offset])) {
          $map[$offset][] = $zone;
        }
      }
    }
  }

  return $map;
}
_

ちなみに、日付の形式として「カスタム」を使用している場合、私はformat_date()を使用しません。また、返された日付の翻訳には興味がありません。そのような場合、 format_date() から実行される次のコードは余分であり、役に立たない。

_  // Encode markers that should be translated. 'A' becomes '\xEF\AA\xFF'.
  // xEF and xFF are invalid UTF-8 sequences, and we assume they are not in the
  // input string.
  // Paired backslashes are isolated to prevent errors in read-ahead evaluation.
  // The read-ahead expression ensures that A matches, but not \A.
  $format = preg_replace(array('/\\\\\\\\/', '/(?<!\\\\)([AaeDlMTF])/'), array("\xEF\\\\\\\\\xFF", "\xEF\\\\\$1\$1\xFF"), $format);

  // Call date_format().
  $format = date_format($date_time, $format);

  // Pass the langcode to _format_date_callback().
  _format_date_callback(NULL, $langcode);

  // Translate the marked sequences.
  return preg_replace_callback('/\xEF([AaeDlMTF]?)(.*?)\xFF/', '_format_date_callback', $format);
_

私が説明した場合、そのコードは次のコードに置き換えることができます。

_return date_format($date_time, $format);
_
1
kiamlaluno