2009-05-06 5 views
3

Probablement une réponse facile: comment puis-je convertir ceci sans importer de modules externes? J'ai lu le CPAN mais je ne pouvais pas identifier explicitement une méthode qui fait ce qui suit:Comment convertir des formats de date en Perl sans importer de modules externes?

Convert: 20080428 to 28-APR-08 

Des idées?

Même me diriger vers un tutoriel serait apprécié.

Cordialement, PIAS

+0

Que voulez-vous dire par des modules externes? Code CPAN ou appels système? – castaway

Répondre

2
my %map = ('01' => 'JAN', '02' => 'FEB', '03' => 'MAR', '04' => 'APR'); # You can do the rest yourself ;-) 
my $in = '20080428'; 
if ($in =~ m/..(..)(..)(..)/) { 
    my ($y, $m, $d) = ($1, $2, $3); 
    my $out = sprintf '%02d-%s-%02d', $d, $map{$m}, $y; 
} 
else { 
    die "Illegal date format"; 
} 
+0

Ceux qui doivent être [0-9] pas \ d sauf si vous avez activé le pragma d'octets (\ d correspond à des choses autres que [0-9] dans Perl 5.8 et 5.10). Sinon, vous pourriez dire /(....)(..)(..)/ si vous ne vous souciez pas du type exact. –

+0

Ce code aime les dates comme 99998877. En outre, les dates de 1900-1999 seront imprimées incorrectement. – daotoad

+0

Bon point les gens (bien que je supposais - et je suis toujours - que seules les dates valides formeront l'entrée). J'ai réparé ces - la manière simple. @Chas: Qu'est-ce qui va correspondre avec ce n'est pas un chiffre? – innaM

3

Ce code échoue dans Y10k, mais cela devrait être assez bon. L'expression rationnelle pourrait être plus stricte, mais si la date a déjà été validée (ou sera validée dans le nouveau formulaire), cela n'a pas d'importance.

#!/usr/bin/perl 

use strict; 
use warnings; 

my @mon = qw/null JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC/; 

my $d = "20080428"; 

$d =~ s/..(..)(..)(..)/$3-$mon[$2]-$1/; 

print "date is now $d\n"; 

Ou, si vous êtes fou et que vous voulez valider dans le regex (nécessite Perl 5.10):

#!/usr/bin/env perl5.10.0 

use strict; 
use warnings; 

my @mon = qw/null JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC/; 

my $d = join '', @ARGV; 

# only validates between 1600 and 9999 
# because of calendar weirdness prior to 1600 
$d =~ s/ 
    ^
    (?: 
     # non-leap years and everything but 29th of Feb in leap years 
     (?: 
      1[6-9]  (?<y> [0-9]{2}) | 
      [2-9][0-9] (?<y> [0-9]{2}) 
     ) 
     (?: #any month 1st through 28th 
      (?: (?<m> 0[1-9] | 1[0-2]) (?<d> 0[0-9] | 1[0-9] | 2[0-8])) 
      | #or 30th of any month but 2 
      (?: (?<m>0[13-9] | 1[0-2]) (?<d> 30)) 
      | # or 31st of 1, 3, 5, 7, 8, 10, or 12 
      (?: (?<m>0[13578] | 1[02]) (?<d> 31)) 
     ) 
     | # or 29th of Feb in leap years 
     (?: 
      (?: #centuries divisible by 4 minus the ones divisible by 100 
       16   |  
       [2468][048] | 
       [3579][26] 
      ) 
      (?<y> 00) 
      | #or non-centuries divisible by 4 
      (?: 1[6-9] | [2-9][0-9]) 
      (?<y> 
       0[48]  | 
       [2468][048] | 
       [13579][26] 
      ) 
     ) 
     (?<m> 02) (?<d> 29) 
    ) 
    $ 
/$+{y}-$mon[$+{m}]-$+{d}/x or die "invalid date: $d"; 

print "date is now $d\n"; 
Questions connexes