2

I am trying to achieve this:

getFormat("Jan 2020") // returns: M Y
getFormat("01 Feb 2020") // returns: d M Y
getFormat("01-January-2020") // returns: d-F-Y

Idea is to basically reverse engineer the php date

This is what I've tried so far:

public function getFormat($date){
    $date = strtolower($date);
    $formats = array(
        "F" => array("january","february","march","april","may","june","july","august","september","october","november","december"),
        "M" => array("jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"),
    );

    foreach($formats as $format=>$data) {
        foreach($data as $d)
            if (stripos($date,$d) !== false) $date = str_replace($d,$format,$date);
    }
    return $date;
}

This would work for months or days but I don't think this technique would ever work for numeric values.

7
  • 1
    good luck: golang.org/src/time/format.go Commented Feb 27, 2020 at 22:02
  • Try this stackoverflow.com/questions/13194322/… Commented Feb 27, 2020 at 22:11
  • Are you wanting to use it for just date strings, or date/time strings as well? Commented Feb 27, 2020 at 22:16
  • Just the date strings Commented Feb 27, 2020 at 22:21
  • 1
    So the strings will always have text as month? 12-12-12 is not possible I hope? Commented Feb 27, 2020 at 22:44

1 Answer 1

1

date_parse () checks whether day, month and year exist in the format. The parts are replaced with the format characters using regular expressions in the config array.

This is not a perfect solution. It is an approach that can be improved.

function getDateFormat($format){
    $parse = date_parse($format);
    if($parse['error_count']) return false;
    $conf = [
        '~\d{4}~' => ['year','Y'],
        '~[a-z]{4,8}~i' => ['month','F'],
        '~[a-z]{3}~i' => ['month','M'],
        '~(?<=[ /\-\.])\d{2}(?=[ /\-\.])~' => ['month','m'],
        '~\d{1,2}(?=[,])~' => ['day','j'],
        '~\d{2}~' => ['day','d'],
        '~\d{1}~' => ['day','j'],
    ];

    foreach($conf as $regEx => $types){
      if($parse[$types[0]] !== false) {
        $format = preg_replace($regEx, $types[1], $format, 1, $count);
        if($count) $parse[$types[0]] = false; ;
      }
    }
    return $format;

}

I haven't fully tested which expressions the function can handle correctly. Here are a few examples:

$data = [
  "Jan 2020","01 Feb 2020","01-January-2020",
  "2020-03-02","05.06.1987", "April 6, 1967",
  "1988", "5. July 1966", 
  "is a Error"

];
foreach($data as $format){
  $frm = getDateFormat($format);
  echo $format." : ".($frm ? $frm : "ERROR")."<br>";
} 

Output:

Jan 2020 : M Y
01 Feb 2020 : d M Y
01-January-2020 : d-F-Y
2020-03-02 : Y-m-d
05.06.1987 : d.m.Y
April 6, 1967 : F j, Y
1988 : Y
5. July 1966 : j. F Y
is a Error : ERROR
Sign up to request clarification or add additional context in comments.

2 Comments

I'll give it an upvote for good effort, but it doesn't solve it all. Such as April 16, 1967 will return F d, Y but it could be F j, Y we just don't know.
I added a regEx in case a comma follows the day. With a date template like April 16, 1967, it is not entirely clear to me whether the day should be output with j or d. Just like in your comment from 12.12.12, there are other cases that cannot be solved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.