2015-09-25 100 views
1

我試圖計算和顯示,以分鐘爲單位,輸入的日期和當前時間之間的差異。我有:查找兩個日期之間的時間在Perl

print "Enter a date YYYY MM DD. Remember perl's months go from 0-11.\n"; 
while (@dateEnt < 1) { 
    my $dateEntered = <STDIN>; 
    chomp $dateEntered; 
    push @dateEnt, $dateEntered; 

    (@datedata) = split(/\s+/, $dateEntered); 
    $year = $datedata[0]; 
    $month = $datedata[1]; 
    $day = $datedata[2]; 
} 

$time   = time; 
$readabletime = localtime($time); 

use Time::Local; 
$timeB = localtime [1]; 
$timeBetween = $readabletime[1] - $timeB; 
print "The time between the dates is $timeBetween\n"; 

當我執行此操作時,我沒有得到答案。任何幫助?

+4

歡迎使用Stack Overflow和_perl_標記。請確保您總是在程序中添加'use strict;'和'warnings'。它們可以幫助您儘早發現錯誤。如果你從一個既不顯示也不顯示的源代碼學習Perl,它已經過時了。您最好使用SO標籤中的Perl標籤wiki。現在,你永遠不會使用你的用戶輸入的日期。還有一些語法錯誤。請以'use strict'和'使用警告'開始。 – simbabque

+3

...和「過時」我們的意思是字面上幾十年的老。 2000年推出「使用警告」; '使用嚴格'於1994年推出。 – melpomene

回答

3

讓我們來看看這最後一塊

use Time::Local; 
$timeB = localtime[1]; 
$timeBetween = $readabletime[1] - $timeB; 
print "The time between the dates is $timeBetween\n"; 

use聲明是在程序的頂部通常放,因爲它在編譯時實際執行,但它的罰款的任何地方真的

localtime[1]外觀就像您正在嘗試訪問名爲localtime的數組的第二個元素(Perl數組從零開始)。但是你實際上做的是創建一個匿名數組,其中包含單值1並將其引用傳遞給localtime。如果您嘗試使用print[1],您會看到類似ARRAY(0x22c4000)的東西。所以localtime試圖內存地址轉換成一個日期和時間

$readabletime[1]試圖訪問數組@readabletime的第二個元素,它不存在,因此將評估爲undef

你最終想減去有點像"Thu Mar 4 18:50:24 1971"undef這是沒有意義的。我想你應該得到一個致命的錯誤類似

Argument "Thu Mar 4 18:50:24 1971" isn't numeric in subtraction 
1

你可以試試這個

use strict; 
use warnings; 
use DateTime; 

my $from_date = DateTime->new(
         year => 2014, 
         month => 9, 
         day => 24, 
         hour => 9, 
         minute => 13, 
         second => 8, 
         time_zone => 'local', 
        ); 
print "$from_date\n"; 
my $current_date = DateTime->now(time_zone => 'local')->set_time_zone('floating'); 
print "$current_date\n"; 
my $time_diff = $current_date - $from_date; 
print 'year = ', $time_diff->years, "\n"; 
print 'month = ', $time_diff->months, "\n"; 
print 'days = ', $time_diff->days, "\n"; 
print 'hours = ', $time_diff->hours, "\n"; 
print 'minutes = ', $time_diff->minutes, "\n"; 
print 'secondss = ', $time_diff->seconds, "\n"; 

結果:

2014-09-24T09:13:08 
2015-09-25T21:31:37 
year = 1 
month = 0 
days = 1 
hours = 12 
minutes = 18 
secondss = 29 
3

use strict;use warnings;會告訴你很多的問題。

  • while循環是多餘的,因爲你push沒有任何驗證。所以它會總是在第二次迭代是正確的。
  • 這使得@dateEnt冗餘。
  • 在標量上下文
  • localtime給出了一個字符串。你不能用字符串做數學。 (偶爾你可以作弊,因爲perl可以將其轉換爲數字,但不適用於日期字符串)。
  • use通常是在一個程序的頂部,因爲它是在一個數組背景下「完成」無論
  • localtime的第一件事就是返回值的數組。 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); you can do (localtime)[1]它給你$min。但是,無論如何,這並不太有意義。
  • $readabletime[1]指稱爲@readabletime的數組的第二個元素。這不存在。

所以來完成你以後 - 我會建議使用Time::Piece(Perl核心模塊)是這樣的:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Time::Piece 

my $date; 
while (not $date) { 
    print "Enter a date YYYY MM DD\n"; 
    my $dateEntered = <STDIN>; 
    chomp $dateEntered; 
    $date = Time::Piece->strptime($dateEntered, "%Y %m %d"); 
} 
print "Understood: $date\n"; 
my $timebetween_s = (time() - $date->epoch); 
print $timebetween_s, "s between then and now\n"; 

注意 - 它使用strptime所輸入的日期轉換爲Time::Piece對象(你可以只需print,如果你想得到一個字符串日期,但你也可以做其他轉換)。 strptime支持許多不同的格式。

但你只是減去$date->epoch - 它得到的時間(秒)自1970年1月1日,從time()這也是自1月1日1970年以秒爲單位的時間這讓你像你想有一個時間差 - 在幾秒鐘。如果你想要不同的單位,你需要分割它。

+2

如果您同時使用'Time :: Seconds',則可以編寫'my $ time_between =(localtime - $ date) - > pretty'並將其格式化得很好 – Borodin

相關問題