I’m using DateTime::createFromFormat()
on a date that use some text like “April 15, 2016”
It’s perfectly working as long as I’m using English culture.
April 15, 2016 -> ok
My code is set as WordPress plugin. Please understand that I have no control over the component that give me the date (as text) and the WordPress settings. If user set the WordPress installation on another language, the date will change from “April 15, 2016” to let’s say (if French) “Avril 15, 2016”.
It looks like that DateTime::createFromFormat()
don’t support other language than English so “April 15, 2016” will end up with:
“Fatal error: Call to a member function format() on boolean”
Did somebody have an idea how we can handle month date as text in several language? Using DateTime::createFromFormat()
or another method in php?
Thanks
There are two ways to do this, but both depend on how exactly the input is generated …
This is the simple/naive and most obvious way, I don’t think the way to do this needs explaining.
However, depending on how WordPress (and/or the plugin that you’re using) works, it may also be your only option.
IntlDateFormatter
classThis is the purely programmatic way and therefore what would be considered the “proper” one, but unfortunately this class comes as part of a PECL extension – intl – and isn’t bundled with PHP.
It also requires that you know the language being used before parsing the date, but that shouldn’t be a problem as that is how all localization solutions should work in the first place, so I assume this information is available to you in WordPress.
pickdate.js also seems to work with standard locales by default.
That being said, here’s how it works:
It’s worth noting that
IntlDateFormatter
is designed mainly for creating localised outputs (and rightly so – you shouldn’t be parsing a translated month name in the first place, or a name at all for that matter; numbers FTW), so we are indeed writing a lot of irrelevant stuff here.For your use case, only the
$locale
and$inputFormat
parameters matter.There’s one more caveat though – we need a timezone!
You can get it via (preferrably)
$dateFormatter->getTimeZone()
or in this case justdate_default_timezone_get()
, but you do need the timezone for two reasons:IntlDateFormatter::parse()
assumes “00:00:00”.IntlDateFormatter::parse()
will take that into account andDateTime::createFromFormat('U', $unixTimestamp)
will set the object’s timezone to UTC!If you’re in another timezone, and more specifically in one on the east side of the world, this will happen:
You could tell
IntlDateFormatter
that you’re in UTC in the first place, but that’s technically cheating (wink) and depending on what you’re using$dateTime
for later, it may cause side-effects.