按文件名中的非常规日期对文件进行排序 (PHP)
我正在使用一个 PHP 脚本,该脚本允许按时间顺序浏览 Eggdrop 生成的 IRC 日志。最初,我读取目录内容并根据文件修改日期将日志名称插入到数组中。然而,在最近的服务器移动之后,文件的修改日期已更新,导航现在变得混乱!
日志文件名结构如下所示:
channel.log.dayMONTHyear.txt
例如:
shrawberry.log.08Apr2011.txt
由于非常易于人类阅读,因此很难正确排序。
由于月份代码始终是三个字符长并且位于序列中的可预测位置,因此我可以手动将非标准日期代码解析为 Unix 时间戳,迭代列表并将每个项目添加到具有该时间戳的数组中,然后排序按该数字排列的数组。
但这听起来有些过分了。
我是否有钱,或者我提出的解决方案是否理想?
在 Marc B. 的帮助下,我实现了以下内容:
function dateFromEggLog($string){
$month = substr($string,-11,-8);
$day = substr($string,-13,-11);
$year = substr($string,-8,-4);
for($i=1;$i<=12;$i++){
if(strtolower(date("M", mktime(0, 0, 0, $i, 1, 0))) == strtolower($month)){
$month = $i;
break;
}
}
return "$year-$month-$day";
}
function my_compare($a, $b) {
$a_date = dateFromEggLog($a);
$b_date = dateFromEggLog($b);
if ($a_date == $b_date) {
return 0;
}
$a = strtotime($a_date); // convert to PHP timestamp
$b = strtotime($b_date); // convert to PHP timestamp
return (($a < $b) ? -1 : 1);
}
这成功地对我的日志进行了排序,而无需修改我的数组。
I'm working with a PHP script that allows the chronological browsing of Eggdrop-generated IRC logs. Initially, I was reading the directory contents and inserting the log names into an array based on file modification date. After a recent server move, however, the files have had their modification dates updated and the navigation is now disorderly!
The log filename structure looks like:
channel.log.dayMONTHyear.txt
for example:
shrawberry.log.08Apr2011.txt
which, for being quite human-readable, is difficult to order properly.
Since the month code is always three characters long and comes in a predictable position in the sequence, I could manually parse the nonstandard date code into a Unix timestamp, iterate through the list and add each item to an array with that timestamp, and then sort the array by that number.
But that sounds excessive.
Am I on the money, or is the solution I proposed ideal?
With Marc B.'s help, I've implemented the following:
function dateFromEggLog($string){
$month = substr($string,-11,-8);
$day = substr($string,-13,-11);
$year = substr($string,-8,-4);
for($i=1;$i<=12;$i++){
if(strtolower(date("M", mktime(0, 0, 0, $i, 1, 0))) == strtolower($month)){
$month = $i;
break;
}
}
return "$year-$month-$day";
}
function my_compare($a, $b) {
$a_date = dateFromEggLog($a);
$b_date = dateFromEggLog($b);
if ($a_date == $b_date) {
return 0;
}
$a = strtotime($a_date); // convert to PHP timestamp
$b = strtotime($b_date); // convert to PHP timestamp
return (($a < $b) ? -1 : 1);
}
This successfully sorts my logs, without needing to muck around with my array.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的示例文件名与“看起来像”示例不匹配 - “txt”和日期字符串颠倒了。但无论如何,您可以使用 PHP
usort()
函数,它可以让用户定义的函数进行比较。它可能不是特别有效,但你会这样做:
Your example filename doesn't match the "looks like" sample - the 'txt' and date string are reversed. but in any case, you can use the PHP
usort()
function, which lets a user-defined function do the comparisons.It may not be particularly efficient, but you'd do something like this:
你以前用过filemtime吗?为什么现在不使用 filectime 呢?
You used filemtime before? Why not use filectime now?
为什么不在排序函数中使用字符串操作将
channel.log.dayMONTHyear.txt
重新排序为channel.log.yyyymmdd.txt
,然后使用基本字符串比较?输出:
这应该比为每个文件名创建完整日期表示要快得多。
Why not, in your sort function, re-order
channel.log.dayMONTHyear.txt
tochannel.log.yyyymmdd.txt
using string manipulation, then use basic string comparison?Output:
This ought to be significantly quicker than creating full date representations for each filename.