문제

우리는 현재 다음 형식으로 DateTime을 제공하는 타사 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

그러나 이러한 DateTime 객체를 MySQL에 다음 형식을 필요로하는 표준 DateTime 필드에 저장하려고합니다.

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"); };

MySQL DateTime 필드에 삽입 할 서버의 적절한 형식과 시간으로 DateTime 객체를 API에서 DateTime 객체를 변환하기 위해 위의 Perl 코드를 더 잘 구현할 수 있습니까?

도움과 조언에 미리 감사드립니다!

도움이 되었습니까?

해결책

내부적으로 시간을 GMT에 보관하십시오. GMT에서 모든 조작을 수행하십시오. 그런 다음 마지막 순간에 사용자에게 결과를 표시하려고하는 것처럼 그 다음에 사용자의 현지 시간으로 변환합니다.

사용하는 것이 좋습니다 날짜 :: 구문 분석, 그러나 예를 들어 현재 Indochina 여름 시간과 일본 일광 시간이 없기 때문에 시간대 오프셋을 보강해야합니다.

#! /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

산출:

Sat Mar 06 09:00:00 ICST 2010 => 2010-03-06 02:00:00
Fri Feb 19 19:30:00 JDT 2010 => 2010-02-19 10:30:00
Fri Feb 19 19:30:00 PST 2010 => 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

다른 팁

날짜를 저장할 때는 항상 UTC에 저장해야합니다. 이렇게하면 데이터베이스에서 가져 와서 사용자에게 표시하는 데 필요한 경우 적절한 시간대로 변환 할 수 있습니다.

Perl에서 DateTimes를 올바르게 처리하려면 진심으로 권장합니다. 날짜 시간 모든 종류의 다양한 입력 및 출력 형식에 대한 파서와 포트 패터가있는 Suite.

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 :: 형식 :: mysql 날짜를 MySQL 호환 DateTeM으로 변환합니다.

3 글자 및 4 자 코드가 고유하지 않고 표준화되지 않았기 때문에 DateTime 생성자에게 어떤 시간대를 다루고 있는지 명시 적으로 알려야 할 것입니다.

나는 시작하는 것이 좋습니다 DateTime :: TimeZone, 목록에서 찾고있는 것을 찾을 수 없다면 타임 존을위한 새로운 유형을 구성 할 수 있습니다. 또한 구문을 준수하는 DateTime Formatter를 찾을 수 있지만 (많은 수의 수가 있음), 그렇지 않으면 날짜와 시간 필드를 추출하여 DateTime 생성자에게 전달하기 위해 단순히 정규식을 사용하는 것은 어렵지 않습니다.

시간이 올바르게 설정된 상태에서 문자열을 DateTime 객체에 구문 분석 한 후에는 MySQL 타임 스탬프로 다시 변환하는 것은 전혀 문제가되지 않습니다. dateTime :: 형식 :: mysql:

my $string = DateTime::Format::MySQL->format_datetime($dt);

사용해보십시오 날짜 시간 기준 치수.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top