5

現在、次の形式で日時を提供するサードパーティのAPIを使用しています。

Sat Mar 06 09:00:00 ICST 2010
Fri Feb 19 19:30:00 JDT 2010
Fri Feb 19 19:30:00 PST 2010

ただし、これらの日時オブジェクトをMySQLの標準の日時フィールドに格納する必要があります。このフィールドには、次の形式が必要です。

YYYY-MM-DD HH:MM:SS

現在、KDT、JDT、ICSTなどの特定のタイムゾーンのエラーを報告している次のコードを使用しています。

use Date::Manip;
use DateTime;
use DateTime::Format::DateManip;

my $date = ParseDate($time);
$date = DateTime::Format::DateManip->parse_datetime($date);
eval{ $time = $date->strftime("%Y-%m-%d %H:%M:%S"); };

上記のPerlコードのより良い実装を推奨して、日時オブジェクトをAPIから、MySQL日時フィールドに挿入するサーバー上の適切な形式と時刻に変換できますか?

よろしくお願いします!

4

4 に答える 4

6

時刻をGMTで内部的に保存します。GMTですべての操作を行います。次に、最後の瞬間に、結果をユーザーに表示しようとしているときに、ユーザーの現地時間変換します。

Date :: Parseを使用することをお勧めしますが、たとえば、現在インドシナの夏時間と日本の夏時間がないため、タイムゾーンのオフセットを増やす必要があります。

#! /usr/bin/perl

use warnings;
use strict;

use Date::Format;
use Date::Parse;

# add timezone offsets
$Time::Zone::Zone{icst} = +7*3600;
$Time::Zone::Zone{jdt}  = +9*3600;

while (<DATA>) {
  chomp;
  warn("$0: failed conversion for $_\n"), next
    unless defined(my $time_t = str2time $_);

  my @t = gmtime($time_t);
  print $_, " => ", strftime("%Y-%m-%d %H:%M:%S", @t), "\n";
}

__DATA__
Sat Mar 06 09:00:00 ICST 2010
Fri Feb 19 19:30:00 JDT 2010
Fri Feb 19 19:30:00 PST 2010

出力:

3月6日土曜日09:00:00ICST2010 => 2010-03-06 02:00:00
2月19日金曜日19:30:00JDT2010 => 2010-02-19 10:30:00
2月19日金曜日19:30:00PST2010 => 2010-02-20 03:30:00

必要なクエリをサポートするには、時刻をGMTとオフセット(つまり、GMTからAPIからの現地時間まで)で保存します。str2time以下のコードは、指定された時間を解析できる場合は、も解析できると想定していることに注意してくださいstrptime。ループをに変更します

my @dates;
while (<DATA>) {
  chomp;
  warn("$0: failed conversion for $_\n"), next
    unless defined(my $time_t = str2time $_);

  my $zone = (strptime $_)[-1];
  my @t = gmtime($time_t);
  push @dates => [ strftime("%Y-%m-%d %H:%M:%S", @t)
                 , sprintf("%+03d:%02d",
                           int($zone / 3600),
                           int($zone % 3600) / 60)
                 , $_
                 ];
}

収集された時間を使用して、SQLとしてレンダリングします。

print "DROP TABLE IF EXISTS dates;\n",
      "CREATE TABLE dates (date DATETIME, offset CHAR(6));\n",
      "INSERT INTO dates (date,offset) VALUES\n",
        join(",\n\n" =>
          map("  -- $_->[2]\n" .
              "  ('$_->[0]','$_->[1]')", @dates)),
        ";\n",
      "SELECT CONVERT_TZ(date,'+00:00',offset) FROM dates;\n"

出力は

DROP TABLE IF EXISTS dates;
CREATE TABLE dates (date DATETIME, offset CHAR(6));
INSERT INTO dates (date,offset) VALUES
  -- Sat Mar 06 09:00:00 ICST 2010
  ('2010-03-06 02:00:00','+07:00'),

  -- Fri Feb 19 19:30:00 JDT 2010
  ('2010-02-19 10:30:00','+09:00'),

  -- Fri Feb 19 19:30:00 PST 2010
  ('2010-02-20 03:30:00','-08:00');
SELECT CONVERT_TZ(date,'+00:00',offset) FROM dates;

パイプで接続できますmysql

$ ./prog.pl | mysql -u username -D dbname
CONVERT_TZ(date、'+ 00:00'、offset)
2010-03-06 09:00:00
2010-02-19 19:30:00
2010-02-19 19:30:00
于 2010-02-12T16:59:31.473 に答える
3

日付を保存するときは、常にUTCで保存する必要があります。これにより、データベースからそれらをフェッチし、ユーザーに表示するために必要に応じて適切なタイムゾーンに変換できます。

Perlで日時を適切に処理するには、あらゆる種類のさまざまな入力および出力形式用のパーサーとフォーマッターを備えたDateTimeスイートを心からお勧めします。

OPにリストされている日付が標準形式であるかどうかはわかりませんが、そうでない場合は、それらからDateTime形式を作成するのは非常に簡単です。

my $str = 'Sat Mar 06 09:00:00 ICST 2010';
my ( $month, $day, $hour, $min, $sec, $tz, $year ) = ( $str =~ m{\w{3}\s(\w{3})\s(\d{2})\s(\d{2}):(\d{2}):(\d{2})\s(\w+)\s(\d{4})} );

my $dt = DateTime->new( year => $year, month => $month, day => $day, 
                        hour => $hour, minute => $min, second => $sec, 
                        time_zone => $tz );

次に、DateTime :: Format :: MySQLを使用して、日付をMySQL互換の日時に変換できます。

于 2010-02-12T15:56:54.887 に答える
1

3文字と4文字のコードは一意ではなく、標準化されていないため、処理しているタイムゾーンをDateTimeコンストラクターに明示的に指示する必要があります。

DateTime :: TimeZoneから始めて、リストで探しているものが見つからない場合は、タイムゾーンの新しいタイプを作成することをお勧めします。構文に準拠したDateTimeフォーマッターを見つけることもできますが(多数あります)、それ以外の場合は、正規表現を使用して日付と時刻のフィールドを抽出し、それをDateTimeコンストラクターに渡すことは難しくありません。

文字列を適切に設定された時刻でDateTimeオブジェクトに解析したら、それらをMySQLタイムスタンプに変換し直すことはまったく問題ありません。DateTime:: Format::MySQLを使用するだけです。

my $string = DateTime::Format::MySQL->format_datetime($dt);
于 2010-02-12T16:29:37.063 に答える
0

DateTimeモジュールを使用してみてください。

于 2010-02-12T15:55:43.873 に答える