php dateTime::createFromFormat in 5.2?

15,118

Solution 1

just include the next code

function DEFINE_date_create_from_format()
  {

function date_create_from_format( $dformat, $dvalue )
  {

    $schedule = $dvalue;
    $schedule_format = str_replace(array('Y','m','d', 'H', 'i','a'),array('%Y','%m','%d', '%I', '%M', '%p' ) ,$dformat);
    // %Y, %m and %d correspond to date()'s Y m and d.
    // %I corresponds to H, %M to i and %p to a
    $ugly = strptime($schedule, $schedule_format);
    $ymd = sprintf(
        // This is a format string that takes six total decimal
        // arguments, then left-pads them with zeros to either
        // 4 or 2 characters, as needed
        '%04d-%02d-%02d %02d:%02d:%02d',
        $ugly['tm_year'] + 1900,  // This will be "111", so we need to add 1900.
        $ugly['tm_mon'] + 1,      // This will be the month minus one, so we add one.
        $ugly['tm_mday'], 
        $ugly['tm_hour'], 
        $ugly['tm_min'], 
        $ugly['tm_sec']
    );
    $new_schedule = new DateTime($ymd);

   return $new_schedule;
  }
}

if( !function_exists("date_create_from_format") )
 DEFINE_date_create_from_format();

Solution 2

Because strtotime does poorly when confronted with D/M/Y and date_create_from_format isn't available, strptime may be your only hope here. It does some pretty oldschool things, like deal with years as if they are the number of years since 1900 and deal with months as if January was month zero. Here's some horrible example code that uses sprintf to reassemble the date into something DateTime understands:

$schedule = '31/03/2011 01:22 pm';
// %Y, %m and %d correspond to date()'s Y m and d.
// %I corresponds to H, %M to i and %p to a
$ugly = strptime($schedule, '%d/%m/%Y %I:%M %p');
$ymd = sprintf(
    // This is a format string that takes six total decimal
    // arguments, then left-pads them with zeros to either
    // 4 or 2 characters, as needed
    '%04d-%02d-%02d %02d:%02d:%02d',
    $ugly['tm_year'] + 1900,  // This will be "111", so we need to add 1900.
    $ugly['tm_mon'] + 1,      // This will be the month minus one, so we add one.
    $ugly['tm_mday'], 
    $ugly['tm_hour'], 
    $ugly['tm_min'], 
    $ugly['tm_sec']
);
echo $ymd;
$new_schedule = new DateTime($ymd);
echo $new_schedule->format('Y-m-d H:i:s');

If it works, you should see the same, correct date and time printed twice.

Solution 3

I think it is much cleaner to extend the DateTime class and implement createFromFormat() yourself like this:-

class MyDateTime extends DateTime
{
    public static function createFromFormat($format, $time, $timezone = null)
    {
        if(!$timezone) $timezone = new DateTimeZone(date_default_timezone_get());
        $version = explode('.', phpversion());
        if(((int)$version[0] >= 5 && (int)$version[1] >= 2 && (int)$version[2] > 17)){
            return parent::createFromFormat($format, $time, $timezone);
        }
        return new DateTime(date($format, strtotime($time)), $timezone);
    }
}

$dateTime = MyDateTime::createFromFormat('Y-m-d', '2013-6-13');
var_dump($dateTime);
var_dump($dateTime->format('Y-m-d'));

This will work in all versions of PHP >= 5.2.0.

See here for a demo http://3v4l.org/djucq

Share:
15,118

Related videos on Youtube

Hailwood
Author by

Hailwood

I could tell you all about me... but I'd prefer to let my work do the talking for me!

Updated on June 04, 2022

Comments

  • Hailwood
    Hailwood almost 2 years

    I have been developing on php 5.3.

    However our production server is 5.2.6.

    I have been using

    $schedule = '31/03/2011 01:22 pm'; // example input
    if (empty($schedule))
        $schedule = date('Y-m-d H:i:s');
    else {
        $schedule = dateTime::createFromFormat('d/m/Y h:i a', $schedule);
        $schedule = $schedule->format('Y-m-d H:i:s');
    }
    echo $schedule;
    

    However that function is not available in 5.2

    What is the easiest way to get around this (no chance of a php upgrade).

  • Hailwood
    Hailwood about 13 years
    out of curiosity, whats the difference between your code and else { $schedule = str_replace('/', '-', $schedule); $schedule = date('Y-m-d H:i:s', strtotime($schedule)); }
  • Jacob
    Jacob about 13 years
    This is probably the best solution unless you can have more control over the input and ensure you are using Supported Date and Time Formats.
  • Charles
    Charles about 13 years
    strtotime does not understand D/M/Y. It only can handle Y/M/D and M/D/Y. If you try to pass a D/M/Y to it, it will fail. strtotime('20/02/2003') returns false. You'd have to pass '20.03.2003' (note the dots!) to get that format recognized, which isn't the date format you expect.
  • Hailwood
    Hailwood about 13 years
    I understand that strtotime does not like / but if you convert / to - then it works perfectly. I am finding it hard to read your code above, mind commenting it a bit to explain what each function is doing?
  • Charles
    Charles about 13 years
    It looks like D-M-Y is supported, but your example date includes only slashes. Further, while D-M-Y is supported, M-D-Y is not -- replacing slashes on a M/D/Y would result in an unparsable date. I'll edit my code with more comments in a moment.
  • Hailwood
    Hailwood about 13 years
    also if ` deal with years as if they are the number of years since 1900` is true would you not want to subtract 1900 instead of adding 1900?
  • Charles
    Charles about 13 years
    I've edited my post with some inline comments, and a link to the sprintf documentation. tm_year ends up being 111 here, so we need to add 1900 to get back to 2011. Yes, it really works that way. Freaky, ain't it? Brings me back to my Perl days...
  • Hailwood
    Hailwood about 13 years
    Wow, that year handling is messed up! Cheers!
  • Jacob
    Jacob about 13 years
    @Hailwood @Charles see my answer stackoverflow.com/questions/5287224/… about date formats.
  • andreapier
    andreapier about 11 years
    This is a GREAT answer. Should really get more upvotes! Thanks
  • glerYbo
    glerYbo over 10 years
    Support for DateTime 'M': $schedule_format = str_replace(array('M', 'Y', 'm', 'd', 'H', 'i', 'a'),array('%b', '%Y', '%m', '%d', '%I', '%M', '%p'), $dformat);
  • glerYbo
    glerYbo over 10 years
    There is a small bug, as 'H' should be replaced to %H (24-hour format), not %I (12-hour format). So here is improved line: $schedule_format = str_replace(array('M', 'Y', 'm', 'd', 'H', 'i', 'a'), array('%b', '%Y', '%m', '%d', '%H', '%M', '%p'), $dformat);
  • Shelly Warren
    Shelly Warren almost 9 years
    Just read the question, please forgive me, meant to post on applicable question but was excited to have finally solved the issue and have no idea how to delete this, my bad.
  • morgar
    morgar over 7 years
    This doesn't work in 5.2.x with an usual non English format like 'd/m/Y', but it works if you replace '/' with '-'.
  • vascowhite
    vascowhite over 7 years
    As 5.2.x reached EOL nearly 6 years ago I'm not too concerned about it. Thanks for letting me know anyway.
  • Marco Andreolli
    Marco Andreolli about 5 years
    Doesn't work on Windows!, strptime is not implemented

Related