2016-06-16 19 views
6

Tôi đang cố gắng tính toán số ngày dương lịch giữa hai ngày được trích xuất từ ​​cơ sở dữ liệu. Tôi nghĩ rằng việc chuyển đổi ngày thành giây sẽ là một giải pháp đơn giản và chính xác.Perl: Tính số ngày bằng cách chuyển đổi sang giây

#!/usr/bin/perl 
use warnings; 
use strict; 
use POSIX qw(strftime); 
use Date::Parse; 

my $minDate = "2016-03-27"; 
my $maxDate = "2016-06-15"; 

print "Format as extracted from db: mindate: $minDate and maxdate: $maxDate\n"; 

my ($dbYear,$dbMonth,$dbDay) = split ('-', $minDate); 
my $datum = "$dbYear$dbMonth$dbDay"; 
my $minDateSec = str2time($datum); 

($dbYear,$dbMonth,$dbDay) = split ('-', $maxDate); 
$datum = "$dbYear$dbMonth$dbDay"; 
my $maxDateSec = str2time($datum); 

my $numCalDaysSec = ($maxDateSec-$minDateSec)/86400; 

print "Min date in Seconds: $minDateSec\n"; 
print "Max date in Seconds: $maxDateSec\n"; 
print "Num days: $numCalDaysSec\n"; 

Ban đầu, tôi nghĩ rằng phương pháp này cung cấp cho tôi với kết quả đáng tin cậy:

bash-3.2$ ./testNumDays.pl 
As extracted from db: mindate: 2016-06-14 and maxdate: 2016-06-15 
Min date in Seconds: 1465855200 
Max date in Seconds: 1465941600 
Num days: 1 
bash-3.2$ ./testNumDays.pl 
As extracted from db: mindate: 2016-05-31 and maxdate: 2016-06-15 
Min date in Seconds: 1464645600 
Max date in Seconds: 1465941600 
Num days: 15 
bash-3.2$ ./testNumDays.pl 
As extracted from db: mindate: 2016-03-28 and maxdate: 2016-06-15 
Min date in Seconds: 1459116000 
Max date in Seconds: 1465941600 
Num days: 79 
bash-3.2$ ./testNumDays.pl 
As extracted from db: mindate: 2016-03-27 and maxdate: 2016-06-15 
Min date in Seconds: 1459033200 
Max date in Seconds: 1465941600 
Num days: 79.9583333333333 
bash-3.2$ 

Rõ ràng, số lượng ngày lịch giữa ngày phải là số nguyên. Mmmm, tôi đang làm gì sai? Tại sao chuyển đổi sang giây không đáng tin cậy?

Vì tôi là một người mới của Perl, có lẽ tôi đã xem xét điều hiển nhiên. Do đó, bất kỳ trợ giúp nào cũng được hoan nghênh hơn.

+2

Tại sao không thực hiện điều này trực tiếp trong truy vấn cơ sở dữ liệu của bạn? – ThisSuitIsBlackNot

+1

Trong thực tế, tôi đang học cách xử lý các ngày trong Perl. Sự tò mò và làm quen với Perl là những động lực chính. –

+1

Dường như lỗi Thời gian tiết kiệm ánh sáng ban ngày. Tôi chưa kiểm tra lịch của mình để xem đó có phải là vấn đề hay không. – hymie

Trả lời

7

Một cách là sử dụng các mô-đun Time::Piece Core:

use warnings; 
use strict; 
use Time::Piece qw(); 

my $t1 = Time::Piece->strptime('2016-03-27', '%Y-%m-%d'); 
my $t2 = Time::Piece->strptime('2016-06-15', '%Y-%m-%d'); 
my $seconds = $t2 - $t1; 
print $seconds->days(), "\n"; 

__END__ 

80 
5

Một cách khác là DateTime. Nó không có trong Core, nhưng nó thường rất tiện dụng. Bởi vì nó không phân tích ngày tháng, chúng tôi đã nhanh chóng thực hiện chức năng phân tích cú pháp của riêng mình.

use strict; 
use warnings; 
use DateTime; 
my $minDate = "2016-03-27"; 
my $maxDate = "2016-06-15"; 

sub parse { 
    my $date = shift; 

    my ($y, $m, $d) = split /-/, $date; 

    return DateTime->new(year => $y, month => $m, day => $d); 
} 

my $days = parse($minDate)->delta_days(parse($maxDate))->in_units('days'); 
print $days; 

__END__ 

80 
+2

Nó phân tích ngày tháng. DateTime :: Format :: Strptime là linh hoạt nhất, nhưng DateTime :: Format :: ISO8601 có lẽ là đơn giản nhất trong trường hợp này. – ikegami

+0

@ikegami yeah nếu bạn tải một trong số đó. Nhưng nó [không nói _this module không phân tích date_] (https://metacpan.org/pod/DateTime#Parsing-Dates) ...;) – simbabque

+0

Bởi logic đó, DateTime không biết gì về múi giờ vì tất cả thông tin múi giờ đó nằm trong phân phối khác. Điều đó khá ngớ ngẩn. – ikegami

3

Bạn đang giả định không hợp lệ rằng mỗi ngày dài 86,400 giây.

Vui lòng truy cập http://www.timeanddate.com/time/dst/2016.html và xem tất cả những nơi Thời gian tiết kiệm ánh sáng ban ngày (còn gọi là Giờ mùa hè) bắt đầu vào ngày 27 tháng 3 năm 2016. Ngày đó không dài 86,400 giây.

Các vấn đề liên quan