Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > localtime


Автор: Agares 30.9.2008, 14:28
Использую так:
Код

my $date = localtime->mday . localtime->mon . localtime->year+1900;

выдает не правильную дату (310008, хотя должна выдавать 300908)

где моя ошибка?

Автор: ginnie 30.9.2008, 14:31
Уважаемый Agares, использую так

Код

perl -e 'my $date = localtime->mday . localtime->mon . localtime->year+1900; print $date;'


Выдает

Код

Can't locate object method "mday" via package "Tue Sep 30 15:30:02 2008" (perhaps you forgot to load "Tue Sep 30 15:30:02 2008"?) at -e line 1.


 smile 

Где моя ошибка?

P.S.

Код

perl -e 'my $date = "20"."30"+100; print $date;'


выдает 2130, т.к. у операторов + и . одинаковый приоритет и они выполняются последовательно слева направо.


Автор: amg 30.9.2008, 14:52
Цитата(Agares @  30.9.2008,  14:28 Найти цитируемый пост)
Использую так:
А почему не так, как предлагают в документации?
Код
my ($mday,$mon,$year) = (localtime)[3..5];
my $date = sprintf '%d.%02d.%02d', $mday, $mon+1,($year+1900)%100;

Автор: ginnie 30.9.2008, 14:55
amg, это кто такое ($year+1900)%100 в документации предлагает?  smile 

Автор: amg 30.9.2008, 15:03
Цитата(ginnie @  30.9.2008,  14:55 Найти цитируемый пост)
amg, это кто такое ($year+1900)%100 в документации предлагает?
Там есть строки
Код
$year += 1900;
$year = sprintf("%02d", $year % 100);
Ну а преобразовать их в ($year+1900)%100 я сам сообразил  smile 

Автор: KSURi 30.9.2008, 15:05
UPD:
сори, не так понял вопрос

Автор: ginnie 30.9.2008, 15:11
amg, в документации это написано последовательно (по тексту), но не означает, что так и надо писать (все вместе) smile

($year+1900)%100 от $year % 100 отличается только лишним сложением, электроэнергию надо экономить  smile 

Автор: amg 30.9.2008, 15:17
Цитата(ginnie @  30.9.2008,  15:11 Найти цитируемый пост)
($year+1900)%100 от $year % 100 отличается только лишним сложением, электроэнергию надо экономить
(Тут должен быть смайлик, стучащий себя по лбу)

Автор: ginnie 30.9.2008, 16:51
Кстати, по поводу основного вопроса, рекомендовал другим модуль B::Deparse, а сам не пользуюсь  smile 

Код

perl -MO=Deparse,-p -e 'my $date = localtime->mday . localtime->mon . localtime->year+1900;'


дает

Код

(my $date = (((localtime->mday . localtime->mon) . localtime->year) + 1900));

Автор: KSURi 30.9.2008, 18:20
ginnie, так ведь выше сами написали, что у . и + одинаковый приоритет.

Автор: ramus 30.9.2008, 22:10
Кстати, насчет электричества smile

пользуюсь гдето подсмотренным вариантом, использующим только один системный вызов функции localtime
почему то мне кажется что так нагрузка на сервер будет меньше

$s = sprintf "%4d/%02d/%02d %02d:%02d:%02d: prg_name(perl): Begin work\n", 
        sub{($_[5]+1900, $_[4]+1, $_[3], $_[2], $_[1], $_[0])}->(localtime);

