PerlでYYYY-mm-dd HH:MM:SSにすばやく到達する
-
06-07-2019 - |
質問
Perlスクリプトを記述するとき、 YYYY-mm-dd HH:MM:SS
(たとえば 2009-11-29 14:28:29
)。
これを行う際に、私はこの非常に面倒なパスを取っていることに気付きます:
-
man perlfunc
現地時間を検索するには -
/ 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);
- 覚えておくべきこと#1:現在の年を取得するには、$ yearに1900を追加する必要があります。
-
my $ now = sprintf("%04d-%02d-%02d%02d:%02d:%02d"、$ year + 1900、$ mon、$ mday、$ hour、$ minで試してください、$ sec);
- 覚えておきたいこと#2:現在の月を取得するには、$ monに1を追加する必要があります。
-
my $ now = sprintf("%04d-%02d-%02d%02d:%02d:%02d"、$ year + 1900、$ mon + 1、$ mday、$ hour、 $ min、$ sec);
- 大丈夫そうです。完了!
上記で概説したプロセスは機能しますが、最適とはほど遠いものです。よりスマートな方法があると確信しているので、私の質問は単純です:
Perlで現在の日付/時刻の YYYY-mm-dd HH:MM:SS
を取得する最も簡単な方法は何ですか?
「簡単」な場所「書きやすい」の両方を含みます。および「覚えやすい」。
解決
標準の POSIX
<で strftime
を使用しますモジュール。 Perlのバインディングの strftime
の引数 localtime
からの戻り値に合わせて設計されました。 gmtime
。比較
strftime(fmt, sec, min, hour, mday, mon, year, wday = -1, yday = -1, isdst = -1)
with
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
モジュールを使用しないのは何ですか?書くのは簡単ですし、覚えておいてください!
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;
何が起こっているかがわかったら、一時ファイルを削除して数行のコードを保存できます:
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をオーバーロードしますTime :: Pieceオブジェクトを返すgmtime:
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に依存せず、かなり時間がかかるため、あまり良いアイデアではないかもしれません。
よろしく、 ホルガー
Time :: Piece :: datetime()
は T
を排除できます。
use Time::Piece;
print localtime->datetime(T => q{ });
正確な形式ではなく、人間が読み取れる時刻文字列のみが必要な場合:
$t = localtime;
print "$t\n";
印刷
Mon Apr 27 10:16:19 2015
またはロケール用に設定されているもの。
短くて甘い、追加のモジュールは必要ありません:
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]