以秒为单位的时差

时间:2012-02-03 20:01:25

标签: perl date time date-arithmetic

在Perl程序中,我有一个包含这种格式的日期/时间的变量:

Feb 3 12:03:20  

我需要确定该日期是否超过 x 秒(基于当前时间),即使这发生在午夜(例如Feb 3 23:59:00,当前时间= {{1 }})。

我发现的perl日期/时间信息令人难以置信。 接近我可以告诉我需要使用Date::Calc,但我没有找到秒 - 三角洲。 谢谢:)

6 个答案:

答案 0 :(得分:20)

#!/usr/bin/perl

$Start = time();
sleep 3;
$End = time();
$Diff = $End - $Start;

print "Start ".$Start."\n";
print "End ".$End."\n";
print "Diff ".$Diff."\n";

这是一种以秒为单位查找时差的简单方法。

答案 1 :(得分:9)

似乎有一个方便的Date::Parse。这是一个例子:

use Date::Parse;

print str2time ('Feb 3 12:03:20') . "\n";

以下是它的输出:

$ perl test.pl
1328288600

是: Fri Feb 3 12:03:20 EST 2012

我不确定解析是否合适,但它解析你的例子很好:)

答案 2 :(得分:6)

本着TMTOWTDI的精神,您可以利用核心Time::Piece

#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $when = "@ARGV" or die "'Mon Day HH:MM:SS' expected\n";
my $year = (localtime)[5] + 1900;
my $t = Time::Piece->strptime( $year . q( ) . $when, "%Y %b %d %H:%M:%S" );
print "delta seconds = ", time() - $t->strftime("%s"),"\n";

$ ./mydelta 2月3日12:03:20

delta seconds = 14553

假设当前年份并从当地时间开始。

答案 3 :(得分:3)

在perl中,总有不止一种方法可以做某事。这里只使用了Perl标准的模块:

#! perl -w

use strict;
use Time::Local;

my $d1 = "Feb 3 12:03:20";
my $d2 = "Feb 4 00:00:30";

# Your date formats don't include the year, so
# figure out some kind of default.
use constant Year => 2012;


# Convert your date strings to Unix/perl style time in seconds
# The main problems you have here are:
# * parsing the date formats
# * converting the month string to a number from 1 to 11
sub convert
{
    my $dstring = shift;

    my %m = ( 'Jan' => 0, 'Feb' => 1, 'Mar' => 2, 'Apr' => 3,
            'May' => 4, 'Jun' => 5, 'Jul' => 6, 'Aug' => 7,
            'Sep' => 8, 'Oct' => 9, 'Nov' => 10, 'Dec' => 11 );

    if ($dstring =~ /(\S+)\s+(\d+)\s+(\d{2}):(\d{2}):(\d{2})/)
    {
        my ($month, $day, $h, $m, $s) = ($1, $2, $3, $4, $5);
        my $mnumber = $m{$month}; # production code should handle errors here

        timelocal( $s, $m, $h, $day, $mnumber, Year - 1900 );
    }
    else
    {
        die "Format not recognized: ", $dstring, "\n";
    }
}

my $t1 = convert($d1);
my $t2 = convert($d2);

print "Diff (seconds) = ", $t2 - $t1, "\n";

为了让这个真正适合生产,它需要更好地处理年份(例如,当开始日期是12月和结束日期是1月时会发生什么?)和更好的错误处理(例如,如果3个月的缩写是错误的吗?)。

答案 4 :(得分:2)

假设您要使用Date::Calc,请使用Date_to_Time将这两个值转换为“时间”值,并减去这些值以获得以秒为单位的差异。但要执行此操作,您需要先将字符串转换为YY MM DD hh mm ss值,然后再传递给Date_to_Time

答案 5 :(得分:0)

在某些情况下,您绝对不能导入任何第三方软件包。这些实例之一:在线代码沙箱网站。在检查了十个不同的Perl沙箱之后,我找不到一个可以使用use语句的沙箱。除非您完全对自己的Perl环境具有系统管理员的权限,否则即使测试上述任何答案都将非常棘手!

无包解决方案

这是一个无需任何程序包依赖即可工作的解决方案,并且保持轻巧简单……

Full Working Demo

sub getTimeDiff {
    my ($times) = @_;
    
    my @times = sort {$a cmp $b} @{$times};
    my ($endhour, $endminute, $endsecond, $starthour, $startminute, $startsecond) = (split(':', $times[0]), split(':', $times[1]));
    my $diff = ($starthour * 60 * 60) + ($startminute * 60) + ($startsecond) - ($endhour * 60 * 60) - ($endminute * 60) - ($endsecond);
    
    return $diff;
}

print(getTimeDiff(["13:00:00", "13:35:17"]));      // output: 2117 (seconds)

说明

这里发生了三种操作:

  1. 使用字母cmp sort对时间进行排序,以使结束时间位于第[0]位,开始时间位于第[1]位。 / li>
  2. 将开始/结束时间分成几段。
  3. 使用基本算法计算差异。

避免基于包或基于CPAN的解决方案

为什么要这样? 很简单,它甚至不到1kb的代码。查看这些软件包中的某些文件大小!这就嚼破了磁盘空间 内存!如果您有一些简单的方法可以计算时间差,那么使用自己的函数可能会更快。

Date::Manip FileSizes

还有什么比这更糟糕的呢?甚至了解这些软件包的工作原理!

use Date::Manip;
$ret = Date::Manip::DateCalc("13:00:00","13:30:00",0).'';
$ret = Date::Manip::DateCalc("00:00:00", $ret,0).'';
$ret = UnixDate($ret, '%I:%M:%S');
print("Date::Manip Result: " . $ret);

根据Date::Manip,“ 13:00:00”和“ 13:30:00”有什么区别?对所有人来说应该是显而易见的!

Date::Manip Result: 12:30:00

因此,这些软件包中存在基本添加问题的困难。我真的不确定还要说些什么。