我得到這個排序在最後。從PHP manual信息的該位放倒我送行:
在$時區參數和當前時區被忽略時,$時間參數要麼是一個UNIX時間戳(如@ 946684800),或者指定一個時區(如2010- 01-28T15:00:00 + 02:00)。
所以我最終的解決方案是擴展DateTime
類並覆蓋__construct()
方法。我的修改後的類如下:
<?php
class timezone extends DateTime {
// Override our __construct method
function __construct($date = "now", $offset = null) {
// If we've not specified an offset
if(is_null($offset)) {
// Assume UTC
$offsetFormat = "+00:00";
$offset = 0;
// Otherwise..
} else {
// Create a new DateTime, and get the difference between that, and another new DateTime that has $offset minutes subtracted from it. Format the results as something like +11:00 or -03:00
$offsetFormat = (new DateTime($date, new DateTimeZone("UTC")))->diff((new DateTime($date, new DateTimeZone("UTC")))->sub(DateInterval::createFromDateString($offset . " minutes")))->format("%R%H:%I");
}
// Next, we get the offset from our $date. If this offset (divided by 60, as we're working in minutes, not in seconds) does NOT equal our offset
if((new DateTime($date))->getOffset()/60 !== $offset) {
// Overwrite $date, and set it to a new DateTime with $offset minutes subtracted from it
$date = (new DateTime($date, new DateTimeZone("UTC")))->sub(DateInterval::createFromDateString($offset . " minutes"));
// If $date's offset equals $offset
} else {
// An offset has already been applied (we know this because all our pre-offset dates will be in UTC), and we don't need to do it again
$date = (new DateTime($date));
}
// Finally, hand this back to the original DateTime class. This format works out to be something like: 2016-03-10T23:16:37+11:00
parent::__construct($date->format("Y-m-d\TH:i:s") . $offsetFormat, null);
}
}
echo (new timezone())->format("c") . "<br />"; // Will output something like 2016-03-10T12:17:44+00:00
echo (new timezone(null, -660))->format("c") . "<br />"; // Will output something like 2016-03-10T23:17:44+11:00
echo (new timezone("midnight", -660))->format("c") . "<br />"; // Will output 2016-03-10T11:00:00+11:00
echo (new timezone("midnight"))->format("c") . "<br />"; // Will output 2016-03-10T00:00:00+00:00
echo (new timezone("2016-01-01T00:00+00:00", -660))->format("c") . "<br />"; // Will output 2016-01-01T11:00:00+11:00
echo (new timezone("2016-01-01T00:00+11:00", -660))->format("c") . "<br />"; // Will output 2016-01-01T11:00:00+11:00. Note that the offset isn't applied twice!
?>
編輯:這是現在我已經開源的庫。 Check it out over on GitHub
由於平臺限制(例如Pebble smartwatch,要求時區打破UX),我正在從Javascript檢索偏移量,所以偏移量將在幾分鐘內(例如,墨爾本比UTC早660分鐘)。編輯:有這個選項:http://stackoverflow.com/questions/7276304/php-setting-a-timezone-by-utc-offset但顯然它不處理夏時制很好 – Grayda