drewwyatt
drewwyatt

Reputation: 6027

Parse datetime string into an array of its individual units

I have looked at several of the other regular expressions questions here and on other message boards. I am beating my head against the wall because I just can't seem to wrap my head around this. (or regular expressions in general)

I am pulling a time stamp from a MYSQL database. This is automatically generated, so it is formatted normally: 2011-12-17 21:30:56

I want to break this up into an array without having to use multiple explodes. I am assuming preg_split() is the answer here. If you have a better idea, I am all ears (though I feel like I need to figure out how to use regular expressions at some point anyway.)

In any case, I am trying to split this up at each "-" ":" and " ". After a bit of reading it seems like a character class is the answer, here is my code, that is simply not working:

$date_arr = preg_split("/ [- :] /", $order['order_date']);

This is outputting: Array ( [0] => 2011-12-17 21:30:56 )

Where am I going wrong?

Upvotes: 0

Views: 208

Answers (3)

mickmackusa
mickmackusa

Reputation: 47764

The simplest, most direct way to split your datetime string into an indexed, six-element array is to feed a regex pattern to preg_split() which treats all non-digits as delimiters. Demo

$dt = '2011-12-17 09:30:56';
var_export(
    preg_split('/\D+/', $dt)
);

Inversely, preg_match_all() can be used to isolate all integer substrings, but this is not directly returns from the function and it creates a 2d array. Demo

preg_match_all('/\d+/', $dt, $m);
var_export(
    $m[0]
);

sscanf() can be implemented to return an array of values using explicit placeholder to signify whether a string-type (%s) or int-type (%d) value is desired. Mind your work, %s will greedily match characters until it encounters a whitespace character. Notice, too, that %d will effectively trim leading zeros as it cases each value to an int type. Demo

var_dump(
    sscanf($dt, '%04s-%02s-%02s %02s:%02s:%02s'),
    sscanf($dt, '%[^-]-%[^-]-%s %[^:]:%[^:]:%s'),
    sscanf($dt, '%d-%d-%d %d:%d:%d'),
);

Parsing the datetime string with a native datetime parser is certainly appropriate as well. Below implementa an Immediately Invoked Functional Expression to elegantly make 6 separate method calls on the datetime object. Demo

var_export(
    (fn($obj) => [
        $obj->format('Y'),
        $obj->format('m'),
        $obj->format('d'),
        $obj->format('H'),
        $obj->format('i'),
        $obj->format('s')
    ])(date_create($dt))
);

Upvotes: 0

Filip Roséen
Filip Roséen

Reputation: 63797

The reason your preg_split fails is because of the spaces surrounding [- :].

As it's currently written in will only split on " - ", "   " and " : ".

$date_arr = preg_split("/ [- :] /", ... ); // original
$date_arr = preg_split("/[- :]/", ...);    // fixed

Instead of using functions such as explode and preg_split to split your string, use strtotime and getdate:

print_r (
  getdate (strtotime ("2011-12-17 21:30:56"))
);

...

Array
(
    [seconds] => 56
    [minutes] => 30
    [hours] => 21
    [mday] => 17
    [wday] => 6
    [mon] => 12
    [year] => 2011
    [yday] => 350
    [weekday] => Saturday
    [month] => December
    [0] => 1324153856
)

Upvotes: 4

Krzysztof
Krzysztof

Reputation: 16130

You have unncesary spaces in regex. Try this:

preg_split("/[- :]/", '2011-12-17 21:30:56');

Upvotes: 1

Related Questions