mysql 的 str_to_date() 的 php 版本

发布于 2024-10-25 22:34:20 字数 439 浏览 2 评论 0原文

我在我公司的代码库中遇到过这个,我想将其更改为不连接到 mysql 的东西,只是一个函数:

$sql = "select date_format(str_to_date('$date','$format'),'%Y-%m-%d') startDate ";
$result = mysql_query($sql);
...

我们的生产环境是 unix 类型,我的开发环境也是如此,但有些人在 Windows 环境上编写代码,因此 strptime() 不是一个选项。

我见过类似的问题,但没有一个答案符合我的需求。是否有一种简单或常见的方法可以使用变量格式从字符串中提取日期?

日期格式差异如此之大的原因是因为我们正在解析供应商的文件名,因此我们必须能够处理 yyyymmdd、mmddyyyy、ddmmyyyy、ddmonyyyy 等。

I've come across this in my companies code base, and I'd like to change it to something that doesn't connect to mysql just to just a function:

$sql = "select date_format(str_to_date('$date','$format'),'%Y-%m-%d') startDate ";
$result = mysql_query($sql);
...

Our production env is of the unix variety, as is my dev environment, but some people write code on a windows environment, so strptime() isn't an option.

I've seen similar questions floating around SO, but none with an answer that fits my needs. Is there a simple, or common way to extract dates from strings using a variable format?

The reason the date formats can vary so much is because we're parsing file names from vendors, so we have to be able to handle yyyymmdd, mmddyyyy, ddmmyyyy, ddmonyyyy, etc, etc.

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

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

发布评论

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

评论(2

静谧 2024-11-01 22:34:20

简而言之,没有办法自动解析任意日期格式来正确解析所有格式。在您自己的示例格式中,无法知道哪些数字对应哪些日期增量。

您可以查看 strtotime() 可接受的格式,如果全部如果您的供应商使用它所识别的格式,那么您很幸运。但如果没有,您真正能做的最好的事情就是创建一个 "vendor" => 的查找表。 “format” 然后你可以使用 date_parse_from_format()

编辑: 根据下面的评论,这里是 date_parse_from_format() 近似值的 php4 版本,应该适合您的需求

function date_parse_from_format($format, $date) {
  $dMask = array('H'=>'hour','i'=>'minute','s'=>'second','y'=>'year','m'=>'month','d'=>'day');
  $format = preg_split('//', $format, -1, PREG_SPLIT_NO_EMPTY);  
  $date = preg_split('//', $date, -1, PREG_SPLIT_NO_EMPTY);  
  foreach ($date as $k => $v) {
    if ($dMask[$format[$k]]) $dt[$dMask[$format[$k]]] .= $v;
  }
  return $dt;
}

基本上您需要有vendor => 的查找表format 其中 format 是日期字符串中每个字符所代表内容的掩码。

注意: 用于每个日期/时间增量的掩码并不完全反映 php 正常 date() 字符串格式。它经过简化,旨在屏蔽自定义字符串的每个单独字符。

示例:

/*
  lookup table for vendors
  for EVERY character you want to count as a date/time 
  increment you must use the following masks:
  hour   : H
  minute : i
  second : s
  year   : y
  month  : m
  day    : d
*/
$vendorDateFormats = array(
  'vendor1' => 'yyyymmdd',
  'vendor2' => 'mmddyyyy',
  'vendor3' => 'ddmmyyyy',
  'vendor4' => 'yyyy.mm.dd HH:ii:ss'
);

// example 1:
echo "<pre>";
print_r(date_parse_from_format($vendorDateFormats['vendor2'],'03232011'));

// example 2:
echo "<pre>";
print_r(date_parse_from_format($vendorDateFormats['vendor4'],'2011.03.23 12:03:00'));

输出:

Array
(
    [month] => 03
    [day] => 23
    [year] => 2011
)

Array
(
    [year] => 2011
    [month] => 03
    [day] => 23
    [hour] => 12
    [minute] => 03
    [second] => 00
)

The short answer is that there is no way to automatically parse arbitrary date formats that will correctly parse all formats out there. In your own example formats, there is just no way to know which numbers are for which date increments.

You can look at the accepted formats of strtotime() and if all your vendors use formats recognized by it, then you are in luck. But if not, the best you can really do is create a lookup table of "vendor" => "format" and then you can use date_parse_from_format()

edit: based on comment below, here is a php4 version of an approximation of date_parse_from_format() that should suit your needs

function date_parse_from_format($format, $date) {
  $dMask = array('H'=>'hour','i'=>'minute','s'=>'second','y'=>'year','m'=>'month','d'=>'day');
  $format = preg_split('//', $format, -1, PREG_SPLIT_NO_EMPTY);  
  $date = preg_split('//', $date, -1, PREG_SPLIT_NO_EMPTY);  
  foreach ($date as $k => $v) {
    if ($dMask[$format[$k]]) $dt[$dMask[$format[$k]]] .= $v;
  }
  return $dt;
}

Basically you need to have a lookup table of vendor => format where format is a mask of what each character in the date string represents.

NOTE: The masks used for each date/time increments do NOT exactly reflect what is used in php's normal date() string format. It is simplified and meant to mask each individual character of your custom string.

Example:

/*
  lookup table for vendors
  for EVERY character you want to count as a date/time 
  increment you must use the following masks:
  hour   : H
  minute : i
  second : s
  year   : y
  month  : m
  day    : d
*/
$vendorDateFormats = array(
  'vendor1' => 'yyyymmdd',
  'vendor2' => 'mmddyyyy',
  'vendor3' => 'ddmmyyyy',
  'vendor4' => 'yyyy.mm.dd HH:ii:ss'
);

// example 1:
echo "<pre>";
print_r(date_parse_from_format($vendorDateFormats['vendor2'],'03232011'));

// example 2:
echo "<pre>";
print_r(date_parse_from_format($vendorDateFormats['vendor4'],'2011.03.23 12:03:00'));

output:

Array
(
    [month] => 03
    [day] => 23
    [year] => 2011
)

Array
(
    [year] => 2011
    [month] => 03
    [day] => 23
    [hour] => 12
    [minute] => 03
    [second] => 00
)

There is the PHP function strtotime() PHP Ref which converts most strings which are a time (including things like "next Thursday") into timestamps, but even it can be somewhat confused when dealing with European and American date structures ("dd/mm/yyyy" versus "mm/dd/yyyy").

You can test it out (without writing a test script) at http://www.functions-online.com/strtotime.html

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