2009-05-06 4 views
3

Wahrscheinlich eine einfache Antwort: Wie konvertiere ich das, ohne externe Module zu importieren? Ich habe das CPAN gelesen, konnte aber eine Methode, die Folgendes bewirkt, nicht genau lokalisieren:Wie konvertiere ich Datumsformate in Perl, ohne externe Module zu importieren?

Convert: 20080428 to 28-APR-08 

Irgendwelche Ideen?

Sogar mich zu einem Tutorial zu verweisen würde geschätzt werden.

Grüße, PIAS

+0

Was meinen Sie durch externe Module? CPAN-Code oder Systemaufrufe? – castaway

Antwort

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

Diese müssen [0-9] not \ d sein, es sei denn, Sie haben das Byte-Pragma aktiviert (\ d stimmt mit anderen Dingen als [0-9] in Perl 5.8 und 5.10 überein). Alternativ könntest du /(....)(..)(..)/ sagen, wenn dir der genaue Typ egal ist. –

+0

Dieser Code mag Daten wie 99998877. Außerdem werden Daten von 1900-1999 falsch gedruckt. – daotoad

+0

Gute Punkte Leute (obwohl ich angenommen habe - und immer noch bin -, dass nur gültige Daten die Eingabe bilden). Ich habe das repariert - auf die einfache Art und Weise. @Chas: Was wird passen, das ist keine Ziffer? – innaM

3

in Y10K Dieser Code nicht überprüft, aber das sollte gut genug sein. Die Regex könnte strenger sein, aber wenn das Datum bereits validiert wurde (oder in der neuen Form validiert wird), spielt es keine Rolle.

#!/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"; 

Oder, wenn Sie verrückt sind und wollen in der Regex zu validieren (erfordert 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"; 
Verwandte Themen