PHP date format /Date(1365004652303-0500)/

19,796

Solution 1

First you need to understand the format you have

/Date(1365004652303-0500)/

Then you have

  • time stamp (U) = 1365004652
  • Milliseconds (u) = 303
  • Difference to Greenwich time (GMT) (O) = -0500

Build a Format

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

Output

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

Solution 2

Try this out:

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

Returns:

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

Solution 3

Let's break /Date(1365004652303-0500)/ down to:

  • Date
  • 1365004652303
  • -0500

First string makes itself pretty clear.

The next large number is the epoch value

The -0500 represents the timezone in which the dates were originally stored. It is relative to UTC and thus, it is referring to Eastern Standard Time.


EDIT

The epoch is with a milisecond precision. Try this code:

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

You can also use the timezone for setting the date relative to your own. http://codepad.viper-7.com/RrSkMy

Solution 4

This timestamp is in milliseconds, which is why it's so large.

You can use the PHP date() call to format this timestamp as you wish. Just divide by 1,000 first. In standard US format, it would be

$mydate = date('m d Y', $timestamp);

(where $timestamp is 1365004652303)

To format it in the format you requested (Y-m-d H:i:s) you would use 'Y-m-d H:i:s' as the format string (first parameter). Chop off text starting with "-".

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

This yields 2013-04-03 11:57:32

Others have suggested the 0500 is an offset; if so, you'd want to adjust $stamps[0] accordingly.

Solution 5

If your date is like /Date(-62135578800000)/, a positive or negative integer without timezone:

$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
Share:
19,796

Related videos on Youtube

Kalpesh
Author by

Kalpesh

Magento Master 2020

Updated on June 04, 2022

Comments

  • Kalpesh
    Kalpesh almost 2 years

    I am calling an API from where I am getting date /Date(1365004652303-0500)/, I don't understand what format this is. How is this date format called? I was not sure what to google for such type of format.

    Can anyone help me out in getting this date in Y-m-d H:i:s format?

    The API I am calling is on .NET server. And when I call it using PHP's file_get_contents and json_decode it gives me the following Date format for created date: /Date(1365004652303-0500)/

    • Stan
      Stan almost 11 years
      It's UNIX time stamp. Before outputting your JSON convert it from UNIX to normal datetime string.
    • hek2mgl
      hek2mgl almost 11 years
      A UNIX time stamp with timezone offset
    • hakre
      hakre almost 11 years
      The interesting part would be to see an example with a positive timezone offset. How does it look like then?
    • zerkms
      zerkms almost 11 years
      @hakre: /Date(1365004652303+0500)/ ?
    • hakre
      hakre almost 11 years
      Well, that's one option I see, as well as /Date(13650046523030500)/ and then that's where the fun starts :)
    • zerkms
      zerkms almost 11 years
    • hakre
      hakre almost 11 years
      Please add more information which API this is.
    • Scott C Wilson
      Scott C Wilson almost 11 years
      The odd thing about this timestamp is that it's in milliseconds. If you divide by 1,000, you see a more reasonable number. That's what had me stumped at first.
    • Jimbo
      Jimbo almost 11 years
      Totally think you picked the wrong answer.
    • hakre
      hakre almost 11 years
      @Kalpesh Mehta: As long as you don't say what the GMT offset of your Y-m-d H:i:s format is, it is technically not possible to answer your question.
    • Kalpesh
      Kalpesh almost 11 years
      @hakre it got solved, using Baba's and Steven's answers. I wanted GMT-5 hours
    • hakre
      hakre almost 11 years
      @KalpeshMehta: Again: Which API? Reference please! "Got solved" is no-saying, it already got solved earlier on this website, you just missed to understand what the problem is. If you would be so kind to provide more reference with your question, there is more for the future than just yesterdays fun.
    • Kalpesh
      Kalpesh almost 11 years
      @hakre Ok just updated the question. Actually it's on .NET server and our company's internal project, so I can't give the URL. And as I was only concerned about converting the date, I gave sample of date I was getting.
    • hakre
      hakre almost 11 years
      It's not so much about sharing the URL but more the specifics. E.g. which JSON serialization library is used in .NET by that API?
    • Gajus
      Gajus over 10 years
    • Steven Moseley
      Steven Moseley almost 10 years
      @KalpeshMehta - Can you please move the checkmark to Baba's answer so I can delete mine? Thanks.
    • Kalpesh
      Kalpesh almost 10 years
      @StevenMoseley Done. Thanks for being honest!
  • Baba
    Baba almost 11 years
    (integer) $matches[1]; fail
  • hek2mgl
    hek2mgl almost 11 years
    @Baba :O ?? Which PHP version?
  • Baba
    Baba almost 11 years
    32 bit system ... (int) $matches[1]; would have always returned PHP_INT_MAX
  • hek2mgl
    hek2mgl almost 11 years
    I have a 64 bit system. Didn't know that (int) and (integer) behave differently
  • hjpotter92
    hjpotter92 almost 11 years
    @Jimbo It never gets old :P
  • Kalpesh
    Kalpesh almost 11 years
    @hjpotter92 the output is 5 hours ahead.. may be due to timezone.
  • hjpotter92
    hjpotter92 almost 11 years
    @KalpeshMehta As I mentioned in the reply: You can also use the timezone for setting the date relative to your own.
  • Baba
    Baba almost 11 years
  • Baba
    Baba almost 11 years
    @KalpeshMehta please note that 0500 is not timezone don't let anyone confuse you
  • Steven Moseley
    Steven Moseley almost 11 years
    @hjpotter92 - That's fine if the timezone in the date IS set to your own. What happens if he gets a time with offset -0800 and he's in EST?
  • Steven Moseley
    Steven Moseley almost 11 years
    This is the correct answer. My answer gets the timezone from the offset, but doesn't correctly account for daylight savings.
  • Kalpesh
    Kalpesh almost 11 years
    I added $dt->sub(new DateInterval('PT5H')); just after $dt=Datetime::createFromFormat.. to subtract 5 hours from the date and it works.
  • Ghigo
    Ghigo almost 7 years
    Be careful: this will lead to incorrect conversions when hour contains minutes as well, like 0930. Must split hours and minutes and do calculation properly.
  • Luceos
    Luceos over 5 years
    If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. - From Review
  • Rumyana Ruseva
    Rumyana Ruseva over 5 years
    Thanks for the review @Luceos. I do not have a new question, I'm adding more info which was not present in any of the previous answers nor comments, and I believe it might be useful to other users.
  • Luceos
    Luceos over 5 years
    Your answer is a new evolution of the question. Answers should only answer the question given. You can ask a new question with your situation and answer it yourself. This is allowed if self answered questions pose value to the community.
  • Vivien
    Vivien over 5 years
    Seem to not support negative dates (before 1970)
  • Jason
    Jason almost 5 years
    It is important to note that this is close, but not close enough. It will not match negative timestamps, that is times before the 1970 epoch. It will also not work for timestamps with fewer than 10 digits. Also DateTime::createFromFormat() will now ignore any timezone passed to it when decoding unix timezones, so the timezone must be added as a separate step.
  • Jason
    Jason over 4 years
    Coming back to this, it can probably be simplified a little more. By removing the parenthesis grouping from the start and the end, there would be just the middle three RE matches to use. [2] to [4] would become [1] to [3].
  • mickmackusa
    mickmackusa about 4 years
    Never use preg_split() to do what explode() can do. I never use explode() to do what strstr() with a true 3rd param can do.