2009-03-11 9 views
4

Qu'est-ce qu'un bon module Perl (ou une bonne approche) qui renvoie toutes les dates de calendrier valides entre une date de début et une date de fin? Par exemple, si j'ai le 29/01/2009 comme date de début et le 2/3/2009 comme date de fin, je voudrais qu'il retourne un tableau du 30/01/2009, 31/01/2009 , 2/1/2009 et 2/2/2009. Il doit y avoir un bon module Perl qui le fait déjà et qui tient compte des années bissextiles, des mois, mais je ne le trouve pas.Quel est un bon moyen de déterminer les dates d'une plage de dates?

Merci pour vos suggestions!

Répondre

2

Date::Manip semble être le module de date canonique en Perl. Il a une API bizarre, mais cela fonctionne. Voici un exemple d'utilisation de la fonction ParseRecur pour faire ce que vous voulez:

#!/usr/bin/perl 
use warnings; 
use strict; 

use Date::Manip; 
use Data::Dumper; 

my ($start, $end) = qw(2009-01-29 2009-02-03); 

# Exclude start date 
$start = DateCalc($start, "+1 day"); 

# y:m:w:d:h:m:s 
my @dates = ParseRecur('0:0:0:1:0:0:0', $start, $start, $end); 

for my $date (@dates) { 
    print UnixDate($date, "%Y-%m-%d\n"); 
} 
+0

Merci! Cela marche. Cela peut être nécessaire en fonction de votre environnement. & Date_Init ("TZ = CST"); – NoahD

9

DateTime, je l'ai utilisé plusieurs fois et il peut faire quoi que ce soit à peu près que vous pouvez penser avec des dates. Il gère les années bissextiles, secondes intercalaires, dates/heures invalides, il peut sortir des dates dans n'importe quel format, il peut comparer, ajouter, soustraire, etc ...

Le seul problème est qu'il pourrait être exagéré.

+0

Oui DateTime est le module de date "canonique". Voir datetime.perl.org – draegtun

4

est ici un coup de poignard. Elle exige Date::Simple et Date::Range:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Date::Simple; 
use Date::Range; 

my $d1 = Date::Simple->new('2009-03-02'); 
my $d2 = Date::Simple->new('2009-03-07'); 

my $range = Date::Range->new($d1, $d2); 

for my $date ($range->dates) { 
    print $date->format("%m/%d/%Y"), "\n" # Fixed format 
} 
+0

Nice! Ces modules ont une API beaucoup plus saine que Date :: Manip. – vasi

+0

Il est également significativement plus léger que Date :: Manip (ou DateTime). Il ne peut pas faire tout ce que DateTime peut faire, mais parfois simple est mieux que complet. – Telemachus

0

En raison de la puissance propre de POSIX::mktime, vous pouvez effectuer les opérations suivantes:

use POSIX qw<mktime strftime>; 

my ($month, $day, $year) = (8, 16, 2008); 
my $end_date = mktime(0, 0, 0, 1, 2 - 1, 2009 - 1900); 
while (1) { 
    my $date = mktime(0, 0, 0, $day++, $month - 1, $year - 1900); 
    push @date_range, strftime('%x', localtime $date); 
    last if $date >= $end_date; 
} 

Avec mktime(0, 0, 0, 500, 0, 108) a un sens. Mais il en est de même pour la dernière date de février pour toute année.

6

Voici un exemple en utilisant DateTime:

use strict; 
use warnings; 

use DateTime; 

my $d1 = DateTime->new(month => 1, day => 29, year => 2009); 
my $d2 = DateTime->new(month => 2, day => 3, year => 2009); 

while ($d1 <= $d2) { 
    print $d1->strftime("%m/%d/%Y"),"\n"; 
    $d1->add(days => 1); 
} 
Questions connexes