How algorithm of strtotime(PHP Date function) Works? - php

i wanna to know how strtotime (php Date function) work?
how Parse string Like "15 September 2012" to timeStamp
is there any better algorithm?
my purpose is changing this function for Persian Language

You can browse the source code of PHP ( https://github.com/php/php-src) and search function to see its implementation.
UPDATE
Here is the algorithm of the function strtotime () https://github.com/php/php-src/blob/master/ext/date/php_date.c#L1324
Regards!.

The method that actually parses the string is in parse_date.re's scan() method. There you will find all strtotime keywords and their behaviors.
That library is included from https://github.com/derickr/timelib.

since strtotime accepts English input, I'd recommend taking the Persian input:
"15 (SOMETHING_PERSIAN) 2012" and replace the required string (you need some RegExp and a switch statement, I guess) and make it "15 (SOMETHING_ENGLISH) 2012" and THEN send it to strtotime

i wanna to know how strtotime (php Date function) work?
Go here: https://github.com/php/php-src/blob/master/ext/date/lib/parse_date.c
Search for timelib_strtotime.

forget about it, use php Intl extension. in future will be a part of php core.
<?php
// format
$format = datefmt_create('fa_IR#calendar=persian', IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'Asia/Tehran', IntlDateFormatter::TRADITIONAL, 'yyyy/MM/dd HH:mm');
// time in locale as you wish
var_dump(datefmt_format($format, time())); // '۱۳۹۱/۰۲/۰۴ ۱۹:۱۵'
support ICU project if you want to support Persian in i18n for all languages.
php intl extension
icu-project.org

Related

PHP DateTime::createFromFormat and multi languages

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 ...
Maintain an array of month name translations
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.
The IntlDateFormatter class
This 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:
// See http://userguide.icu-project.org/formatparse/datetime
$inputFormat = 'MMMM dd, yyyy';
$inputDate = 'Avril 15, 2016';
$locale = 'fr_FR';
// Here comes the magic ...
$dateFormatter = new IntlDateFormatter(
$locale,
IntlDateFormatter::LONG, // Not really important, may even be NONE
IntlDateFormatter::NONE, // Time ... we're not using it
NULL, // Will use date_default_timezone_get()
NULL, // Calendar; we don't need it
$inputFormat
);
// Will return bool(false) on failure, use getErrorMessage() for debugging
$unixTimestamp = $dateFormatter->parse($inputDate);
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 just date_default_timezone_get(), but you do need the timezone for two reasons:
You don't have a time value in your input, so IntlDateFormatter::parse() assumes "00:00:00".
UNIX timestamps are always in UTC, so IntlDateFormatter::parse() will take that into account and DateTime::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:
$dateTime = DateTime::createFromFormat('U', $unixTimestamp);
var_dump($dateTime->format('Y-m-d')); // string(10) "2016-04-14" !!!
$dateTime->setTimeZone(new DateTimeZone($timezone));
var_dump($dateTime->format('Y-m-d')); // string(10) "2016-04-15"
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.

PHP date format with intl-aware day suffix?

Sorry if this is a dupe - lots of similar questions but obviously if I could find an exact answer I wouldn't be asking :)
Note I'm coming from .Net and am a PHP newbie, so there may be noob-scale errors.
I would like to be able to output e.g. new DateTime('2014-01-01 13:15:00') as:
'Wednesday the 1st of January 2014 at 1:15PM' (possible - non-localized) or 'Mercredi 1er Janvier 2014 à 13h15' (not possible?).
Basically, there seems to be no ISO formatting equivalent to PHP's 'S' date format specifier, nor is there one for strftime?
The IntlDateFormatter::FULL comes close - but 'Wednesday, 1 January' or 'mercredi 1 janvier' is not good English (or French) - but it seems to be the closest that I can get? I could live without the 'on', 'the' and 'at' if I had to, but ordinal suffixes would be nice. ('Wednesday one January' - what's that, the beginning to a poem?)
I did see one example on the strftime section comments on PHP.net addressing this issue (which seems to suggest that it is an issue) - however it only seemed to add the English suffixes, which didn't seem much use? I'd like a simple method that takes a UTC datetime, a locale and a timezone and outputs a localized string - preferably in 'proper' human-readable format (as above) as is possible in English. I'd like to achieve this without writing a format string for every language in the world. It would also be nice if it worked on my Windows dev box as well as the *nix production box.
<?php
$utcdate = new DateTime('2014-01-01 13:15:00', new DateTimeZone('UTC'));
echo $utcdate->format('l \t\h\e jS \o\f F Y \a\t g:ia') . "<br>";
function dumpDates($date, $locale, $tz){
$date->setTimeZone(new DateTimeZone($tz));
$fmt = new IntlDateFormatter( $locale, IntlDateFormatter::FULL, IntlDateFormatter::FULL,
$tz, IntlDateFormatter::GREGORIAN );
echo $fmt->format($date) . "<br>";
// doesn't work under windows?
setLocale(LC_TIME, $locale);
echo strftime('%A, %#d %B %Y %I:%M:%S %p', $date->getTimeStamp()) . "<br>";
}
dumpDates($utcdate, 'en_GB', 'Europe/London');
dumpDates($utcdate, 'de_DE', 'Europe/Berlin');
dumpDates($utcdate, 'fr_FR', 'Europe/Paris');
?>
The full part of this question - including full grammatical legibility - would be very difficult to do without either, as you say, writing a format string for every language in the world, or finding a library that contains such strings. MomentJs seems to provide great intl support, but after a cursory search, I haven't been able to find a PHP equivalent, other than the intl extension.
You could get to the stage of providing an internationalised form including ordinal-based number by using a combination of IntlDateFormatter and NumberFormatter, by first using NumberFormatter to get the pattern for the date's ordinal suffix/prefix:
$numFmt = new NumberFormatter('fr_FR', NumberFormatter::ORDINAL);
$ordinalDay = $numFmt->format($date->format('j'));
You could then create a IntlDateFormatter that allows you to retrieve the pattern for the Full date format of the target language:
$dateFormat = new IntlDateFormatter('fr_FR', IntlDateFormatter::FULL, IntlDateFormatter::FULL, $tz, IntlDateFormatter::GREGORIAN);
$datePattern = $dateFormat->getPattern();
Finally, you would need to replace the section in the $datePattern representing the day with the escaped ordinal day pattern:
$datePattern = preg_replace('/d+', "'"+$ordinalDay+"'", $datePattern);
$dateFormat->setPattern($datePattern);
$outputDate = $dateFormat->format($date);
Note that the pattern used by IntlDateFormatter is different from the usual PHP date formatting format codes, here is the documentation for the codes recognised.
A warning; in internationalised formats that are fairly rigidly standardized, an ordinal number would look out of place. For example in chinese, the format is:
y年M月d日EEEE
and inserting the ordinal prefix that exists for written Chinese before the day value may look odd to a Chinese reader.

Django equivalent of PHP's date

Does anybody know something similar to function date() from PHP in Django?
I'm starting to learn this nice framework, I'm very happy with it (at the momment) but i haven't found that function
Yes.
date
Formats a date according to the given format.
Uses a similar format as PHP’s date() function (http://php.net/date) with some differences.
For example, you can do:
{{ value|date:"D d M Y" }}
If value is a datetime object (e.g., the result of datetime.datetime.now()), the output will be the string 'Jul 22 2013'.
Documentation:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
https://docs.djangoproject.com/en/dev/ref/settings/#date-format
https://docs.djangoproject.com/en/dev/topics/i18n/timezones/#naive-and-aware-datetime-objects

Change the language for date in php

I have this MySQL query, which returns two dates (which are both formatted as a-m-Y). Now I want to translate this date into my own language (Danish). How can I do that.
I have tried both the setlocale() and strftime() functions, but it won't work.
I know it's a very basic question, but i really need help :) Thanks a lot!
I found that setlocale isn't reliable, as it is set per process, not per thread (the manual mentions this). This means other running scripts can change the locale at any time. A solution is using IntlDateFormatter from the intl php extension.
Install intl if necesarry (ubuntu): sudo apt-get install php5-intl
Install the locale you want to use (I'm using italian as an example): sudo locale-gen it_IT
Generate a locally formatted date:
$fmt = new \IntlDateFormatter('it_IT', NULL, NULL);
$fmt->setPattern('d MMMM yyyy HH:mm');
// See: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax for pattern syntax
echo $fmt->format(new \DateTime());
// Output: 6 gennaio 2016 12:10
Use setlocale and strftime together:
setlocale(LC_TIME, array('da_DA.UTF-8','da_DA#euro','da_DA','danish'));
echo strftime("%A"); // outputs 'tirsdag'
Works on my php installation on Windows.
strftime(): Warning! This function has been DEPRECATED as of PHP 8.1.0. Relying on this function is highly discouraged.
Use
http://php.net/manual/en/function.strftime.php
<?php
setlocale(LC_ALL, 'da_DA');
echo strftime("%A %e %B %Y");
?>
I don't think the date() function is quite evolved enough for you, here.
Instead, I would recommend you take a look at the IntlDateFormatter1 class (quoting) :
Date Formatter is a concrete class that enables locale-dependent
formatting/parsing of dates using pattern strings and/or canned
patterns.
There are a couple of examples on the manual page of IntlDateFormatter::format(), where that method is used to display a date in two different languages, by just setting the desired locale.
1. bundled with PHP >= 5.3
This Will Surely works for you if you want norwegian date and month format
$date = '2016-11-16 05:35:14';
setlocale(LC_TIME, array('nb_NO.UTF-8','nb_NO#norw','nb_NO','norwegian'));
echo strftime("%e %b %Y",strtotime($date));
if you want to get other language locale ids like nb_NO then refer this site
International Components for Unicode (ICU) Data
If you are trying to convert a datetime try this:
$fecha = $dateConsulta->format('d-M-Y');
$fecha = str_replace('Jan','Ene',$fecha);
$fecha = str_replace('Apr','Abr',$fecha);
$fecha = str_replace('Aug','Ago',$fecha);
$fecha = str_replace('Dec','Dic',$fecha);

what is the best method to translate strings to mysql dates?

What is the best way in php to take the following string mm[some char]dd[some char]yyyy and translate it to yyyymmdd?
I will probably want in the future, according to local do the same with dd[some char]mm[some char]yyyy.
If there is a way that already uses the Zend Framework API, the better
<?php
$str = '08-24-1989'; // can be in any recognizable date format.
$new_str = date('Ymd', strtotime($str)); // produces "20090824".
?>
You can replace Ymd in the second statement above with any date format characters found here.
If you're looking to use Zend's Zend_Date framework, check out some examples and documentation here. Quite frankly though, the PHP functions are a lot simpler and easier to use in your case.
date('Ymd', strtotime($time));
Strtotime is absolutely the best tool to translate almost any time format into a standard one that you can then use Date to put into the format you want.
Because you question title says MySQL Dates, this is the string format that mysql uses.
date('Y-m-d h:i:s', strtotime($time));
Unless [some char] varies , use the mysql str_to_date function, e.g. STR_TO_DATE('12|23|2009','%m|%d|%Y');
I would absolutely use TIMESTAMP for any date storage. It's incredibly easy to handle time differences (like SELECT ... WHERE date BETWEEN 2138728753 AND 376251237) and can be translated to any locale pretty easily :)

Categories