日付/時刻が (年、月、日、時、分、秒) の配列として与えられた場合、それをエポック時間、つまり 1970-01-01 00:00:00 GMT からの秒数にどのように変換しますか? ?
おまけの質問: 日付/時刻が文字列として与えられた場合、最初にどのように (y,m,d,h,m,s) 配列に解析しますか?
DateTimeモジュールを使用している場合は、DateTime オブジェクトでepoch()メソッドを呼び出すことができます。これが UNIX 時間と見なされるためです。
DateTimes を使用すると、エポックから日付オブジェクトにかなり簡単に変換できます。
あるいは、localtimeと gmtime はエポックを年月日を含む配列に変換し、Time::Local モジュールの timelocal と timegmは反対のことを行い、時間要素の配列 (秒、分、...、日) を変換します。 、月など) エポックに。
これは、UNIX時間を取得する最も簡単な方法です。
use Time::Local;
timelocal($second,$minute,$hour,$day,$month-1,$year);
引数の順序が逆であり、1月が月0であることに注意してください。その他の多くのオプションについては、CPANのDateTimeモジュールを参照してください。
解析については、CPANのDate::Parseモジュールを参照してください。日付の解析に本当に慣れる必要がある場合は、Date :: Manipが役立つ場合がありますが、独自のドキュメントでは、荷物が多いため(たとえば、一般的な休日などを知っているため)、Date::Manipから離れるように警告されています。ソリューションははるかに高速です。
解析する日付/時刻の形式について何か知っている場合は、単純な正規表現で十分かもしれませんが、適切なCPANモジュールを使用することをお勧めします。たとえば、日付が常にYMDHMSの順序になることがわかっている場合は、CPANモジュールDateTime :: Format::ISO8601を使用します。
私自身の参考のために、以下は、日付が常にYMDHMSの順序であり、「HMS」部分の全部または一部がオプションであることがわかっているアプリケーションに使用する関数です。すべての区切り文字(「2009-02-15」または「2009.02.15」など)を受け入れます。対応するUNIX時間(1970-01-01 00:00:00 GMTからの秒数)を返します。解析できなかった場合は-1を返します(つまり、1969年の日付を合法的に解析する必要がないことを確認してください- 12-31 23:59:59)。また、「69」までの2桁の年XXは「20XX」を指し、それ以外の場合は「19XX」(たとえば、「50-02-15」は2050-02-15を意味しますが、「75-02-15」は1975-を意味します)を想定しています。 02-15)。
use Time::Local;
sub parsedate {
my($s) = @_;
my($year, $month, $day, $hour, $minute, $second);
if($s =~ m{^\s*(\d{1,4})\W*0*(\d{1,2})\W*0*(\d{1,2})\W*0*
(\d{0,2})\W*0*(\d{0,2})\W*0*(\d{0,2})}x) {
$year = $1; $month = $2; $day = $3;
$hour = $4; $minute = $5; $second = $6;
$hour |= 0; $minute |= 0; $second |= 0; # defaults.
$year = ($year<100 ? ($year<70 ? 2000+$year : 1900+$year) : $year);
return timelocal($second,$minute,$hour,$day,$month-1,$year);
}
return -1;
}
日付を解析するには、CPANのDate::Parseを見てください。
$ENV{TZ}="GMT";
POSIX::tzset();
$time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900);
use Date::Manip;
$string = '18-Sep-2008 20:09'; # or a wide range of other date formats
$unix_time = UnixDate( ParseDate($string), "%s" );
編集:
Date :: Manipは大きくて遅いですが、解析は非常に柔軟で、純粋なPerlです。コードを書いているときに急いでいて、実行しているときに急いでいないことがわかっている場合に使用します。
たとえば、起動時にコマンドラインオプションを解析するために使用しますが、ビジー状態のWebサーバーで大量のデータを解析するために使用しないでください。
著者のコメントを参照してください。
(以下の最初のコメントの作者に感謝します)
私のお気に入りの日時パーサーはDateTime::Format :: ISO8601 です。これが機能するようになると、epoch()を使用してエポック秒に簡単に変換できるDateTimeオブジェクトが作成されます。
おそらく、CPANの助けを借りて、または使わずに、「それを行うには複数の方法があります」のより良い例の1つです。
'date / time'として渡されるものを制御できる場合は、特定のDate :: Time :: Formatサブクラスを使用するか、DateTime :: Format :: Strptimeを使用して、 DateTimeルートを使用することをお勧めします。奇抜な日付形式をサポートするものはありません(詳細については、日時に関するFAQを参照してください)。一般に、Date :: Timeは、結果に対して深刻なことをしたい場合に最適な方法です。CPANのいくつかのクラスは、肛門性格が非常に高く、執拗に正確です。
奇妙なフリーフォームのものを期待している場合は、Date :: Parseのstr2time()メソッドにスローします。これにより、エポックからの秒数の値が取得され、Dateのオーバーヘッドなしで邪悪な方法を使用できます。 :マニピュレータ。
!#/bin/sh
詳しくは、スクリプトなどに適用できるワンライナーを参照してください。
EPOCH="`perl -e 'use Time::Local; print timelocal('${SEC}','${MIN}','${HOUR}','${DAY}','${MONTH}','${YEAR}'),\"\n\";'`"
8 進数値を避けることを忘れないでください!
CPAN には多くの日付操作モジュールがあります。私が特に気に入っているのはDateTimeです。strptime モジュールを使用すると、日付を任意の形式で解析できます。CPAN には、特殊な日付形式を処理するための DateTime::Format モジュールも多数ありますが、strptime が最も一般的です。
標準入力のさまざまなISO関連形式の日付(およびMighty Kuhnの記述を読んだ後に他の何かを使用するのは誰か)を標準出力のエポック時間から秒に変換するフィルターは、両方の部分を説明するのに役立つ可能性があります:
martind@whitewater:~$ cat `which isoToEpoch`
#!/usr/bin/perl -w
use strict;
use Time::Piece;
# sudo apt-get install libtime-piece-perl
while (<>) {
# date --iso=s:
# 2007-02-15T18:25:42-0800
# Other matched formats:
# 2007-02-15 13:50:29 (UTC-0800)
# 2007-02-15 13:50:29 (UTC-08:00)
s/(\d{4}-\d{2}-\d{2}([T ])\d{2}:\d{2}:\d{2})(?:\.\d+)? ?(?:\(UTC)?([+\-]\d{2})?:?00\)?/Time::Piece->strptime ($1, "%Y-%m-%d$2%H:%M:%S")->epoch - (defined ($3) ? $3 * 3600 : 0)/eg;
print;
}
martind@whitewater:~$
コマンドライン ユーティリティ (つまり、他の関数から呼び出されるものではない) を探しているだけの場合は、このスクリプトを試してください。GNU date が存在することを前提としています (ほぼすべての Linux システムに存在します):
#! /usr/bin/perl -w
use strict;
$_ = (join ' ', @ARGV);
$_ ||= <STDIN>;
chomp;
if (/^[\d.]+$/) {
print scalar localtime $_;
print "\n";
}
else {
exec "date -d '$_' +%s";
}
仕組みは次のとおりです。
$ Time now
1221763842
$ Time yesterday
1221677444
$ Time 1221677444
Wed Sep 17 11:50:44 2008
$ Time '12:30pm jan 4 1987'
536790600
$ Time '9am 8 weeks ago'
1216915200