|
|
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) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/20800a6b4aa2.html, оценка из 5, голосов 10
|