Главная страница


ru.perl

 
 - RU.PERL ----------------------------------------------------------------------
 From : Michael Poliakov                     2:5020/400     29 Nov 2001  15:19:50
 To : Andrey Larushkin
 Subject : Re: Дата в секунды?
 -------------------------------------------------------------------------------- 
 
 On Wed, 28 Nov 2001 08:40:47 +0300, Andrey Larushkin
 <Andrey.Larushkin@p12.f11.n5024.z2.fidonet.org> wrote:
 
 >Есть ли какая-нибудь функция, которая может перевести дату вида:
 >
 >"2000 11 20 00:00:00" в секунды?
 >
 >Или "Wed Nov 28 08:45:02 2001" тоже в секунды?
 
 === cut ===
 #!/usr/bin/perl -w
 
 use strict;
 use Time::Local;
 
 use vars qw(@DoW @MoY %MoY);
 @DoW = qw(Sun Mon Tue Wed Thu Fri Sat);
 @MoY = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
 @MoY{@MoY} = (1..12);
 my %GMT_ZONE = (GMT => 1, UTC => 1, UT => 1, Z => 1, MSK => 1);
 my $str = 'Wed Nov 28 08:45:02 2001';
 my $sec = str2time($str);
 
 print $str . ' = ' . $sec . "\n";
 print $sec . ' = ' . time2str($sec). "\n";
 
 #####################################################################
 # из модуля HTTP::Date
 #
 sub time2str (;$)
 {
     my $time = shift;
     $time = time unless defined $time;
     my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($time);
     sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT",
       $DoW[$wday],
       $mday, $MoY[$mon], $year+1900,
       $hour, $min, $sec);
 }
 #####################################################################
 # из модуля HTTP::Date
 #
 sub str2time ($;$)
 {
     my $str = shift;
     return unless defined $str;
 
     # fast exit for strictly conforming string
     if ($str =~ /^[SMTWF][a-z][a-z], (\d\d) ([JFMAJSOND][a-z][a-z]) (\d\d\d\d)
 (\d\d):(\d\d):(\d\d) GMT$/) {
   return eval {
       my $t = Time::Local::timegm($6, $5, $4, $1, $MoY{$2}-1, $3-1900);
       $t < 0 ? undef : $t;
   };
     }
 
     my @d = parse_date($str);
     return unless @d;
     $d[0] -= 1900;  # year
     $d[1]--;        # month
 
     my $tz = pop(@d);
     unless (defined $tz) {
   unless (defined($tz = shift)) {
       return eval { my $t = Time::Local::timelocal(reverse @d);
         $t < 0 ? undef : $t;
            };
   }
     }
 
     my $offset = 0;
     if ($GMT_ZONE{uc $tz}) {
   # offset already zero
     }
     elsif ($tz =~ /^([-+])?(\d\d?):?(\d\d)?$/) {
   $offset = 3600 * $2;
   $offset += 60 * $3 if $3;
   $offset *= -1 if $1 && $1 ne '-';
     }
     else {
   eval { require Time::Zone } || return;
   $offset = Time::Zone::tz_offset($tz);
   return unless defined $offset;
     }
     
     return eval { my $t = Time::Local::timegm(reverse @d);
      $t < 0 ? undef : $t + $offset;
    };
 }
 
 #####################################################################
 # из модуля HTTP::Date
 # c минимальными изменениями
 #
 sub parse_date ($)
 {
     local($_) = shift;
     return unless defined;
 
     # More lax parsing below
     s/^\s+//;  # kill leading space
     s/^(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)[a-z]*,?\s*//i; # Useless weekday
 
     my($day, $mon, $yr, $hr, $min, $sec, $tz, $ampm);
 
     # Then we are able to check for most of the formats with this regexp
     (($day,$mon,$yr,$hr,$min,$sec,$tz) =
         /^
    (\d\d?)               # day
       (?:\s+|[-\/\.])    # в качестве разделителя добавлена точка
    (\w+)                 # month
       (?:\s+|[-\/\.])    # в качестве разделителя добавлена точка
    (\d+)                 # year
    (?:
          (?:\s+|:)       # separator before clock
       (\d\d?):(\d\d)     # hour:min
       (?::(\d\d))?       # optional seconds
    )?                    # optional clock
       \s*
    ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone
       \s*$
   /x)
 
     ||
 
     # Try the ctime and asctime format
     (($mon, $day, $hr, $min, $sec, $tz, $yr) =
   /^
    (\w{1,3})             # month
       \s+
    (\d\d?)               # day
       \s+
    (\d\d?):(\d\d)        # hour:min
    (?::(\d\d))?          # optional seconds
       \s+
    (?:([A-Za-z]+)\s+)?   # optional timezone
    (\d+)                 # year
       \s*$               # allow trailing whitespace
   /x)
 
     ||
 
     # Then the Unix 'ls -l' date format
     (($mon, $day, $yr, $hr, $min, $sec) =
   /^
    (\w{3})               # month
       \s+
    (\d\d?)               # day
       \s+
    (?:
       (\d\d\d\d) |       # year
       (\d{1,2}):(\d{2})  # hour:min
             (?::(\d\d))?       # optional seconds
    )
    \s*$
        /x)
 
     ||
 
     # ISO 8601 format '1996-02-29 12:00:00 -0100' and variants
     (($yr, $mon, $day, $hr, $min, $sec, $tz) =
   /^
     (\d{4})              # year
        [-\/]?
     (\d\d?)              # numerical month
        [-\/]?
     (\d\d?)              # day
    (?:
          (?:\s+|[-:Tt])  # separator before clock
       (\d\d?):?(\d\d)    # hour:min
       (?::?(\d\d))?      # optional seconds
    )?                    # optional clock
       \s*
    ([-+]?\d\d?:?(:?\d\d)?
     |Z|z)?               # timezone  (Z is "zero meridian", i.e. GMT)
       \s*$
   /x)
 
     ||
 
     # Windows 'dir' 11-12-96  03:52PM
     (($mon, $day, $yr, $hr, $min, $ampm) =
         /^
           (\d{2})                # numerical month
              -
           (\d{2})                # day
              -
           (\d{2})                # year
              \s+
           (\d\d?):(\d\d)([APap][Mm])  # hour:min AM or PM
              \s*$
         /x)
 
     ||
     return;  # unrecognized format
 
     # Translate month name to number
     $mon = $MoY{$mon} ||
            $MoY{"\u\L$mon"} ||
      ($mon >= 1 && $mon <= 12 && int($mon)) ||
            return;
 
     # If the year is missing, we assume first date before the current,
     # because of the formats we support such dates are mostly present
     # on "ls -l" listings.
     unless (defined $yr) {
   my $cur_mon;
   ($cur_mon, $yr) = (localtime)[4, 5];
   $yr += 1900;
   $cur_mon++;
   $yr-- if $mon > $cur_mon;
     }
     elsif (length($yr) < 3) {
   # Find "obvious" year
   my $cur_yr = (localtime)[5] + 1900;
   my $m = $cur_yr % 100;
   my $tmp = $yr;
   $yr += $cur_yr - $m;
   $m -= $tmp;
   $yr += ($m > 0) ? 100 : -100
       if abs($m) > 50;
     }
 
     # Make sure clock elements are defined
     $hr  = 0 unless defined($hr);
     $min = 0 unless defined($min);
     $sec = 0 unless defined($sec);
 
     # Compensate for AM/PM
     if ($ampm) {
   $ampm = uc $ampm;
   $hr = 0 if $hr == 12 && $ampm eq 'AM';
   $hr += 12 if $ampm eq 'PM' && $hr != 12;
     }
 
     return($yr, $mon, $day, $hr, $min, $sec, $tz)
   if wantarray;
     
     if (defined $tz) {
   $tz = "Z" if $tz =~ /^(GMT|UTC?|[-+]?0+)$/;
     } else {
   $tz = "";
     }
     return sprintf("%04d-%02d-%02d %02d:%02d:%02d%s",
       $yr, $mon, $day, $hr, $min, $sec, $tz);
 }
 
 === cut ===
 
 Michael Poliakov
 --- ifmail v.2.15dev5
  * Origin: Nizhniny Novgorod Information Networks (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Дата в секунды?   Andrey Larushkin   28 Nov 2001 09:40:47 
 Re: Дата в секунды?   Kirill Solomko   28 Nov 2001 16:25:35 
 Re: Дата в секунды?   Slava Gorbanev   28 Nov 2001 22:32:21 
 Re: Дата в секунды?   Michael Poliakov   29 Nov 2001 15:19:50 
Архивное /ru.perl/20800a6b4aa2.html, оценка 1 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional