質問

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]
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top