0

I have a string

$string = "2012-1-12 51:00:00.5";

How can I explode this date into year, month, day, hour, minutes, seconds without using a date function.

I was trying with multiple calls of explode() because it can only split on one delimiter at a time, but this isn't working out well.

My try:

$string = "2012-1-12 51:00:00.5";
print_r(explode(" ", $date));
print_r(explode("-", $date));
print_r(explode(":", $date));

Output:

Array
(
    [0] => Array
        (
            [0] => 2012-1-12
            [1] => 51:00:00.5
        )

    [1] => Array
        (
            [0] => 2012
            [1] => 1
            [2] => 12 51:00:00.5
        )

    [2] => Array
        (
            [0] => 2012-1-12 51
            [1] => 00
            [2] => 00.5
        )
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
jsduniya
  • 2,464
  • 7
  • 30
  • 45

4 Answers4

2

You can use preg_split since you need to explode on 3 parameters, This works -

$string="2012-1-12 51:00:00.5";
$pieces = preg_split("/[-: ]/", $string);
var_dump($pieces);
/*
array
  0 => string '2012' (length=4)
  1 => string '1' (length=1)
  2 => string '12' (length=2)
  3 => string '51' (length=2)
  4 => string '00' (length=2)
  5 => string '00.5' (length=4)
*/
Kamehameha
  • 5,423
  • 1
  • 23
  • 28
1

As mentioned in the comment to your query three explodes would be needed:

list($date, $time) = explode(" ", $string);
list($year, $month, $day) = explode("-", $date);
list($hours, $mins, $sec) = explode(":", $time);

/*print the values of $year, $date and  so on*/

Hope this helps. Of course this would work assuming all date-time values in your application are in the above format.

Prahalad Deshpande
  • 4,709
  • 1
  • 20
  • 22
0

Using sscanf() might be the most-controllable approach for parsing that datetime string into its individual numeric components. preg_split() might be the most succinct.

The placeholders in the "format" argument:

  • %d means integer (and the isolated value will be cast an an int type value),
  • %f means float value (and the isolated value will be cast an an float type value).
  • [^...] is like a negated character class which will greedily match one or more characters that are not listed inside of the square braced expression.

Codes: (Demo)

  • Ints and float:

    $string = "2012-1-12 51:00:00.5";
    var_export(sscanf($string, '%d-%d-%d %d:%d:%d%f'));
    // or if you want only integers:
    // var_export(sscanf($string, '%d-%d-%d %d:%d:%d.%d'));
    // or if you want seconds as a float:
    // var_export(sscanf($string, '%d-%d-%d %d:%d:%f'));
    // or if you want seconds as an integer
    // var_export(sscanf($string, '%d-%d-%d %d:%d:%d'));
    

    Output:

    array (
      0 => 2012,
      1 => 1,
      2 => 12,
      3 => 51,
      4 => 0,
      5 => 0,
      6 => 0.5,
    )
    

  • Strings to retain zero padding (and remove delimiting dot)

    var_export(sscanf($string, '%[^-]-%[^-]-%[^ ] %[^:]:%[^:]:%[^.].%s'));
    // or truncate the decimal value
    // var_export(sscanf($string, '%[^-]-%[^-]-%[^ ] %[^:]:%[^:]:%[^.]'));
    

    Output:

    array (
      0 => '2012',
      1 => '1',
      2 => '12',
      3 => '51',
      4 => '00',
      5 => '00',
      6 => '5',
    )
    

  • To merely split on all non-digit characters, preg_split():

    var_export(preg_split('/\D/', $string));
    

    Output (same as second snippet):

    array (
      0 => '2012',
      1 => '1',
      2 => '12',
      3 => '51',
      4 => '00',
      5 => '00',
      6 => '5',
    )
    

*Note, sscanf() also has an alternative usage where individuals can be declared after the second parameter. If declaring variables for the isolated values, the function's return value will become the number of matches that it made.

The second snippet produces the same output as the third and if this is the data that is required, then it makes more sense to use the simpler syntax of preg_split().

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
0

Other variant by regex (if not changed structure)

$re = '/(?<year>\d+)\-(?<month>\d+)\-(?<day>\d+)\s(?<hour>\d+):(?<minutes>\d+):(?<second>\d+)/m';
$str = '2012-1-12 51:00:00.5';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

// Print the entire match result
var_dump($matches[0]);

output:

array(13) {
  [0]=>
  string(18) "2012-1-12 51:00:00"
  ["year"]=>
  string(4) "2012"
  [1]=>
  string(4) "2012"
  ["month"]=>
  string(1) "1"
  [2]=>
  string(1) "1"
  ["day"]=>
  string(2) "12"
  [3]=>
  string(2) "12"
  ["hour"]=>
  string(2) "51"
  [4]=>
  string(2) "51"
  ["minutes"]=>
  string(2) "00"
  [5]=>
  string(2) "00"
  ["second"]=>
  string(2) "00"
  [6]=>
  string(2) "00"
}