Дата и время из строк в различных форматах - PullRequest
0 голосов
/ 04 мая 2018

Клиенты создают билеты для моей команды с задачами, которые нужно выполнять в разное время. Дата и время указаны в описании, но формат может отличаться для каждого билета, например:

Todo: четверг 26 апреля в 19

Todo: ср 25/04/2018 с 14:00 до 14:30

Todo: понедельник, 25/04 между 11 и 11: 30

Todo: 30.03.2018 13:30 - 14:00

Я создал функцию, которая берет строку, содержащую дату и время (после взрыва в двоеточии) и пытается преобразовать ее в стандартный формат, который можно использовать в поле datetime-local (не заботятся о секундах ).

public static function getDatetime ( string $datetime )
{
    $formats[] = "dS * F * G?i+";
    $formats[] = "* dS * F * G?i+";
    $formats[] = "D d#m#Y * G#i+";
    $formats[] = "d M Y * G:i+";
    $formats[] = "* d F Y G?i+";
    $formats[] = "* d F Y * G?i+";
    $formats[] = "* j F * g#i A+";
    $formats[] = "* j F * h A+";
    $formats[] = "*# d F * g#i a+";
    $formats[] = "*# M d Y * G?i+";
    $formats[] = "*# F d * g a+";
    $formats[] = "* d F * G\hi+";
    $formats[] = "* d#m * G:i+";
    $formats[] = "d#m#Y G\hi+";
    $formats[] = "d#m#Y * G?i+";
    $formats[] = "* d#m#Y G\Hi+";
    $formats[] = "* d#m#Y * G\hi+";
    $formats[] = "d#m#Y * G\h+";
    $formats[] = "* d#m#Y * G\h+";
    $formats[] = "* dS * F, * G\h+";
    $formats[] = "* dS F * G\h+";
    $formats[] = "* d * M Y * G?i+";
    $formats[] = "dS * F * G+";
    $formats[] = "* dS * F * G+";
    $formats[] = "* dS F Y * G?i+";
    $formats[] = "* d#m#Y * G?i+";
    $formats[] = "* d#m#Y * G+";
    $formats[] = "*# dS M Y * G?i+";
    $formats[] = "*# dS M Y * G+";
    $formats[] = "d S * M * G+";

    foreach ( $formats as $format )
    {
        if ( DateTime::createFromFormat ( $format, $datetime ) !== false )
        {
            return DateTime::createFromFormat ( $format, $datetime )->format ( 'Y-m-d\TH:i' );
        }
    }

    return;
}

Как вы можете видеть, я создал массив из примерно 20 форматов, по которому я зацикливаюсь, и возвращаю отформатированную дату, как только строка соответствует формату. Чтобы это работало, я должен добавить более специфичные форматы перед более общими в массиве.

Эта функция работает примерно в 80-90% случаев, с которыми я сталкивался до сих пор, за исключением случаев с опечатками или строками, которые даже не читаются человеком.

Проблема в том, что клиенты могут произвольно решить, скажем, добавить запятую, чтобы отделить название и дату дня, или инвертировать номер дня и месяц, и в этом случае мне нужно создать новый формат.

Простой пример:

$datetime = "Monday, 08 January at 8:00 am";
$formats[] = "*# d F * g#i a+";

$datetime = "Thursday, April 18 at 7:30 pm";
$formats[] = "*# F d * g#i a+";

Прежде чем создать эту функцию, я пытался использовать preg_replace и str_replace, чтобы сохранить только то, что мне нужно, из строки, а затем передать ее на strtotime, но это было определенно хуже!

Мой вопрос: есть ли лучший способ сделать это? Если нет, могу ли я хотя бы сделать что-то простое, чтобы избежать большого количества форматов (например, первых 2) для строк, которые очень похожи?

Спасибо!

1 Ответ

0 голосов
/ 04 мая 2018

хорошо, чтобы избежать слишком большого количества форматов, вам нужно ограничить способ предоставления этой информации вашим клиентом (например, для веб-приложения, вместо того, чтобы использовать текстовое поле, где пользователь может поместить произвольный текст в любом формате, используйте элемент управления календаря, который возвращать только определенный формат), это может избежать опечаток и неправильной даты (например, 30 февраля).

В противном случае, как вы сказали, клиент может просто продолжать добавлять новый формат :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...