web-dev-qa-db-ja.com

PHP-strtotime、タイムゾーンを指定

日付文字列があり、「2008-09-11 '。これからタイムスタンプを取得したいのですが、タイムゾーンを動的に指定する必要があります(代わりにPHP default)。

要約すると、2つの文字列があります。

$dateStr = '2008-09-11';
$timezone = 'Americas/New_York';

これのタイムスタンプを取得するにはどうすればよいですか?

編集:時刻はその日の真夜中になります。..$ dateStr = '2008-09-11 00:00:00';

50
Andy Hin
_$date = new DateTime($dateStr, new DateTimeZone($timezone));
_

$timestamp = $date->format('U');

71
salathe

PHP> 5.2(私はそれがDateTimeクラスを追加したバージョンだと思います)を実行している場合、受け入れられた答えは素晴らしいです。古いバージョンをサポートしたい場合、あなたはしたくない入力するか、機能的なアプローチを好む場合は、グローバル設定を変更しない別の方法があります:

$dateStr = '2008-09-11 00:00:00';
$timezone = 'America/New_York';
$dtUtcDate = strtotime($dateStr. ' '. $timezone);
25
krowe

これは何らかの理由で<5.2(Heaven forbid)を使用している場合に機能します。

$reset = date_default_timezone_get();
date_default_timezone_set('America/New_York');
$stamp = strtotime($dateStr);
date_default_timezone_set($reset);

ただし、5.2以上の場合は、@ salatheの回答を選択することを強くお勧めします。

16
Jonah

タイムゾーンを使用する場合は、DateTimeクラスを使用することを提案します。この場合、DateTime :: createFromFormat()関数を使用すると、次のようにセモスティングを実行できます。

$start = "2015-01-14 11:59:43";
$timezone = "America/Montreal";

$tz = new DateTimeZone($timezone);
$dt = DateTime::createFromFormat('Y-m-d H:i:s', $start, $tz);

DateTime :: createFromFormat関数に$ tzを入れると、指定した日付がどのタイムゾーンにあるかを伝えるため、別のタイムゾーンに変換する必要があるときは、次のようにします。

$start = $dt->setTimeZone(new DateTimeZone('UTC'));
4

正確な瞬間を指すときはいつでも、夏時間の影響を受けない統一された標準に従って時間を維持します。 (GMTとUTCはこの点では同等ですが、UTCという用語を使用することをお勧めします。UTCはZuluまたはZ時間とも呼ばれることに注意してください。)

代わりに、ローカル時間値を使用して時間を保持することを選択した場合は、UTCからのローカル時間オフセットを含めて、後でタイムスタンプを明確に解釈できるようにします。

場合によっては、UTC時間と同等の現地時間の両方を保存する必要があります。多くの場合、これは2つの別個のフィールドで行われますが、プラットフォームによっては、両方を単一のフィールドに格納できるdatetimeoffset型をサポートしています。

タイムスタンプを数値として保存する場合は、Unix時間を使用します。これは、1970-01-01T00:00:00Z(うるう秒を除く)以降の秒数です。より高い精度が必要な場合は、代わりにミリ秒を使用してください。この値は、タイムゾーンの調整なしで、常にUTCに基づいている必要があります。

後でタイムスタンプを変更する必要がある場合は、元のタイムゾーンIDを含めて、オフセットが記録された元の値から変更されたかどうかを判断できるようにします。

将来のイベントをスケジュールする場合、オフセットが変更されるのが一般的であるため、通常はUTCではなく現地時間が推奨されます。回答とブログ投稿をご覧ください。

タイムゾーンオフセットは常に整数時間ではないことに注意してください(たとえば、インド標準時はUTC + 05:30で、ネパールはUTC + 05:45を使用します)。

Javaを使用する場合、Java 8にJava.timeを使用するか、Java 7以下にJoda Timeを使用します。NETを使用する場合は、Noda Timeの使用を検討してください。 Noda Timeなしで.NETを使用する場合、DateTimeOffsetがDateTimeよりも適切な選択肢であると考えてください。Perlを使用する場合はDateTimeを使用します。Pythonを使用する場合はpytzまたはdateutilを使用しますPHP> 5.2を使用する場合は、DateTimeおよびDateTimeZoneクラスによって提供されるネイティブタイムゾーン変換を使用します。使用時には注意してください。

