簡體   English   中英

PHP日期格式/Date(1365004652303-0500)/

[英]PHP date format /Date(1365004652303-0500)/

我正在從獲取日期的地方調用 API /Date(1365004652303-0500)/ ,我不明白這是什么格式。 這種日期格式如何命名? 我不確定要在 google 上搜索什么類型的格式。

任何人都可以幫助我以Ymd H:i:s格式獲取此日期嗎?

我正在調用的 API 位於 .NET 服務器上。 當我使用 PHP 的file_get_contentsjson_decode調用它時,它為我提供了以下創建日期的日期格式: /Date(1365004652303-0500)/

首先,您需要了解您擁有的格式

/Date(1365004652303-0500)/

那么你有

  • 時間戳 (U) = 1365004652
  • 毫秒 (u) = 303
  • 與格林威治時間 (GMT) 的差異 (O) = -0500

建立格式

$date = '/Date(1365004652303-0500)/';
preg_match('/(\d{10})(\d{3})([\+\-]\d{4})/', $date, $matches);
$dt = DateTime::createFromFormat("U.u.O",vsprintf('%2$s.%3$s.%4$s', $matches));
echo $dt->format('r');

輸出

Wed, 03 Apr 2013 15:57:32 -0500
                            ^
                            |= Can you see the GMT ? 

interface DateFormatParser
{
    /**
     * @param $string
     *
     * @return DateTime
     */
    public function parse($string);

}

abstract class PregDateParser implements DateFormatParser
{
    protected $pattern, $format, $mask;

    public function parse($string) {
        $string = (string)$string;

        $pattern = $this->pattern;
        $format  = $this->format;
        $mask    = $this->mask;

        $r = preg_match($pattern, $string, $matches);
        if (!$r) {
            throw new UnexpectedValueException('Preg Regex Pattern failed.');
        }
        $buffer = vsprintf($mask, $matches);
        $result = DateTime::createFromFormat($format, $buffer);
        if (!$result) {
            throw new UnexpectedValueException(sprintf('Failed To Create from Format "%s" for "%s".', $format, $buffer));
        }
        return $result;
    }
}

class JsonTimestampWithOffsetParser extends PregDateParser
{
    protected $pattern = '/^\/Date\((\d{10})(\d{3})([+-]\d{4})\)\/$/';
    protected $format  = 'U.u.O';
    protected $mask    = '%2$s.%3$s.%4$s';
}

$date   = '/Date(1365004652303-0500)/';
$parser = new JsonTimestampWithOffsetParser;
$dt     = $parser->parse($date);

echo $dt->format('r');

試試這個:

var_dump(date('Y-m-d H:i:s', '1365004652303'/1000));
$str = '/Date(1365004652303-0500)/';

$match = preg_match('/\/Date\((\d+)([-+])(\d+)\)\//', $str, $date);

$timestamp = $date[1]/1000;
$operator = $date[2];
$hours = $date[3]*36; // Get the seconds

$datetime = new DateTime();

$datetime->setTimestamp($timestamp);
$datetime->modify($operator . $hours . ' seconds');
var_dump($datetime->format('Y-m-d H:i:s'));

返回:

string(19) "2013-04-03 17:57:32"
string(19) "2013-04-03 12:57:32"

讓我們打破/Date(1365004652303-0500)/到:

  • 日期
  • 1365004652303
  • -0500

第一個字符串很清楚。

下一個大數是紀元值

-0500 表示最初存儲日期的時區。 它相對於 UTC,因此,它指的是東部標准時間。


編輯

紀元具有毫秒級精度。 試試這個代碼:

<?php
    $str = "/Date(1365004652303-0500)/";
    preg_match( "#/Date\((\d{10})\d{3}(.*?)\)/#", $str, $match );
    echo date( "r", $match[1] );
?>

您還可以使用時區來設置相對於您自己的日期。 http://codepad.viper-7.com/RrSkMy

這個時間戳以毫秒為單位,這就是它如此大的原因。

您可以根據需要使用 PHP date () 調用來格式化此時間戳。 只需先除以 1,000。 在標准的美國格式中,它將是

$mydate = date('md Y', $timestamp);

(其中 $timestamp 是 1365004652303)

要將其格式化為您請求的格式 (Ymd H:i:s),您可以使用 'Ymd H:i:s' 作為格式字符串(第一個參數)。 剪掉以“-”開頭的文本。

$stamps = preg_split("/-/", $time);
$stamps[0] = $stamps[0]/1000; 
$mydate = date('Y-m-d H:i:s', $stamps[0]); 

這產生了 2013-04-03 11:57:32

其他人則認為 0500 是偏移量; 如果是這樣,您需要相應地調整 $stamps[0] 。

如果您的日期類似於/Date(-62135578800000)//Date(-62135578800000)/不帶時區的正整數或負整數:

