6

我想知道是否有办法在给定的持续时间内获取两个时区之间给定日期范围的时区偏移量。

getTimezoneOffset(startDate,endDate,timezone1,timezone2){
    ...missing magic to go here...
}

应该返回对给定持续时间有效的时区偏移量。但是,如果偏移量发生变化,它应该返回它有效的日期范围。

所以我在看这样的东西:

getTimezoneOFfset("march 9 12 am", "march 15 12 am", "UTC", "US/NEW_YORK")

返回值是这样的

timezoneoffset[0]["range"]=[march 9 12am to march 11 2 am]
timezoneoffset[0]["offset"]=5
timezoneoffset[1]["range"]=[march 9 2 am to march 15 12 am]
timezoneoffset[1]["offset"]=4

我只是不想为给定范围内的每个计划项目计算时区偏移量。正在寻找是否有某种方法可以直接查找偏移量(如果它会发生变化)。

我正在使用 PHP,但任何语言的解决方案都会受到赞赏。

MySQL 解决方案也将起作用,因为它将在 MySQL 中进行更优化。

4

3 回答 3

4

假设您有更新版本的 php (5.2.0+),DateTimeZone类是 PHP 核心的一部分,您可以使用该getOffset()函数进行这些计算。它会让你传入一个dateTime 对象并指定一个时区。如果你在两个日期都这样做,你应该能够计算出你想要抓住的所有部分。要使用 php.net 中的示例:

// Create two timezone objects, one for Taipei (Taiwan) and one for
// Tokyo (Japan)
$dateTimeZoneTaipei = new DateTimeZone("Asia/Taipei");
$dateTimeZoneJapan = new DateTimeZone("Asia/Tokyo");

// Create two DateTime objects that will contain the same Unix timestamp, but
// have different timezones attached to them.
$dateTimeTaipei = new DateTime(mktime([the date in question]), $dateTimeZoneTaipei);
$dateTimeJapan = new DateTime(mktime([the date in question]), $dateTimeZoneJapan);


// Calculate the GMT offset for the date/time contained in the $dateTimeTaipei
// object, but using the timezone rules as defined for Tokyo
// ($dateTimeZoneJapan).
$timeOffset = $dateTimeZoneJapan->getOffset($dateTimeTaipei);

// Should show int(32400) (for dates after Sat Sep 8 01:00:00 1951 JST).
print("Number of seconds Japan is ahead of GMT at the specific time: ");
var_dump($timeOffset);

print("<br />Number of seconds Taipei is ahead of GMT at the specific time: ");
var_dump($dateTimeZoneTaipei->getOffset($dateTimeTaipei));

print("<br />Number of seconds Japan is ahead of Taipei at the specific time: ");
var_dump($dateTimeZoneJapan->getOffset($dateTimeTaipei)
     -$dateTimeZoneTaipei->getOffset($dateTimeTaipei));
于 2012-02-06T18:39:28.943 回答
2

这对我有用:

function Get_Timezone_Offset($remote_tz, $origin_tz = null) 
{
    if($origin_tz === null) 
    {
        if(!is_string($origin_tz = date_default_timezone_get())) {
            return false;
        }
    }
    $origin_dtz = new DateTimeZone($origin_tz);
    $remote_dtz = new DateTimeZone($remote_tz);
    $origin_dt  = new DateTime("now", $origin_dtz);
    $remote_dt  = new DateTime("now", $remote_dtz);
    $offset     = $origin_dtz->getOffset($origin_dt) - $remote_dtz->getOffset($remote_dt);
    return $offset;
}

使用它

echo Get_Timezone_Offset('America/New_York', 'Europe/Stockholm');

来源: http: //php.net/manual/en/function.timezone-offset-get.php

于 2018-04-27T05:39:57.920 回答
1

我认为 PHP 的DateTimeZone::getTransitions方法可以让你到达那里。它有一个程序别名timezone_transitions_get().

public array DateTimeZone::getTransitions (
    [ int $timestamp_begin [, int $timestamp_end ]]    )

此方法返回给定时间范围内从一个时区偏移值到另一个时区的所有“转换”。

出于您的目的,您需要DateTimeZone为每个时区创建对象,调用DateTimeZone::getTransitions您的日期范围以获取该时区的转换数组,然后合并和排序两个转换数组。timezoneoffset[]这将为您提供与您寻求的数组等效的值。

就像是:

getTimezoneOffset(startDate,endDate,timezone1,timezone2){
    DT1 = DateTimeZone( timezone1 );
    transitions1 = DT1->getTransitions( startDate,endDate );
    DT2 = DateTimeZone( timezone2 );
    transitions1 = DT2->getTransitions( startDate,endDate );
    timezoneoffset[] = // merge and sort (transitions1, transitions2)
}

转换数组的格式没有很好的记录。方法文档显示了一些示例条目:

Array
(
...
    [1] => Array
        (
            [ts] => -1691964000
            [time] => 1916-05-21T02:00:00+0000
            [offset] => 3600
            [isdst] => 1
            [abbr] => BST
        )

    [2] => Array
        (
            [ts] => -1680472800
            [time] => 1916-10-01T02:00:00+0000
            [offset] => 0
            [isdst] => 
            [abbr] => GMT
        )
    ...
)

我推测:ts指以纪元秒为单位的 PHP 时间戳,由 . 返回time(),给出偏移量更改为此记录中的值的时刻。time指的是同一时刻,作为格式化的字符串日期时间。offset是从 UTC 开始的时区偏移量(以秒为单位),从time/ts开始,向前到下一个转换。isdst如果偏移量是指夏令时偏移量,则为 1,否则为 0。abbr是时区的字符串缩写。如果有人有关于此数据结构的可靠信息,请将其添加到文档中将是一种好意。

于 2012-02-06T23:25:50.013 回答