4
$year = date('Y', strtotime("2012"));
var_dump($year);//returns 2013

This is happening with an old server with php 5.2 and a new one with php 5.4

The server uses strtotime to get the year from a string like 2012-01-01 or 2012-01 or 2012

I also tried it using $dt = new DateTime('2012') and then getTimestamp returns "1374516720" which is "Mon, 22 Jul 2013 18:12:00 GMT"

What is causing this bug? In the documentation it says that strtotime accepts only the year

I don't know what to do...

Edit:

$year = date('Y', strtotime("2012"));

gets treated as military time, 20:12 current year

Timo Huovinen
  • 53,325
  • 33
  • 152
  • 143
  • 3
    dont use strtotime if strlen == 4 – Rufinus Jul 22 '13 at 10:42
  • What point is is there in doing this when you can shorten the code to `echo 2012`? – deceze Jul 22 '13 at 10:45
  • I don't understand why you're inputting a year and formatting it back to the same thing. – Austin Brunkhorst Jul 22 '13 at 10:45
  • Because I'm formatting a partial or full date and outputting a year, date and year are mostly different things – Timo Huovinen Jul 22 '13 at 10:46
  • 1
    there is no bug... strtotime just doesnt returns a value, so date uses current timestamp. – Rufinus Jul 22 '13 at 10:47
  • strtotime returns a string "1374516720", which is not really the current timestamp (which is "1374490126" right now according to http://www.currenttimestamp.com/) – Timo Huovinen Jul 22 '13 at 10:48
  • 2
    @TimoHuovinen I'm with you, the documentation says that `2012` is a valid date format. For me it is currently unclear as well. That's why I could gave you just a workaround. Will investigate that. Btw, the behaviour is reproducable with PHP5.3 too – hek2mgl Jul 22 '13 at 10:55
  • @hek2mgl thank you, interesting to see it fail on PHP5.3 too – Timo Huovinen Jul 22 '13 at 11:00
  • 1
    @TimoHuovinen The manual states this: `The "Year (and just the year)" format only works if a time string has already been found -- otherwise this format is recognised as HH MM. `.. I'm currently unsure what this means – hek2mgl Jul 22 '13 at 11:03
  • @hek2mgl it seems to mean that if you put in 2012 then it it will be treated as "{current_date} 20:12", military style "Get up at 0900!!", but still does not explain why it gets the time "18:12" instead – Timo Huovinen Jul 22 '13 at 11:20
  • @TimoHuovinen yes 2012 will interpreted as `20:12` today. Currently not ready with final analyzis. **strange**! :P – hek2mgl Jul 22 '13 at 11:26
  • @TimoHuovinen check my update. While it is still unsatisfying the update at least explains the behaviour – hek2mgl Jul 22 '13 at 11:40

3 Answers3

7

Using a complete date string YYYY-MM-DD and the 01.01 as the day did the trick for me:

$year = date('Y', strtotime("2012-01-01"));
var_dump($year);//returns 2012

Normally I would suggest to use DateTime::createFromFormat() as @Rufinus suggested, but the method is not available in PHP5.2 (what you are using on one of the servers). Maybe a reason fro upgrading the old one? ;)


Reasons why this happens:

While the manual says at one point that YYYY (and just YYYY) formats are ok, it tells about restrictions to that behaviour some lines below: strtotime() called with YYYY will under special circumstances return a time stamp for today, 20:12:

The "Year (and just the year)" format only works if a time string has already been found -- otherwise this format is recognised as HH MM.

I don't know what they mean when saying a time string has already been found. But you can see this behaviour using the following line:

var_dump(date("Y-m-d H:i:s", strtotime('2012')));
// output: string(19) "2013-07-22 20:12:00"

This leads to the result 2013.

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
3

EDIT: different formats...

try

$date = '2012-11';

$parts = explode('-', $date);
switch(count($parts)){
        case 2:
                $format = 'Y-m';
                break;
        case 3:
                $format = 'Y-m-d';
                break;
        case 1:
        default:
                $format = 'Y';
                break;
}

$date = DateTime::CreateFromFormat($format, $year);
echo $date->format('Y');
Rufinus
  • 29,200
  • 6
  • 68
  • 84
0

try more manual approach. i find strtotime not too reliable in edge cases and prefer to have more control over what is going on.

$parsed = explode('-',$input_string);
$year = (isset($parsed[0])) ? $parsed[0] : NULL;
$month = (isset($parsed[0])) ? $parsed[0] : 1;
$day = (isset($parsed[0])) ? $parsed[0] : 1;

$timestamp = mktime(0,0,0,$day,$month,$year);
echo date($your_preffered_format, $timestamp);
Jarek.D
  • 1,274
  • 1
  • 8
  • 18
  • If you prefer more control, you should be using DateTime class that cuts your code to 2 lines. – N.B. Jul 22 '13 at 11:01
  • It won't work in 5.2. Besides after working on a project involving storing data in UTC, lots of data arithmetics and display according to users time zone I stopped trusting new DateTime functions - buggy – Jarek.D Jul 22 '13 at 11:11
  • Timestamps are always UTC. Creating a DateTime object and then getting the timestamp is always UTC. PHP 5.2 can be upgraded to higher version without issues. – N.B. Jul 22 '13 at 11:34