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


PHP date format /Date(1365004652303-0500)/

我正在调用一个API,我从中获取日期/Date(1365004652303-0500)/,我不知道这是什么格式。这个日期格式是如何调用的?我不知道在谷歌上搜索这种格式的内容。

有人能帮我把这个日期用Y-m-d H:i:s格式吗?

我正在调用的API已打开。NET服务器。当我使用PHP的file_get_contentsjson_decode调用它时,它为我提供了以下创建日期的Date格式:/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((调用来格式化此时间戳。先除以1000。在标准的美国格式中,它将是

$mydate=日期('m d Y',$timestamp(;

(其中$timestamp为1365004652303(

要将其格式化为您请求的格式(Y-m-d H:i:s(,您需要使用"Y-m-d 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是一种抵消;如果是这样,则需要相应地调整$stamp[0]。

这是我用来从Xero API解析时间戳的方法。它说明:

  • 负时间戳,日期在纪元之前
  • 小于10位的时间戳(但在epoch上-时间为零-甚至不确定该格式会是什么样子(
  • 几分之一秒
  • 可选时区偏移,包括正偏移和负偏移

代码:

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'));
}

如果你的日期像/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?

我想把这作为对爸爸的回答的评论,但我的声誉不允许我这样做。我希望这对我来说是合适的,因为我认为这可能有用。

以下示例使用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');

Baba的答案非常有用,但它没有涵盖我需要的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在评论中建议的regex组。