2009-07-09 18 views
7

我想知道是否有任何庫(優選DateTime -esque),可以採取一個正常的日期時間,並創建一個適當的相對人類可讀的日期。 基本上與更常見的問題完全相反:How can I parse relative dates with Perl?如何在Perl中創建相對/近似日期?

顯然,確切措辭/解釋到實際執行,但我正在尋找提供一致的方式來指定在將來的日期。瞭解一個apporximation像「due in 2 weeks」是(對我)在得到我有多少剩餘時間比什麼「due on 2009-07-30」的把握更有幫助。

例子:

2009-07-06  => "in 1 year" 
2009-07-30  => "in 2 weeks" 
2009-07-09  => "tomorrow" 
2009-07-09 12:32 => "tomorrow at 12:32" 
2009-07-12 05:43 => "monday morning" 
2009-07-03 05:74 => "6 days ago" 

回答

7

更新:它看起來像這樣的功能是在Template Toolkit Plugin實現。我將其餘的答案留在這裏作爲參考,但Template::Plugin::DtFormatter可能是最好的看看。在該模塊的源代碼

看,我是導致DateTime::Format::Natural這似乎與你想要什麼。

以前的答案:

查找到Date::Calc使用Delta_DHMS給你增量。你應該能夠使用這些變化來選擇你如何說出日期。

這是一個非常基本的出發點。它是越野車,但說明了基本的想法。添加品嚐的邏輯。

#!/usr/bin/perl 

use strict; 
use warnings; 

use Date::Calc qw(:all); 
use Lingua::EN::Inflect qw(NO); 

my @dates = (
    [ 2009, 7, 6 ], 
    [ 2009, 7, 30 ], 
    [ 2009, 7, 9 ], 
    [ 2009, 7, 9, 12, 32 ], 
    [ 2009, 7, 12, 5, 43 ], 
    [ 2009, 7, 3, 5, 14 ], 
    [ 2010, 8, 9 ], 
    [ 2012, 8, 9 ], 
    [ 2013, 8, 9 ], 
); 

for my $date (@dates) { 
    print "@$date: ", relative_when($date), "\n"; 
} 

sub relative_when { 
    my ($year, $month, $day, $hour, $min, $sec) = @{ $_[0] }; 
    my ($Dyear, $Dmon, $Dday, $Dhr, $Dmin, $Dsec) = Delta_YMDHMS(
     Today_and_Now(), 
     $year, $month, $day, $hour || 0, $min || 0, $sec || 0 
    ); 
    return NO('year', $Dyear)  if $Dyear > 0; 
    return NO('month', $Dmon)  if $Dmon > 0; 
    return NO('week', int($Dday/7) if $Dday > 6; 
    return NO('day', $Dday)  if $Dday > 1; 
    return 'tomorrow' if $Dday == 1; 
    return 'today' if $Dday == 0; 
    return ""; 
} 

__END__ 

輸出:

C:\Temp> dfg 
2009 7 6: 
2009 7 30: 2 weeks 
2009 7 9: today 
2009 7 9 12 32: today 
2009 7 12 5 43: 2 days 
2009 7 3 5 14: 
2010 8 9: 1 year 
2012 8 9: 3 years 
2013 8 9: 4 years 
+0

咦?爲什麼downvote? – 2009-07-09 15:14:57