Perl을 사용하여 DateTime 형식간에 변환합니다
-
20-09-2019 - |
문제
우리는 현재 다음 형식으로 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);
사용해보십시오 날짜 시간 기준 치수.