如何在perl中比较字符串日期时间?

发布于 2024-12-17 11:35:18 字数 278 浏览 0 评论 0原文

我的日期时间格式为字符串“11:56:41, 11/22/2011”。

这就是我想要的:

比较两个日期时间字符串。

$date1 = "11:56:41, 11/22/2011";
$date2 = "11:20:41, 11/20/2011";
if($date2 < $date1) {
    do something...
} else {
    do nothing...
}

我有什么想法如何在 Perl 中实现这一点吗?

I have this date time format in string "11:56:41, 11/22/2011".

Here's what I want:

Compare two date time strings like.

$date1 = "11:56:41, 11/22/2011";
$date2 = "11:20:41, 11/20/2011";
if($date2 < $date1) {
    do something...
} else {
    do nothing...
}

Any ideas how could i achieve this in perl?

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

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

发布评论

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

评论(6

笙痞 2024-12-24 11:35:18

另一种解决方案是在将时间转换为 Time::Piece 对象后使用重载比较。对于一些简单的事情来说,创建这些对象可能有点大材小用,但如果您需要随时间做其他事情,它们就会变得非常有用。

use Time::Piece;

my $dateformat = "%H:%M:%S, %m/%d/%Y";

my $date1 = "11:56:41, 11/22/2011";
my $date2 = "11:20:41, 11/20/2011";

$date1 = Time::Piece->strptime($date1, $dateformat);
$date2 = Time::Piece->strptime($date2, $dateformat);

if ($date2 < $date1) {
    do something...
} else {
    do nothing...
}

One more solution that uses the overloaded comparisons after converting the times to Time::Piece objects. Creating the objects may be overkill for something simple, but they can become very useful if you need to do other things with the times.

use Time::Piece;

my $dateformat = "%H:%M:%S, %m/%d/%Y";

my $date1 = "11:56:41, 11/22/2011";
my $date2 = "11:20:41, 11/20/2011";

$date1 = Time::Piece->strptime($date1, $dateformat);
$date2 = Time::Piece->strptime($date2, $dateformat);

if ($date2 < $date1) {
    do something...
} else {
    do nothing...
}
淤浪 2024-12-24 11:35:18

一种有效的方法是将字段重新排序为词汇上可比较的内容。

sub to_comparable {
   my ($date) = @_;
   my ($H,$M,$S,$d,$m,$Y) = $date =~ m{^([0-9]{2}):([0-9]{2}):([0-9]{2}), ([0-9]{2})/([0-9]{2})/([0-9]{4})\z}
      or die;
   return "$Y$m$d$H$M$S";
}

if (to_comparable($date2) lt to_comparable($date1)) {
   ...
} else {
   ...
}

An efficient method is to reorder the fields to something lexically comparable.

sub to_comparable {
   my ($date) = @_;
   my ($H,$M,$S,$d,$m,$Y) = $date =~ m{^([0-9]{2}):([0-9]{2}):([0-9]{2}), ([0-9]{2})/([0-9]{2})/([0-9]{4})\z}
      or die;
   return "$Y$m$d$H$M$S";
}

if (to_comparable($date2) lt to_comparable($date1)) {
   ...
} else {
   ...
}
一刻暧昧 2024-12-24 11:35:18

什么,已经 4 个小时了,还没有一个 DateTime(所有人都欢呼强大的 DateTime)答案就在眼前?你偷懒了, 订阅者… ☻

use DateTime::Format::Strptime qw();
my $p = DateTime::Format::Strptime->new(pattern => '%T, %D', on_error => 'croak',);

my $date1 = $p->parse_datetime('11:56:41, 11/22/2011');
my $date2 = $p->parse_datetime('11:20:41, 11/20/2011');

if($date2 < $date1) {
    say "$date2 comes before $date1";
} else {
    say "$date2 does not come before $date1";
}

方法parse_datetime 返回 DateTime 的实例其比较运算符和字符串化被重载到 DTRT。

What, already 4 hours and not a single DateTime (all hail the mighty DateTime) answer in sight? You're slacking, subscribers… ☻

use DateTime::Format::Strptime qw();
my $p = DateTime::Format::Strptime->new(pattern => '%T, %D', on_error => 'croak',);

my $date1 = $p->parse_datetime('11:56:41, 11/22/2011');
my $date2 = $p->parse_datetime('11:20:41, 11/20/2011');

if($date2 < $date1) {
    say "$date2 comes before $date1";
} else {
    say "$date2 does not come before $date1";
}

The method parse_datetime returns instances of DateTime whose comparison operators and stringification are overloaded to DTRT.

雨巷深深 2024-12-24 11:35:18

将日期时间(在您的情况下,这些是本地日期时间,因为它们没有时区)转换为 ISO8601,然后您可以进行常规字符串比较。

要执行转换,您应该从格式中提取六个组件

HH:MM:SS, mm/DD/YYYY

并将它们重新组合成 ISO 8601:

YYYY-MM-DDTHH:MM:SS

然后就可以进行正常的词典比较了。

请参阅 http://codepad.org/berle9um

此处重复:

sub my_format_to_iso8601 {
    $_[0] =~ /(\d\d):(\d\d):(\d\d), (\d\d)\/(\d\d)\/(\d\d\d\d)/;
    return "$6-$4-$5T$1:$2:$3";
}

$date1 = "11:56:41, 11/22/2011";
$date2 = "11:20:41, 11/20/2011";
$d1 = my_format_to_iso8601($date1);
$d2 = my_format_to_iso8601($date2);
print "first is $d1\n";
print "second is $d2\n";
if ($d2 < $d1) {
    print "second is earlier\n";
} else {
    print "first is earlier\n";
}

ADDENDUM

  • ikegami 的 Perl 代码是好多了。
  • 日期库将是你的朋友;只需指定一个格式字符串并使用库的解析函数来获取日期对象,然后它应该能够直接比较。 (也就是说,指出 ISO8601 按照设计可以以字符串形式排序总是很有趣的。)

Convert the datetimes (in your case these are local datetimes because they have no time zones) into ISO8601 then you can do regular string comparison.

To perform the conversion, you should extract the six components from your format

HH:MM:SS, mm/DD/YYYY

and reassemble them into ISO 8601:

YYYY-MM-DDTHH:MM:SS

Then a normal lexicographic comparison will work.

See http://codepad.org/berle9um

Repeated here:

sub my_format_to_iso8601 {
    $_[0] =~ /(\d\d):(\d\d):(\d\d), (\d\d)\/(\d\d)\/(\d\d\d\d)/;
    return "$6-$4-$5T$1:$2:$3";
}

$date1 = "11:56:41, 11/22/2011";
$date2 = "11:20:41, 11/20/2011";
$d1 = my_format_to_iso8601($date1);
$d2 = my_format_to_iso8601($date2);
print "first is $d1\n";
print "second is $d2\n";
if ($d2 < $d1) {
    print "second is earlier\n";
} else {
    print "first is earlier\n";
}

ADDENDUM

  • ikegami's Perl code is much better.
  • A date library would be your friend here; simply specify a format string and use the library's parse function to get your date object, which it should then be able to compare directly. (That said, it is always fun to point out that ISO8601 is, by design, sortable in string form.)
财迷小姐 2024-12-24 11:35:18

我用unixtime。 :)

