Perlスクリプトを記述するとき、_YYYY-mm-dd HH:MM:SS
_(たとえば_2009-11-29 14:28:29
_)としてフォーマットされた文字列として表される現在の時刻を取得する必要があることがよくあります。
これを行う際に、私はこの非常に面倒なパスを取っていることに気付きます
man perlfunc
_/localtime
_ localtimeを検索する-5回繰り返して(_/
_ + _\n
_)、マンページの関連セクションに到達します($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
_をマンページからスクリプトにコピーします。my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec);
で試してくださいmy $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon, $mday, $hour, $min, $sec);
で試してくださいmy $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
で試してください上記のプロセスは機能しますが、最適とはほど遠いものです。よりスマートな方法があると確信しているので、私の質問は単純です:
Perlで現在の日付/時刻の_YYYY-mm-dd HH:MM:SS
_を取得する最も簡単な方法は何ですか?
「簡単」には、「書きやすい」と「覚えやすい」の両方が含まれます。
標準の strftime
モジュールでPOSIX
を使用します。 Perlバインディングの strftime
の引数は、 localtime
および gmtime
。比較する
strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
と
my ($sec,$min,$hour,$mday,$mon,$year,$wday, $yday, $isdst) = gmtime(time);
コマンドラインの使用例は
$ Perl -MPOSIX -le 'print strftime "%F %T", localtime $^T'
またはソースファイルから
use POSIX;
print strftime "%F %T", localtime time;
一部のシステムは%F
および%T
の短縮形をサポートしていないため、明示的に指定する必要があります
print strftime "%Y-%m-%d %H:%M:%S", localtime time;
または
print strftime "%Y-%m-%d %H:%M:%S", gmtime time;
time
は、呼び出されたときに現在の時刻を返しますが、 $^T
はプログラムが開始された時刻に固定されていることに注意してください。 gmtime
の場合、戻り値はGMTの現在の時刻です。 localtime
を使用して、ローカルタイムゾーンの時間を取得します。
DateTime
モジュールを使用して、汚い仕事をしていないのは何ですか? and覚えやすい!
use strict;
use warnings;
use DateTime;
my $dt = DateTime->now; # Stores current date and time as datetime object
my $date = $dt->ymd; # Retrieves date as a string in 'yyyy-mm-dd' format
my $time = $dt->hms; # Retrieves time as a string in 'hh:mm:ss' format
my $wanted = "$date $time"; # creates 'yyyy-mm-dd hh:mm:ss' string
print $wanted;
何が起こっているのかがわかれば、tempを取り除き、数行のコードを保存できます。
use strict;
use warnings;
use DateTime;
my $dt = DateTime->now;
print join ' ', $dt->ymd, $dt->hms;
これを試して:
use POSIX qw/strftime/;
print strftime('%Y-%m-%d',localtime);
strftime
メソッドは、私にとって効果的な仕事をします。非常にシンプルで効率的。
Time :: Piece (Perl 5.10以降のコア内)にはstrftime関数もあり、デフォルトでlocaltimeとgmtimeをオーバーロードしてTime :: Pieceオブジェクトを返します:
use Time::Piece;
print localtime->strftime('%Y-%m-%d');
または、オーバーライドされた現地時間なし:
use Time::Piece ();
print Time::Piece::localtime->strftime('%F %T');
次のブロックをそれぞれ1.000.000回呼び出す小さなテスト(VMのFreeBSDでのPerl v5.20.1)を行いました。
A
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
B
my $now = strftime('%Y%m%d%H%M%S',localtime);
C
my $now = Time::Piece::localtime->strftime('%Y%m%d%H%M%S');
次の結果があります。
A:2秒
B:11秒
C:19秒
もちろん、これは完全なテストやベンチマークではありませんが、少なくとも私にとっては再現可能です。したがって、より複雑ですが、datetimestampの生成が非常に頻繁に必要な場合は、最初の方法をお勧めします。
呼び出し(例:FreeBSD 10.1の下)
my $now = `date "+%Y%m%d%H%M%S" | tr -d "\n"`;
oSに依存せず、かなり時間がかかるため、あまり良いアイデアではないかもしれません。
よろしく、ホルガー
正確な形式ではなく、人間が読み取れる時間文字列が必要な場合:
$t = localtime;
print "$t\n";
プリント
Mon Apr 27 10:16:19 2015
またはあなたのロケール用に設定されているものは何でも。
Time::Piece::datetime()
はT
を削除できます。
use Time::Piece;
print localtime->datetime(T => q{ });
短くて甘い、追加のモジュールは不要:
my $toDate = `date +%m/%d/%Y" "%l:%M:%S" "%p`;
たとえば、出力は2017年4月25日午前9時30分33秒です。
多くの場合、必要な「現在時刻」はむしろ$ ^ Tです。これは、スクリプトが実行を開始した時刻であり、UNIXエポック以降の秒単位(60秒と仮定)で表されます。
これにより、スクリプトの初期部分が、クエリ条件やその他の派生値など、スクリプトの後半部分とは異なる日付(または夏時間ステータス)を使用することを防ぎます。
'現在時刻'のそのバリアントでは、定数を使用して、コンパイル時に凍結されたことを文書化することもできます。
use constant YMD_HMS_AT_START => POSIX::strftime( "%F %T", localtime $^T );
別の高解像度の起動時間:
0+ [ Time::HiRes::stat("/proc/$$") ]->[10]