DateTimeZone :: listAbbreviations()-回答を参照してください。最新のOlsonデータでPHPを保持するには、timezonedb PECLパッケージを定期的にインストールします。回答を参照してください。

C++を使用する場合は、IANAタイムゾーンデータベースを適切に実装するライブラリを使用してください。これらには、cctz、ICU、およびHoward Hinnantの「tz」ライブラリが含まれます。

タイムゾーンの変換にBoostを使用しないでください。 APIは、標準のIANA(別名「zoneinfo」)識別子をサポートすると主張していますが、各ゾーンに加えられた変更の豊富な履歴を考慮せずに固定オフセットに大まかにマッピングします。

(また、ファイルはメンテナンスから外れました。)

ほとんどのビジネスルールでは、UTCやGMTではなく、常用時間が使用されます。したがって、アプリケーションロジックを適用する前に、UTCタイムスタンプをローカルタイムゾーンに変換することを計画してください。

タイムゾーンとオフセットは固定されておらず、変更される可能性があることに注意してください。たとえば、歴史的に米国と英国は同じ日付を使用して「春先」と「フォールバック」を行いました。

しかし、2007年に米国は時計が変更される日付を変更しました。これは、現在、1年の48週間はロンドン時間とニューヨーク時間の差が5時間であり、4週間(春は3、秋は1)が4時間であることを意味します。複数のゾーンが関係する計算では、このような項目に注意してください。

時間のタイプ(実際のイベント時間、ブロードキャスト時間、相対時間、履歴時間、繰り返し時間)を考慮して、正しい取得のために保存する必要のある要素(タイムスタンプ、タイムゾーンオフセット、タイムゾーン名)を参照してください。回答。

OS、データベース、およびアプリケーションのtzdataファイルを、それらと他の世界との間で同期させてください。

サーバーでは、ハードウェアクロックとOSクロックをローカルタイムゾーンではなくUTCに設定します。

前の箇条書きに関係なく、Webサイトを含むサーバー側のコードは、サーバーのローカルタイムゾーンが特定のものであることを決して期待すべきではありません。答えをご覧ください。

NTPすべてのサーバーのサービスを使用。

FAT32を使用する場合、タイムスタンプはUTCではなく現地時間で保存されることに注意してください。

定期的なイベント(毎週のテレビ番組など)を処理する場合、時間はDSTによって変化し、時間帯によって異なることに注意してください。

日時の値は常に、下限を含む、上限を含まない(> =、<)としてクエリします。

2
Charu

Laconic Answer(デフォルトのタイムゾーンを変更する必要はありません)

$dateStr = '2008-09-11';
$timezone = 'America/New_York';
$time = strtotime(
    $dateStr, 
    // convert timezone to offset seconds
    (new \DateTimeZone($timezone))->getOffset(new \DateTime) - (new \DateTimeZone(date_default_timezone_get()))->getOffset(new \DateTime) . ' seconds'
);

Loquacious Answer

関数の参照フレームを変更するstrtotimeの2番目のオプションを使用します。ところで、私はスクリプトのデフォルトのタイムゾーンを更新しないことを好みます:

http://php.net/manual/en/function.strtotime.php

int strtotime(string $ time [、int $ now = time()])

この関数は、英語の日付形式を含む文字列が与えられることを想定しており、その形式をUnixタイムスタンプ(1970年1月1日00:00:00 UTCからの秒数)に解析しようとしますタイムスタンプに関連して現在、または現在が指定されていない場合は現在の時刻

そしてヘルパー

/**
 * Returns the timestamp of the provided time string using a specific timezone as the reference
 * 
 * @param string $str
 * @param string $timezone
 * @return int number of the seconds
 */
function strtotimetz($str, $timezone)
{
    return strtotime(
        $str, strtotime(
            // convert timezone to offset seconds
            (new \DateTimeZone($timezone))->getOffset(new \DateTime) - (new \DateTimeZone(date_default_timezone_get()))->getOffset(new \DateTime) . ' seconds'
        )
    );
}

var_export(
    date(
        'Y-m-d', 
        strtotimetz('this monday', 'America/New_York')
    )
);

おそらく最もパフォーマンスの高いアプローチではありませんが、デフォルトのタイムゾーンとオフセットがわかっている場合はうまく機能します。たとえば、デフォルトのタイムゾーンがUTCで、オフセットが-8時間:

var_dump(
    date(
        'Y-m-d', 
        strtotime('this tuesday', strtotime(-8 . ' hours'))
    )
);
0
hpaknia