时差(以秒为单位)

发布于 2025-01-02 11:47:46 字数 354 浏览 3 评论 0原文

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

Feb 3 12:03:20  

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

我发现的 Perl 日期/时间信息令人难以置信。 据我所知,我需要使用 Date::Calc,但我是没有找到秒增量。 谢谢 :)

In a Perl program I have a variable containing date / time in this format:

Feb 3 12:03:20  

I need to determine if that date is more than x seconds old (based on current time), even if this occurs over midnight (e.g. Feb 3 23:59:00 with current time = Feb 4 00:00:30).

The perl date / time information I've found is mind-boggling.
Near as I can tell I need to use Date::Calc, but I am not finding a seconds-delta.
Thanks :)

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

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

发布评论

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

评论(6

追我者格杀勿论 2025-01-09 11:47:46
#!/usr/bin/perl

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

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

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

#!/usr/bin/perl

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

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

This is a simple way to find the time difference in seconds.

深海少女心 2025-01-09 11:47:46

似乎有一个方便的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

我不确定解析是否正确,但它可以很好地解析您的示例:)

There seems to be a convenient Date::Parse. Here's the example:

use Date::Parse;

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

And here's what it outputs:

$ perl test.pl
1328288600

which is:
Fri Feb 3 12:03:20 EST 2012

I'm not sure how decent the parsing is, but it parses your example just fine :)

若水微香 2025-01-09 11:47:46

本着 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 Feb 3 12:03:20

delta seconds = 14553

当前年份是假定的,取自您的当地时间。

In the spirit of TMTOWTDI, you can leverage the core 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 Feb 3 12:03:20

delta seconds = 14553

The current year is assumed and taken from your localtime.

乖乖哒 2025-01-09 11:47:46

在 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 个字符的月份缩写拼写错误会发生什么?)。

In perl, there is always more than one way to do something. Here's one which uses only a module that comes standard with 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";

To make this really production-ready, it needs better handling of the year (for example, what happens when the start date is in December and end date in January?) and better error handling (for example, what happens if the 3-char month abbreviation is mispelled?).

执手闯天涯 2025-01-09 11:47:46

假设您想使用 Date::Calc,将这两个值转换为“时间” " 值与 Date_to_Time 并减去这些值即可得到以秒为单位的差异。但要做到这一点,您需要先将字符串转换为 YY MM DD hh mm ss 值,然后传递给 Date_to_Time

Assuming you want to use Date::Calc, convert the two values to "time" values with Date_to_Time and subtract the values to get the difference in seconds. But to do this, you need to convert from the strings to YY MM DD hh mm ss values to pass to Date_to_Time first.

请你别敷衍 2025-01-09 11:47:46

在某些情况下,您绝对不能导入任何第三方包。其中之一:在线代码沙箱网站。在检查了十个不同的 Perl 沙箱后,我找不到一个允许 use 语句的沙箱。除非您完全拥有 Perl 环境的系统管理员权限(完全由您随心所欲),否则即使测试上述任何答案也会很棘手!

无包解决方案

这是一个无需任何包依赖即可工作的解决方案,并且保持轻量级和简单...

完整工作演示

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. 使用 alpha cmp sort 对时间进行排序,以便结束时间位于 [第 0] 个位置和第[1]位置的开始时间。
  2. 将开始/结束时间分成几部分。
  3. 使用基本算术计算差异。

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

为什么这样做?很简单,它甚至不是 1kb 的代码。看看这些包中的一些文件大小!这会消耗磁盘空间内存!如果您有一些简单的方法来计算时间差异,那么使用您自己的函数可能会更快。

日期: :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”有什么区别?大家应该都很清楚吧!

日期::Manip 结果:12:30:00

因此,这些包在基本加法问题上存在困难。我真的不知道还能说什么。

There are some cases where you absolutely cannot import any third party package. One of these instances: online code sandbox websites. After checking ten different Perl sandboxes, I couldn't find a single one that would allow use statements. Unless you full have system-admin permissions to a Perl environment that's entirely at your whim, even testing any of these answers above will be tricky!

Package-Free Solution

Here is a solution that works works without any package dependencies and remains lightweight and simple...

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)

Explanation

There are three operations happening here:

  1. Sort the times using alpha cmp sort, so that the endtime is in the [0]'th position and the start time in the [1]'th position.
  2. Split the start/end times into pieces.
  3. Calculate the diff using basic arithmetic.

Avoid Package-Based or CPAN-Based Solutions

Why do it this way? Easy, it's not even 1kb of code. Look at some of the file sizes in these packages! That chews through diskspace and memory! If you have something simple to just calculate the time diff, it might be faster to just use your own function.

Date::Manip FileSizes

What's worse than that? Even understanding how these packages work!

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);

According to Date::Manip, what's the difference between "13:00:00" and "13:30:00"? It should be obvious to everyone!

Date::Manip Result: 12:30:00

So, there are difficulties in these packages with the problem of basic addition. I'm really not sure what else to say.

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