在给定的持续时间内获得两个时区之间的时区偏移

时间:2012-02-06 15:41:52

标签: php mysql datetime timezone datetimeoffset

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

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中进行更优化。

3 个答案:

答案 0 :(得分:3)

假设你有一个较新版本的php(5.2.0+),DateTimeZone类是PHP核心的一部分,可以让你使用getOffset()函数进行这些计算。它将允许您传入dateTime object并指定时区。如果你在两个日期都这样做,你应该能够计算出你想要抓住的所有部分。要使用来自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));

答案 1 :(得分:1)

我认为PHP的DateTimeZone::getTransitions method可以帮助你。它有一个程序别名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指的是time()返回的epoch秒中的PHP时间戳,给出了偏移量变为此记录中值的瞬间。 time指的是同一时刻,作为格式化的字符串日期时间。 offset是时区与UTC之间的距离(以秒为单位),截至当前time / ts,转发到下一个转换。如果偏移量指的是夏令时偏移量,则isdst为1,否则为0。 abbr是时区的字符串缩写。如果有人掌握有关此数据结构的可靠信息,那么将其添加到the documentation是一种善意。

答案 2 :(得分:1)

这对我有用:

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