5

1か月かかる場合に日付を調整する組み込みのPerl関数があるかどうか疑問に思っていました。たとえば、日付が 31 日の場合、31 日がない場合は前月末に調整されます。

31日が隣り合っている月(12月/ 1月、7月/ 8月)と2月でなければ、簡単に30日に変更します。現在の日付から一定時間離れた日付を保存したいだけです。

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

$current_date = join("-", (1900+$year), ($mon+1), $mday);
$one_month_ago = join("-", (1900+$year), ($mon), $mday);
$one_year_ago = join("-", (1899+$year), ($mon+1), $mday);

2 月のインスタンスは年にしか適用されないので対処できますが、これが 2012 年 12 月 31 日に取得された場合、1 か月を削除すると 2012 年 11 月 31 日を意味し、もちろん存在しません。自分で物事を複雑にする前に、機能があるかどうかを尋ねると思いました...ありがとう:)

4

3 に答える 3

10

DateTime は組み込みモジュールではありませんが、インストールすると、次の計算が簡単になります。

#!/usr/bin/perl
use strict;
use warnings;

use feature qw( say );
use DateTime;

my $dt = DateTime->now;
say $dt->ymd;

$dt->truncate( to => month );

say $dt->ymd;

$dt->add( days => -1 );
say $dt->ymd;

foreach ( 1 .. 12 ) { 
    $dt->add( months => -1 );
    say $dt->ymd;
} 

これを今日 (2012 年 8 月 29 日) 実行すると、次の出力が得られます。

[~] $ perl dt.pl 
2012-08-29
2012-08-01
2012-07-31
2012-06-30
2012-05-31
2012-04-30
2012-03-31
2012-02-29
2012-01-31
2011-12-31
2011-11-30
2011-10-31
2011-09-30
2011-08-31
2011-07-31
于 2012-08-29T11:20:05.547 に答える
9

他の人は を提案DateTimeしましたが、それは非常に大きく、コアではなく、遅くなる可能性があります。

より簡単な解決策は、ビルトインlocaltimePOSIX::mktime関数を使用することです。

use POSIX qw( mktime );

my @t = localtime $epoch;
$t[4] -= 2;  # $t[4] is tm_mon
my $two_months_ago = mktime @t;

このmktime()関数は、特に非正規化された値を処理します。1月マイナス2ヶ月が前年の11月などに対応します。同じ秒・分・時、同じ月の同じ日を保ちます。

于 2012-08-29T11:59:03.740 に答える
8

モジュールDateTimeをインストールする機会があれば。日付を扱うとき、それはあなたに多くの特典を与えます。

use strict;
use DateTime;

my $epoch = ...;
my $dt    = DateTime->from_epoch( epoch => $epoch );
$dt->subract(months => 1);

printf "%s", $dt->datetime();
于 2012-08-29T11:20:52.753 に答える