我将两个时间都转换为 unixtime,然后我只有两个整数要比较,因此我可以使用运算符 <、==、>等

例如转换为unixtime如下

my $timestamp = "2014-03-25 12:33:32";  # (We assume localtime)

# 
# To split on the space character, it's best to use the regex / /
# 
my ($date, $time) = split (/ /, $timestamp);
my ($year, $mon, $mday) = split ('-', $date);
my ($hour, $min, $sec) = split (':', $time);

my $unixtime = timelocal($sec, $min, $hour, $mday, $mon-1, $year);

I use unixtime. :)

I convert both times to unixtime and then I just have two integers to compare and so I can use the operators <, ==, > etc

e.g. convert to unixtime as follows

my $timestamp = "2014-03-25 12:33:32";  # (We assume localtime)

# 
# To split on the space character, it's best to use the regex / /
# 
my ($date, $time) = split (/ /, $timestamp);
my ($year, $mon, $mday) = split ('-', $date);
my ($hour, $min, $sec) = split (':', $time);

my $unixtime = timelocal($sec, $min, $hour, $mday, $mon-1, $year);
七秒鱼° 2024-12-24 11:35:18

在这种情况下,我一直使用 Date::Calc

use Date::Calc;

my $date1 = "11:56:41, 11/22/2011";
my $date2 = "11:20:41, 11/20/2011";

my @date1arr=split /[^\d]/, $date1 if($date1 =~ m!\d{2}:\d{2}:\d{2}, \d{2}/\d{2}/\d{4}!;
my @date2arr=split /[^\d]/, $date2 if($date2 =~ m!\d{2}:\d{2}:\d{2}, \d{2}/\d{2}/\d{4}!;

my @diff = Delta_DHMS(@date1arr, @date2arr);
my $less;
foreach my $d ( @diff ) { $less = 1 if $d < 0; }

if($less) { ... }

In this instance I've always used Date::Calc:

use Date::Calc;

my $date1 = "11:56:41, 11/22/2011";
my $date2 = "11:20:41, 11/20/2011";

my @date1arr=split /[^\d]/, $date1 if($date1 =~ m!\d{2}:\d{2}:\d{2}, \d{2}/\d{2}/\d{4}!;
my @date2arr=split /[^\d]/, $date2 if($date2 =~ m!\d{2}:\d{2}:\d{2}, \d{2}/\d{2}/\d{4}!;

my @diff = Delta_DHMS(@date1arr, @date2arr);
my $less;
foreach my $d ( @diff ) { $less = 1 if $d < 0; }

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