Convert a PHP date format to a jQueryUI Datepicker date format
Asked Answered
T

5

15

[EDIT] : I guess people had problem to understand exactly what I mean, so I completely rewrote my explanations.

I work on a project where users can define a date format used in the whole site. It uses PHP date format standard. For example : "year-month-day" is set by "Y-m-d".

PHP standard uses single-character symbols like Y, m, d, F, j to describe the date format. As seen in the documentation : http://www.php.net/manual/en/function.date.php

Sometimes users can select a date thanks to a jQueryUI Datepicker. This component describes its date format with code-words like yy, y, mm, dd, D, ... http://api.jqueryui.com/datepicker/#utility-formatDate

I would like to display the dates in the same format for both PHP and the Datepicker. I mean that PHP should output the date as in the format set by user, AND the Datepicker should show the selected date in the same format.

Given that:

  1. The date format is necessarily described "PHP style"
  2. I can't know a priori which format was set by users

/!\ This not a problem of how to read/parse/display a date from a known format.

Unfortunately, Javascript date format description is not the same as in PHP. For instance, these 2 date formats are equivalent but described differently in PHP and Javascript:

  1. PHP : Y-m-d (set by users)
  2. Javascript : yy-mm-dd

As you can see, I cannot just configure the datepicker with the PHP date format, because it will be misunderstood, or not recognized at all.

Someone (in answers below) adviced to create my own "date format standard converter", matching each PHP symbol with its equivalent in JS date format description. Just like:

  • Y => yy
  • m => mm
  • d => dd
  • y => y
  • z => o
  • ...

And then replace each PHP symbol with the JS one. And so "d/m/Y" will be translated into "dd/mm/yy", magically.

But maybe somebody knows another proper way to make jQueryUI Datepicker understand PHP date format standard?

EDIT: I wrote a tutorial that explains both the problem and the solution. For further reading : http://tristan-jahier.fr/blog/2013/08/convertir-un-format-de-date-php-en-format-de-date-jqueryui-datepicker

Transsonic answered 22/5, 2013 at 22:6 Comment(3)
Do not send aribtrary date formats out of PHP -- always send in the known fixed format, so that Javascript will know what to expect. Don't expect to be able to "handle automatically any date format", because that's fundamentally impossible to get right (due to the ambiguity between various commonly-used formats). The whole point of using a javascript date picker is that your code should never need to have to handle dates in any format; you as the programmer should be in complete control of the format, so just pick a good one (yyyy-mm-dd is generally best) and stick with it.Delainedelainey
I understand what you think about. But this is not really my issue. In fact, I would like the user to see the date displayed by Datepicker in the same format as it is displayed by : echo $date->format("any_format");Transsonic
vlttp: this is a thing that sent me crazy all the times. Every other language I've used in the last 20 years uses single char for single digit and double char for double digit with eventual padding with zero. Why the hell PHP -that is almost perfect in everything else- has to be so different in this? And, in an area (Dates) that already is pretty chaotic by itself!!Legra
T
35

I chose the brutal method : converting symbol-by-symbol the date format. I made a 'not-so-dummy' code snippet.

/*
 * Matches each symbol of PHP date format standard
 * with jQuery equivalent codeword
 * @author Tristan Jahier
 */
function dateformat_PHP_to_jQueryUI($php_format)
{
    $SYMBOLS_MATCHING = array(
        // Day
        'd' => 'dd',
        'D' => 'D',
        'j' => 'd',
        'l' => 'DD',
        'N' => '',
        'S' => '',
        'w' => '',
        'z' => 'o',
        // Week
        'W' => '',
        // Month
        'F' => 'MM',
        'm' => 'mm',
        'M' => 'M',
        'n' => 'm',
        't' => '',
        // Year
        'L' => '',
        'o' => '',
        'Y' => 'yy',
        'y' => 'y',
        // Time
        'a' => '',
        'A' => '',
        'B' => '',
        'g' => '',
        'G' => '',
        'h' => '',
        'H' => '',
        'i' => '',
        's' => '',
        'u' => ''
    );
    $jqueryui_format = "";
    $escaping = false;
    for($i = 0; $i < strlen($php_format); $i++)
    {
        $char = $php_format[$i];
        if($char === '\\') // PHP date format escaping character
        {
            $i++;
            if($escaping) $jqueryui_format .= $php_format[$i];
            else $jqueryui_format .= '\'' . $php_format[$i];
            $escaping = true;
        }
        else
        {
            if($escaping) { $jqueryui_format .= "'"; $escaping = false; }
            if(isset($SYMBOLS_MATCHING[$char]))
                $jqueryui_format .= $SYMBOLS_MATCHING[$char];
            else
                $jqueryui_format .= $char;
        }
    }
    return $jqueryui_format;
}

