Самый безопасный способ сохранения неожиданных форматов времени в MySQL с помощью PHP - PullRequest
1 голос
/ 09 декабря 2010

Мне нужно собирать даты из разных форматов и сохранять их в MySQL. Подано Date (ГГГГ-ММ-ДД, я считаю), так как я могу изменить такие форматы, как 24.12.2010, 24.12.2010, 12 -10-2010 и все такое с PHP?

Я знаю, что есть mktime, strtotime, но как я могу сделать это безопасно?

ОБНОВЛЕНИЕ: безопасно с точки зрения точности! :)

Ответы [ 4 ]

2 голосов
/ 09 декабря 2010

... форматы, такие как 24.12.2010, 24.12.2010 ...

Ваша основная проблема здесь в том, что dd/mm/yyyy часто неотличим от mm/dd/yyyy.

Если вы получите 11/12/2010, как вы узнаете, в каком формате он должен быть?strtotime() вам там не поможет.

Если вы планируете использовать strtotime(), стоит указать, что если вы дадите ему 11/12/2010 (то есть с разделителями слеша), он будет обрабатываться какmm/dd/yyyy, но если вы укажете 11-12-2010 (разделители тире), он будет обрабатываться как dd-mm-yyyy.Но поскольку оба формата обычно пишутся в обоих направлениях, это различие не только бессмысленно, но фактически делает функцию strtotime() слишком непредсказуемой для реального использования.

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

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

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

Если данные поступают из какого-то другого источника, который вы не можете контролировать, и выЕсли вы получаете неоднозначные данные, вам нужно либо просто принять, что вы иногда ошибаетесь, либо спросить конечного пользователя / daЧтобы уточнить, что они имели в виду.

2 голосов
/ 09 декабря 2010

Вы не можете: рассмотрите мм / дд / гг гг гг / мм / дд v дд / мм / гг на дату 9 ноября 2010 года.

Вам нужно знать тот формат, в котором они это сделалив перед рукой.Единого решения не существует.

0 голосов
/ 09 декабря 2010

Вы могли бы попробовать следующее, если вам действительно нужно (постарайтесь избежать этого, другие говорили, почему):

$mysql_timestamp = date("Y-m-d",strtotime($unknown_timestamp));
0 голосов
/ 09 декабря 2010

Если у вас уже есть эти даты под рукой, у вас может быть много работы впереди, но если вам нужно собрать ее, вы можете легко форсировать стандарт через формы

Month : [   ] / Day : [   ] / Year : [    ] 

, а затем выпостроить вашу дату через mktime / date в PHP

Но если у вас уже есть данные, вам, возможно, придется создать некоторые правила для пометки странных данных, так как strtotime () будет работать в зависимости от вашей локали (французский и английский)даты не пишутся одинаково, например: французская дата дд / мм / гггг и английская мм / дд / гггг).

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

, т. е .: 24.12.2010 (идеально подходит для английского формата даты, но это будет 12.12.2011 на французском языке (обратите внимание на изменение года)).

Редактировать:

Вот начало просмотра ваших дат перед их преобразованием:

<?php

$dates = array('12-12-2010', '24-12-2010','12-24-2010','12-24-10','24-12-10',
               '12-12-10','12/12/2010','24/12/2010','12/24/2010', '12/24/10',
               '24/12/10', '12/12/10','2010-12-12', '2010-24-12','2010-12-24',
               '10-12-24','10-24-12','10-12-12','2010/12/12','2010/24/12',
               '2010/12/24', '10/12/24','10/24/12','10/12/12','11-11-2011');

$regEx = array('YYYY-MM-DD' => '/^(19|20)\d\d[- \/.](0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])$/',
               'MM-DD-YYYY' => '/^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]((19|20)\d\d)$/',
               'DD-MM-YYYY' => '/^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.](\d\d)$/',
               'YY-MM-DD' => '/^\d\d[- \/.](0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])$/',
               'MM-DD-YY' => '/^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](\d\d)$/',
               'YY-DD-MM' => '/^\d\d[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])$/',
               'No Match' => '//' );


echo '<table style="table-layout:fixed;width:400px">';
echo '<tr>'.'<th>'.'Date'.'</th>'.'<th>'.'PATTERN'.'</th>'.'</tr>';

foreach($dates as $date){
echo '<tr>';
    echo '<td>';
    echo $date . ' ';
    echo '</td>'.'<td>';
    foreach($regEx as $name=>$pattern)
        if(preg_match($pattern, $date)){
            echo $name;
            break;
        }
    echo '</td>';

echo '</tr>';

} echo '';?>

, который даст вам стол, подобный

+-------------+-------------+
| Date        | PATTERN     | 
+-------------+-------------+
| 12-12-2010  | MM-DD-YYYY  | 
| 24-12-2010  | No Match    | 
| 12-24-2010  | MM-DD-YYYY  | 
| 12-24-10    | MM-DD-YY    | 
+-------------+-------------+

. Из этой корзины будет возможность создать подстроку, чтобы захватить нужные части

...