0

I need to get UNIX timestamp parsing not-only-numeric dates written in specific locale.
An example date (Italian locale) is:

2014 Settembre 25, 19:12:55

This is the code I currently wrote, but it works only for English locale...:

<?php

  $format = "Y M d, H:i:s";
  $timezone = "Europe/Rome"; # (timezone is not meaningful for this example...)

  $date = "2014 September 25, 19:12:55";
  $locale = "en";
  print date2Timestamp($format, $locale, $timezone, $date);
  # outputs "1411621975", o.k.

  $date = "2014 Settembre 25, 19:12:55";
  $locale = "it";
  print date2Timestamp($format, $locale, $timezone, $date);
  # outputs "PHP Fatal error:  Call to a member function getTimestamp() on a non-object", error!

  /**
    * Converts a date from a custom format to UNIX timestamp.
    *
    * @param string $format   source date format
    * @param string $locale   source locale
    * @param string $timezone source timezone
    * @param string $date     source date to be converted
    * @return string          UNIX timestamp conevrsion of the given date
    */
  function date2Timestamp($format, $locale, $timezone, $date) {
    $oldLocale = setlocale(LC_TIME, 0);
    setlocale(LC_TIME, $locale);
    $dt = DateTime::createFromFormat($format, $date, new DateTimeZone($timezone));
    setlocale(LC_TIME, $oldLocale);
    return $dt->getTimestamp();
  }

?>

So, effectively, as documented, PHP DateTime does not take into account locales... :-(

Any suggestion how to get timestamp from localized date in PHP?

UPDATE: As indirectly suggested in comments, I tested strptime().
It doesn't seem to work as expected, nor even for English formatted dates... :-(

$ php --version
PHP 5.3.3 (cli) (built: Oct 30 2014 20:12:53)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies

<?php
  $locale = "en";
  setlocale(LC_TIME, $locale);

  $format = "%Y %m %d, %H:%M:%S";
  $date = "2014 9 25, 19:12:55";
  print "strptime with decimal month:"; var_dump(strptime($date, $format));

  $format = "%Y %F %d, %H:%M:%S";
  $date = "2014 September 25, 19:12:55";
  print "strptime with textual month:": var_dump(strptime($date, $format));
?>

Output:

strptime with decimal month: array(9) {
  ["tm_sec"]=>
  int(55)
  ["tm_min"]=>
  int(12)
  ["tm_hour"]=>
  int(19)
  ["tm_mday"]=>
  int(25)
  ["tm_mon"]=>
  int(8)
  ["tm_year"]=>
  int(114)
  ["tm_wday"]=>
  int(4)
  ["tm_yday"]=>
  int(267)
  ["unparsed"]=>
  string(0) ""
}
strptime with textual month: bool(false)
MarcoS
  • 17,323
  • 24
  • 96
  • 174
  • is that not strtotime? –  Jan 15 '15 at 11:05
  • @HaltlolXD - Nope! strtotime() — Parse about any __English__ textual datetime description into a Unix timestamp; question is specifically asking about __non-English__ – Mark Baker Jan 15 '15 at 11:08
  • Ah sorry;) I still learn every day! –  Jan 15 '15 at 11:09
  • 1
    http://stackoverflow.com/questions/6988536/strtotime-with-different-languages Someone with same question with answer! –  Jan 15 '15 at 11:10
  • @HaltlolXD: thanks, I didn't notice it. However, as noted in comments, accepted answer explais the problem but does not solve it... Hoewver, another answer suggests `strptime()` (http://php.net/manual/en/function.strptime.php)... It's not supported on Windows, but I don't need it... I will try it, and will post here results... – MarcoS Jan 15 '15 at 13:42
  • strptime() doesn't parse textual dates not even for English, at least until PHP 5.3.3 ... :-( See the update to my question... – MarcoS Jan 16 '15 at 09:11

1 Answers1

0

Eventually, not receiving any answer, I got to this solution...
It looks a bit hacky, but it works:

  /**
    * Converts a *localized* date from format
    * "Year MonthName day, hour:minute:second" to UNIX timestamp
    *
    * @param string $date     source date to be converted
    * @return string          UNIX timestamp conevrsion of the given date
    */
  function date2Timestamp($date) {
    $timestamp = "0";
    for ($m = 1; $m <= 12; $m++) {
      $month_name = ucfirst(strftime("%B", mktime(0, 0, 0, $m))); # get month name for current locale
      if (strstr($date, $month_name)) {
        $date = str_replace($month_name, $m, $date); # replace month name with month number
        $date = preg_replace("/^(\d{4})\s+(\d{1,2})\s+(\d{1,2})/", "$1-$2-$3", $date); # puts dashes to separate Y M D, so strtotime is happy...
        $timestamp = strtotime($date);
        break;
      }
    }
    return $timestamp;
  }

It obviously presumes locale and timezone are already correctly initialized... For example:

setlocale(LC_TIME, "it_IT");
date_default_timezone_set("Europe/Rome");
MarcoS
  • 17,323
  • 24
  • 96
  • 174