2013-03-04 6 views
0

J'utilise perl pour accéder à une base de données d'où je reçois la date au format DD-MON-YYYY. Je dois effectuer 2 opérations:date conversion en perl

  1. Convertissez ce format en format MM/JJ/AAAA.
  2. Comparez cette date avec deux dates pour voir si elle se situe dans cette période.

    mon $ chdate = '15 -Feb-2013 ';

    sous get_stats {

    my %map = ('Jan' => '01', 'Feb' => '02', 'Mar' => '03', 'Apr' => '04', 
          'May' => '05', 'Jun' => '06', 'Jul' => '07', 'Aug' => '08', 
          'Sep' => '09', 'Oct' => '10', 'Nov' => '11', 'Dec' => '12'); 
    
        $chdate =~ s/(..)-(...)-(....)/$map{$2}\/$1\/$3/; 
        print "New date: $chdate"; 
    

    }

Comment puis-je effectuer l'opération (2)?

J'ai une ancienne version de Perl (pas module Time :: Piece), que je ne dispose pas de privilèges pour mettre à jour :)

+3

[? Qu'avez-vous essayé] (http://mattgemmell.com/2008/12/08/what-have-you- try /) Montrez-nous le code pertinent afin que la communauté puisse vous aider à surmonter les problèmes. –

+0

http://search.cpan.org/~gbarr/TimeDate-2.30/lib/Date/Format.pm – CloudyMarble

+0

@aditya [DateHeure! Seulement un code rigide! :)] (https://metacpan.org/module/DateTime) – gaussblurinc

Répondre

-2

Pour (2), vous pouvez le faire:

sub dateAsNumber # Arg mm/dd/yyyy - Converts to a number to be compared 
{ 
    $_[0]=~m%(\d\d)/(\d\d)/(\d\d\d\d)%; 
    return (($3 * 400 + $1) * 40 + $2); 
} 

$test = &dateAsNumber($testDateAsString); 

if (&dateAsNumber($startDateAsString) < $test && 
    &dateAsNumber($endDateAsString) > $test) 
{ 
    print "$test date is between $startDateAsString and $endDateAsString\n"; 
} 
else 
{ 
    print "$test date is NOT between $startDateAsString and $endDateAsString\n"; 
} 
+0

Comment avez-vous déterminé (formule ($ 3 * 400 + $ 1) * 40 + $ 2)? – adizone

+0

Vous avez juste besoin de comparer deux nombres - Il n'y a pas plus de 400 jours dans l'année ou 40 jours dans le mois (j'ai arrondi à la hausse). Peu importe s'il y a des trous dans la ligne numérique. –

+0

Merci Ed. Juste un commentaire, la regex ne devrait pas être modifiée comme suit: $ _ [0] = ~/(\ d \ d) \/(\ d \ d) \/(\ d \ d \ d \ d) /; – adizone

5

Je suggère d'utiliser le module Time::Piece vous. Il a été un module de base depuis Perl5 v9.5 et n'aura donc probablement pas besoin d'être installé.

Il suffit de décoder la date en utilisant strptime et de la réencoder en utilisant strftime.

use strict; 
use warnings; 

use Time::Piece; 

my $date = '28-jul-1986'; 

print Time::Piece->strptime($date, '%d-%b-%Y')->strftime('%m/%d/%Y'); 

sortie

07/28/1986 
+0

Malheureusement, j'utilise perl-5.8 .6, et il se plaint du module Time :: Piece. – adizone

+1

Vous * devriez * mettre à jour votre version de Perl. v8.6 a plus de huit ans et il y a eu quatre versions majeures depuis. Êtes-vous capable d'installer 'Time :: Piece' de CPAN? Je ne vois pas pourquoi cela ne devrait pas fonctionner sur votre système. – Borodin

+0

J'utilise perl depuis un serveur, je n'ai pas les privilèges pour mettre à jour la version. J'ai trouvé une façon novice de faire la conversion :) – adizone

1

Si vous convertissez vos dates de Time::Piece objet, vous pouvez les comparer avec les opérateurs de comparaison numériques standard. Donc vous pourriez faire quelque chose comme ça.

#!/usr/bin/perl 

use strict; 
use warnings; 
use 5.010; 

use Time::Piece; 

my $start_date_str = '1-mar-2013'; 
my $end_date_str = '31-mar-2013'; 
my $date_to_test_str = '4-mar-2013'; 

my $in_fmt = '%d-%b-%Y'; 
my $out_fmt = '%m/%d/%y'; # Warning: Illogical format! 

my $start_date_tp = Time::Piece->strptime(
    $start_date_str, $in_fmt 
); 
my $end_date_tp = Time::Piece->strptime(
    $end_date_str, $in_fmt 
); 
my $date_to_test_tp = Time::Piece->strptime(
    $date_to_test_str, $in_fmt 
); 

print $date_to_test_tp->strftime($out_fmt), ' is '; 
unless ($start_date_tp <= $date_to_test_tp and 
    $date_to_test_tp <= $end_date_tp) { 
     print ' not '; 
} 
say 'between the two test dates';