This function handles all the common codewords between PHP and Datepicker date format standards.

Plus, I added support for character escaping :

d m \o\f Y becomes dd mm 'of' yy

You may still have problems with symbols like 'W', 'L' that have no equivalent handled by Datepicker.

Transsonic answered 23/5, 2013 at 23:3 Comment(3)
You're welcome. ;-) Please thumb up this answer if you find it useful and relevant.Transsonic
Hello @TristanJ, the snippet above doesn't seem to be able to support time to me. What is the reason for that? Is there any inconsistency between the two standards or you just wanted to create the date format converter?Washout
Hi @gen. This is because I was using jQuery UI's "Datepicker" (i.e.: http://jqueryui.com/datepicker) and it does not support time. That's why I've never thought of that. But you should be able to add time support easily. Just look for the symbols your "date & time picker" supports and report the changes in the $SYMBOLS_MATCHING array.Transsonic
P
4

You cannot use the same format with datepicker that you're using with PHP.

Since PHP's date format only uses single letter codes, you're better off just taking the PHP date format and replacing each code to the corresponding value in the jQuery datepicker format, e.g.:

$PHPFormatOptions = array('y', 'Y', 'm', 'd');
$JSFormatOptions = array('yy', 'yyyy', 'mm', 'dd'); // and so on
$JSFormat = str_replace($PHPFormatOptions, $JSFormatOptions, $PHPFormat);
Prosthodontics answered 22/5, 2013 at 22:20 Comment(2)
So, you advice to create a kind of dictionary matching each symbol together ?Transsonic
I hope there is no ambiguous case.Transsonic
J
2

Here is the solution:

function datepicker_format($format) {
        static $assoc = array(
            'Y' => 'yyyy',
            'y' => 'yy',
            'F' => 'MM',
            'm' => 'mm',
            'l' => 'DD',
            'd' => 'dd',
            'D' => 'D',
            'j' => 'd',
            'M' => 'M',
            'n' => 'm',
            'z' => 'o',
            'N' => '',
            'S' => '',
            'w' => '',
            'W' => '',
            't' => '',
            'L' => '',
            'o' => '',
            'a' => '',
            'A' => '',
            'B' => '',
            'g' => '',
            'G' => '',
            'h' => '',
            'H' => '',
            'i' => '',
            's' => '',
            'u' => ''
        );

        $keys = array_keys($assoc);

        $indeces = array_map(function($index) {
            return '{{' . $index . '}}';
        }, array_keys($keys));

        $format = str_replace($keys, $indeces, $format);

        return str_replace($indeces, $assoc, $format);
    }

The magic double str_replace call caused by duplicating in needles and its replacement values, so that's why the string

m/d/Y 

becomes

{{3}}/{{5}}/{{1}}

and after that this nests replacing with actual replacement values:

mm/dd/yy
Jaredjarek answered 19/3, 2017 at 12:22 Comment(0)
I
1

Not sure I'm quite with you, but this really shouldn't be an issue. You could either parse the front-end input: using DateTime::createFromFormat cf. php documentation for this, or use JSON.
Since JSON has an accepted standard way of formatting date strings, you can pass a JSON-stringified version of the input date to PHP, and json_decode it server-side. Both of these solutions are open to you, though I believe the first one to be easier to implement in your case.

If you want to be able to choose the format on both sides, the DateTime object is definitely what you need:

$date = new DateTime();
echo $date->format('Y-m-d').' <==> '.$date->format('y-M-j');
$postDate = $date->createFromFormat('y-m-d',$_POST['submitDate']);
echo $postDate->format('Y-m-d');

The format is explained on the page I've linked to.

Idalla answered 22/5, 2013 at 22:38 Comment(4)
I think it's not about parsing input per se, it's about date format strings and converting between PHP's date format string and jQuery's date format string, i.e., literally between Y-m-d and yy-mm-dd.Prosthodontics
Then the first option is the best way to go, I'll just add look into the DateTime objectIdalla
In fact, I have not problem with parsing a date from a given date format. It's about making Datepicker accept the date format I get from PHP.Transsonic
@TristanJ: Well then, either use the DateTime object, and send a different format to the datepicker, or use json_encode, because the JSON encoded date is a standard format, which JS will convert to a date objectIdalla
C
-3

Ok so the best solution for you would be to store everything in your website using time();

As far as I know datepicker can be set to work with dates for PHP timestamp

dateFormat : 'yy-mm-dd',

Edit :

Why would you store a date like : Y-m-d ? It should be stored as timestamp or int

Corpus answered 22/5, 2013 at 23:26 Comment(1)
It is not about conversion of the date, nor date storage. I want the datepicker to be able to handle the same date format standard that is displayed on the site. BUt for any standard, that's why I can't right it hard.Transsonic

© 2022 - 2024 — McMap. All rights reserved.