0

私は現在、多くの時間関連の機能を扱うモジュールを構築しています。localtime(time) は、返される配列 (sec、min、hour、dayofmonth、mon、year、weekday、yearday、isDST) がタイムスタンプに役立つため、頻繁に使用しており、一貫性のために可能な限りこれを使用したいと考えています。

与えられた時差に基づいて時間を計算する方法を作成する必要があります (つまり、「5 日前の日付は何だった?」など)。私の現在の考えは、違いを「差分配列」として設定し(例では [0,0,0,-5,0,0,0,-5,0] のようなもの)、これをに追加することです新しい日付を与えるベースタイム。しかし、これには境界時間 (前の月にロールバックするなど) とすべてを正しく調整する (夏時間など) という問題があります。

私のもう1つの考えは、timelocal()を使用してこれを時間値に変換し直し、フラットな差を与え、それを基本時間に追加して結果の時間を取得し、次にlocaltimeを使用して変換し直して、モジュールの残りの部分。しかし、潜在的に負の値を不規則に処理する可能性があるため、これは問題になる可能性があります。

もちろん、最初のメソッドの配列値を正規化することも、一連の値を時間値から減算することもできます (つまり、定数のリスト、Day = 8400、hour = 3600、min = 60 のようなものです)。しかし、これらはどちらも面倒であり、私の質問は本質的に、これを解決するために取ることができる別の(そしてよりエレガントな)アプローチがあり、それでも localtime で使用される配列に時間を戻すことができるので、残りの部分と一貫性がありますモジュール?

4

2 に答える 2

1

それを行うためのより洗練された方法は、時間ベースのオブジェクトを使用することです。それらを使用すると、より高い、より抽象的なレベルで計算を行うことができ、日/月/年の境界を処理する とlocaltimeの間のすべての変換から解放されます。timelocal

それを可能にするさまざまなモジュールがあります。Time::Piece (コアの一部であり、非常に高速で軽量でもあります) から始めて、必要に応じて十分でない場合は、より重いものに移行することをお勧めします。

use Time::Piece;    # takes over localtime()
use Time::Seconds;  # use constant ONE_DAY

my $now = localtime();
my $five_days_ago = $now - ONE_DAY * 5;

print $now, "\n";           # same as if you used localtime() w/o Time::Piece
print $now->datetime, "\n"; # 2000-02-29T12:34:56 (ISO 8601)

my $diff = $now - $five_days_ago;
print $diff->pretty, "\n";

Time::Piece下位互換性のある方法でオーバーライドlocaltimeするため、既存のコードに簡単に導入できるはずです。

于 2013-04-02T10:23:38.020 に答える