это как рабочий пример, естественно без sprintf электроэнергии еще меньше тратится smile
правда она тогда в тепло выделяется :(

еще примеры (зато работают smile
Код

$YY     = sprintf "%02d",sub{(substr($_[5]+1900,2,2))}->(localtime);
$YYMMDD = sprintf "%02d%02d%02d",sub{(substr($_[5]+1900,2,2),$_[4]+1, $_[3])}->(localtime);
$DDMM   = sprintf "%02d%02d",sub{($_[3], $_[4]+1)}->(localtime);
$JJJ    = sprintf "%03d",sub{($_[7])}->(localtime);
$MM     = sprintf "%02d",sub{($_[4]+1)}->(localtime);


Автор: ginnie 1.10.2008, 00:47
ramus, за такое

Цитата

$s = sprintf "%4d/%02d/%02d %02d:%02d:%02d: prg_name(perl): Begin work\n", 
        sub{($_[5]+1900, $_[4]+1, $_[3], $_[2], $_[1], $_[0])}->(localtime);


надо на кол и премию вручать, посмертно  smile
Как только не изголяются программисты, чтобы написать все в одну строку!  smile 

Завтра сравним по производительности с моим любимым вариантом

Код

my @localtime = (localtime())[5,4,3,2,1,0];
$localtime[0] += 1900;
$localtime[1]++;
my $s = sprintf("%4d/%02d/%02d %02d:%02d:%02d: prg_name(perl): Begin work\n", @localtime);


Что-то мне подсказывает, что мой вариант...  smile 

Автор: rcdimon 1.10.2008, 10:59
Я ваще вот так деаю всегда 

Код

my ($sec, $n_min, $n_hour, $n_mday, $n_mon, $n_year, $n_wsday, $n_yday, $n_isdst)=localtime;
$n_year+=1900;
$n_mon++;
my $mydate = $year . '-' . $mon . '-' . $mday;


 smile 

Автор: ginnie 1.10.2008, 11:43
Провел тестирование двух вариантов, разница в производительности практически отсутствует.

Код

use strict;
use warnings;

use Test::Timestamp;

my $timer = Test::Timestamp->new();

$timer->stamp('start test 1');
for ( my $counter = 0 ; $counter < 10000 ; $counter++ ) {
    my @localtime = ( localtime() )[ 5, 4, 3, 2, 1, 0 ];
    $localtime[0] += 1900;
    $localtime[1]++;
    my $s = sprintf( "%4d/%02d/%02d %02d:%02d:%02d: prg_name(perl): Begin work\n", @localtime );
}
$timer->stamp('stop test 1');
$timer->stamp('start test 2');
for ( my $counter = 0 ; $counter < 10000 ; $counter++ ) {
    my $s = sprintf "%4d/%02d/%02d %02d:%02d:%02d: prg_name(perl): Begin work\n",
      sub { ( $_[5] + 1900, $_[4] + 1, $_[3], $_[2], $_[1], $_[0] ) }->(localtime);

}
$timer->stamp('stop test 2');


результаты такие:

Код

#              Time:    Increment: Label
           0.000066:     0.000066: start test 1
           0.155115:     0.155049: stop test 1
           0.155131:     0.000016: start test 2
           0.318173:     0.163042: stop test 2


Код

#              Time:    Increment: Label
           0.000200:     0.000200: start test 1
           0.154849:     0.154649: stop test 1
           0.154862:     0.000013: start test 2
           0.317820:     0.162959: stop test 2




Автор: arto 1.10.2008, 13:08
# perl -MBenchmark -e 'sub A () { my @a = localtime; return ( @a[0..3],$a[4]+1,$a[5]+1900 
} sub B () { return sub { @_[0..3],$_[4]+1,$_[5]+1900 }->(localtime) } timethese ($ARGV[0],{ A => \&A,B => \&B
)' 10000000
Benchmark: timing 10000000 iterations of A, B...
         A: 143 wallclock secs (75.38 usr + 58.65 sys = 134.03 CPU) @ 74610.16/s (n=10000000)
         B: 125 wallclock secs (63.99 usr + 58.12 sys = 122.11 CPU) @ 81893.37/s (n=10000000)
# print -f "%.2f%%\\n" $[(81893.37-74610.16)/74610.16*100]
9.76%
#

Автор: amg 1.10.2008, 13:34
Цитата(Agares @ 30.9.2008,  14:28)
Использую так:
Код
my $date = localtime->mday . localtime->mon . localtime->year+1900;

выдает не правильную дату (310008, хотя должна выдавать 300908)
где моя ошибка?

Понял я наконец, откуда мог взяться такой синтаксис (localtime->mday etc.). 
Код
use Time::localtime;
my $date = localtime->mday . (localtime->mon + 1) . (localtime->year % 100);


Автор: ginnie 1.10.2008, 15:04
arto, тест со sprintf() дает другие результаты:

Код

use strict;
use warnings;

use Benchmark qw(:hireswallclock);

sub A () {
    my @localtime = ( localtime() )[ 5, 4, 3, 2, 1, 0 ];
    $localtime[0] += 1900;
    $localtime[1]++;
    my $s = sprintf( "%4d/%02d/%02d %02d:%02d:%02d: prg_name(perl): Begin work\n", @localtime );
}

sub B () {
    my $s = sprintf "%4d/%02d/%02d %02d:%02d:%02d: prg_name(perl): Begin work\n",
      sub { ( $_[5] + 1900, $_[4] + 1, $_[3], $_[2], $_[1], $_[0] ) }->(localtime);
};

timethese (1000000, { A => \&A, B => \&B });


Код

Benchmark: timing 100000 iterations of A, B...
         A: 1.65336 wallclock secs ( 1.30 usr +  0.16 sys =  1.46 CPU) @ 68449.20/s (n=100000)
         B: 1.76267 wallclock secs ( 1.41 usr +  0.14 sys =  1.55 CPU) @ 64321.61/s (n=100000)


но это не принципиально smile 

пока тестировал, обнаружил вот что

Код

use strict;
use warnings;

use Benchmark qw(:hireswallclock);

sub A () {
    my @a = localtime;
    return(@a[0..3],$a[4]+1,$a[5]+1900);
}

sub B () {
    return sub { @_[0..3],$_[4]+1,$_[5]+1900 }->(localtime);
};

sub C () {
    return(localtime());
}

timethese (100000, { A => \&A, B => \&B, C => \&C });


Код

A: 1.10945 wallclock secs ( 0.86 usr +  0.12 sys =  0.98 CPU) @ 102400.00/s (n=100000)
B: 0.922597 wallclock secs ( 0.71 usr +  0.11 sys =  0.82 CPU) @ 121904.76/s (n=100000)
C: 1.07489 wallclock secs ( 0.86 usr +  0.09 sys =  0.95 CPU) @ 104918.03/s (n=100000)


Сильно удивила функция C()  smile 

Автор: KSURi 1.10.2008, 15:20
Цитата(amg @  1.10.2008,  13:34 Найти цитируемый пост)
Понял я наконец, откуда мог взяться такой синтаксис (localtime->mday etc.). 

Значит мой первый пост в теме был все-таки нормальным) Как раз написал
Код

use Time::localtime;

Автор: ramus 1.10.2008, 19:52
Какое бурное обсуждение  smile  интересно читать 

Спасибо ginnie  за сравнение производительности

Цитата(rcdimon @ 1.10.2008,  10:59)

Я ваще вот так деаю всегда 
Код

my ($sec, $n_min, $n_hour, $n_mday, $n_mon, $n_year, $n_wsday, $n_yday, $n_isdst)=localtime;



Я тоже так писал раньше, но потом отказался. Вначале моего освоения модулей perl, при использовании такой конструкции в модуле, функция localtime упорно возвращала значение НЕ в списковом контексте. 
Победил только так
Код

package My_package;
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst);
  my $tm = localtime(time);
  ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = @$tm;


Но мне это не понравилось своей не универсальностью и я стараюсь не использовать сомнительные конструкции. Хотя она рекомендуется в мануале...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)