$date = substr('/Date(-62135578800000)/', 6, -5);
$date = date('m/d/Y H:i:s', $date + date('Z', $date) * -1);
// 01/01/0001 05:00:00

我有一些略有不同的經歷,這使我對巴巴的出色回答做了一些細微的改動。

使用 Newtonsoft 的 JSON 庫在 .NET 中編碼消息,然后我將其發送到我們的網站(PHP 部分),我在時區偏移之前得到一個空格,並且沒有 +/- 字符。

我還看到了前紀元日期的負數,這意味着我需要在毫秒值之前滿足 - 符號。

我將正則表達式更改為此,它非常適合我:

^/Date(([-]?\\d{10})(\\d{3})\\s?([+-]?\\d{4}))/$

這兩個區別是

[-]? 在 10 位毫秒值之前,以及\\s? 在時區偏移之前。

我會將其作為對巴巴回答的評論,但我缺乏聲譽不允許我這樣做。 我希望這適合我在這里發帖,因為我認為它可能有用。

這就是我用來解析來自 Xero API 的時間戳的方法。 它占:

  • 負時間戳,紀元之前的日期。
  • 少於 10 位數字的時間戳(但在紀元上 - 時間為零 - 不確定那種格式會是什么樣子)
  • 幾分之一秒。
  • 可選的時區偏移量,正負。

代碼:

if (preg_match('#^(/Date\()([-]?[0-9]+)([0-9]{3})([+-][0-9]{4})?(\)/)$#', $data, $matches)) {
    // Handle Xero API DateTime formats. Examples:
    // "/Date(1436961673000)/" - unix timestamp with milliseconds
    // "/Date(1436961673000+0100)/" - with an additional timezone correction
    // "/Date(-1436961673000-0530)/" - before the epoch, 1924 here
    //
    // RE matches for "/Date(1436961673090+0100)/":
    // [1] = (/Date\()          "/Date("
    // [2] = ([-]?[0-9]+)       "1436961673"    epoch seconds
    // [3] = ([0-9]{3})         "090"           milliseconds
    // [4] = ([+-][0-9]{4})?    "+0100" or ""   optional timezone
    // [5] = (\)/)              ")"

    $result = \DateTime::createFromFormat('U u', $matches[2] . ' ' . $matches[3] . '000')
        ->setTimezone(new \DateTimeZone($matches[4] ?: '+0000'));
}

以下示例使用preg_match()DateTime類:

$date = '/Date(1365004652303-0500)/';

// get the timestamp
$pattern = '~/Date\(([0-9]*)~';
preg_match($pattern, $date, $matches);
$timestamp = round(((int) $matches[1]) / 1000);

$dt = new DateTime();
$dt->setTimestamp($timestamp);

echo $dt->format('Y-m-d H:i:s');

巴巴的回答很有幫助,但它不包括我需要的 3 種情況:

  • 時間戳可能為負
  • 時間戳可能少於 10 位
  • GMT 偏移量可能丟失。

這是我用來獲取時間戳的內容:

$date_string = '/Date(-594262800300+0100)/';
preg_match('/([+-]?\d+)([+-]\d{4})?/', $date_string, $matches);
$timestamp = $matches[1] / 1000;
$hours = $matches[2] * 36; // Get the seconds
return $timestamp + $hours;

同樣,正如 Ghigo 指出的,如果偏移量包含分鍾,這是不正確的,但它適用於我的情況。

您可以使用此包來解析 JSON 日期:

https://github.com/webapix/dot-net-json-date-formatter

use \Webapix\DotNetJsonDate\Date;

$dateTime = Date::toDateTime('/Date(1365004652303-0500)/'); 
// return with \DateTime object, you can format it: $dateTime->format('Y-m-d H:i:s')

稍微調整 Jason 為 Xero API 給出的優秀答案:

if (preg_match('#^\\\/Date\(([-]?[0-9]+)([0-9]{3})([+-][0-9]{4})?\)\\\/$#', $data, $matches)) {
    // Handle Xero API DateTime formats. Examples:
    // "\/Date(1436961673000)\/" - unix timestamp with milliseconds
    // "\/Date(1436961673000+0100)\/" - with an additional timezone correction
    // "\/Date(-1436961673000-0530)\/" - before the epoch, 1924 here
    //
    // RE matches for "\/Date(1436961673090+0100)\/":
    // [1] = ([-]?[0-9]+)       "1436961673"    epoch seconds
    // [2] = ([0-9]{3})         "090"           milliseconds
    // [3] = ([+-][0-9]{4})?    "+0100" or ""   optional timezone
    $result = \DateTime::createFromFormat('U.u', $matches[1] . '.' . $matches[2] . '000')
        ->setTimezone(new \DateTimeZone($matches[3] ?? '+0000'));
}

這使用帶有附加反斜杠的當前 Xero 格式,並簡化以減少 Jason 在評論中建議的正則表達式分組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM