使用 PHP 在 MySQL 中保存意外时间格式的最安全方法

发布于 2024-10-06 16:18:01 字数 237 浏览 6 评论 0原文

我必须收集不同格式的日期并将它们保存在 MySQL Filed Date 中(我认为是 YYYY-MM-DD),那么我如何更改格式,例如 12/24/2010、24/12/2010 ,12-10-2010 以及类似 PHP 的东西?

我知道有 mktimestrtotime 但我怎样才能安全地做到这一点?

更新:从准确性的角度来看是安全的! :)

I have to collect dates from different formats and save them in MySQL Filed Date (YYYY-MM-DD I reckon), so how can i change formats like 12/24/2010, 24/12/2010, 12-10-2010 and stuff like this with PHP ?

I know there is mktime, strtotime but how can i do it safely ?

UPDATE: safe from accuracy point of view! :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

二智少女猫性小仙女 2024-10-13 16:18:01

您不能:考虑 2010 年 11 月 9 日的日期为 mm/dd/yy v yy/mm/dd v dd/mm/yy。

您需要事先知道他们使用的格式。没有一次性的解决方案。

You can't: consider mm/dd/yy v yy/mm/dd v dd/mm/yy for the date November 9th 2010.

You would need to know that format that they did it in before hand. There is no one-off solution.

无风消散 2024-10-13 16:18:01

...格式如 12/24/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),从而消除任何可能的歧义。

如果数据来自您无法控制的其他来源,并且您收到的输入不明确,那么您需要要么接受有时会出错的事实,要么询问最终用户/数据提供者澄清他们的意思。

...formats like 12/24/2010, 24/12/2010...

Your basic problem here is that dd/mm/yyyy is often indistinguishable from mm/dd/yyyy.

If you get 11/12/2010, how will you know which format it is supposed to be? strtotime() won't help you there.

If you do plan to use strtotime(), it's worth pointing out that if you give it 11/12/2010 (ie with slash separators), it will treat it as mm/dd/yyyy, but if you give it 11-12-2010 (dash separators), it will treat it as dd-mm-yyyy. But because both formats are commonly written both ways, that distinction is not only pointless but actually makes the strtotime() function too unpredictable for real-life use.

If you do already know the format of any specific incoming date string, then your best best is to split it into its component parts using preg_match() or similar, and re-build it using mktime().

If you don't know the format that was intended by the user then you can guess, but if its ambiguous then there's always a chance you'll get it wrong.

If this is coming from a web site input form, you would be better advised to provide a front-end control in Javascript that always sends the date in a known format (preferably yyyy-mm-dd), and thus removing any possible ambiguity.

If the data is coming from some other source that you can't control, and you're getting ambiguous input then you need to either just accept that you're going to get it wrong some of the time, or ask the end user / data provider to clarify what they meant.

当梦初醒 2024-10-13 16:18:01

如果确实有必要的话,你可以尝试以下操作(尽量避免它,其他人说了原因):

$mysql_timestamp = date("Y-m-d",strtotime($unknown_timestamp));

you could try the folowing if you realy have to (try to avoid it, others said why):

$mysql_timestamp = date("Y-m-d",strtotime($unknown_timestamp));
谁的年少不轻狂 2024-10-13 16:18:01

如果您手头已经有了这些日期,那么您可能需要做很多工作,但是如果您必须收集它们,您可以轻松地通过表单强制执行标准

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

,然后通过 PHP 中的 mktime / date 构建日期

但是如果您手头已有数据,您可能需要制定一些规则来标记奇怪的数据,因为 strtotime() 将根据您的语言环境工作(法语和英语日期的书写方式不同,即:法语日期 dd/mm/YYYY 和英文月/日/年)。

您必须定义要使用的格式,并标记所有不适合手动返工的数据

,即:12/24/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>';

}
回声'';
?>

这将为您提供一个类似

+-------------+-------------+
| 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    | 
+-------------+-------------+

From 的表格,它将有一种方法可以继续构建子字符串以获取正确的部分

If you already have thoses dates at hand, you might have a lot of work ahead of you, but if you have to collect it you can easily force a standard through forms

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

and then you build your date through mktime / date in PHP

But if you have already the data at hand, you might have to make some rules to flag weird data since strtotime() will work based on your locale (french and english dates aren't written the same way ie : french date dd/mm/YYYY and english mm/dd/YYYY).

You would have to define a format you want to use and flag all data that doesn't fit in it for manual rework

ie : 12/24/2010 (perfectly makes sense in english date format but that would be 12/12/2011 in french (notice the year change)).

Edit :

Here is a start to review your dates before converting them :

<?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 '';
?>

which will give you a table like

+-------------+-------------+
| 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    | 
+-------------+-------------+

From that woul will have a way to proceed for building your substring to grab the right parts

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文