Mysql 使用Perl在日期时间格式之间转换

Mysql 使用Perl在日期时间格式之间转换,mysql,perl,datetime,date-conversion,Mysql,Perl,Datetime,Date Conversion,我们目前使用的第三方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 YYYY-MM-DD HH:MM:SS 但是,我们希望将这些datetime对象存储在MySQL中的标准datetime字段中,该字段需要以下格式: Sat Mar 06 09:00:00 ICST 2010 Fri Feb 19 19:30:00 JDT 2010

我们目前使用的第三方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
YYYY-MM-DD HH:MM:SS
但是,我们希望将这些datetime对象存储在MySQL中的标准datetime字段中,该字段需要以下格式:

Sat Mar 06 09:00:00 ICST 2010
Fri Feb 19 19:30:00 JDT 2010
Fri Feb 19 19:30:00 PST 2010
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中的datetime对象转换为服务器上要插入MySQL datetime字段的正确格式和时间吗


提前感谢您的帮助和建议

尝试使用该模块。

存储日期时,应始终以UTC格式存储。这样,您就可以从数据库中获取它们,并根据需要将它们转换为适当的时区,以便显示给用户

为了在Perl中正确地处理日期时间,我衷心推荐该套件,它具有用于各种输入和输出格式的解析器和格式化程序

我不确定OP中列出的日期是否为标准格式,但如果不是,则很容易根据它们构建日期时间格式:

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

然后,您可以使用将日期转换为与MySQL兼容的datetime。

您可能需要明确地告诉datetime构造函数您正在处理的时区,因为三个字母和四个字母的代码不是唯一的,也不是标准化的

如果你在列表中找不到你想要的东西,我会建议你开始,并可能为你的时区构建新的类型。您还可以找到一个符合您的语法的日期时间格式化程序(有很多),但是,简单地使用正则表达式提取日期和时间字段并将其传递给日期时间构造函数并不困难

一旦您将字符串解析为DateTime对象并正确设置了时间,就可以将它们转换回MySQL时间戳:只需使用:


在GMT内部存储时间。在GMT中执行所有操作。然后在最后一刻,正如您将要向用户显示结果一样,转换为用户的本地时间

我建议使用,但你必须增加时区偏移量,因为它目前没有印度支那夏季时间和日本白天时间。
#! /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
收集时间后,将其呈现为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 $./prog.pl | mysql-u username-D dbname 转换(日期,+00:00',偏移量) 2010-03-06 09:00:00 2010-02-19 19:30:00
2010-02-19 19:30:00一个好的开始:我们目前正在使用DateTime,但出于某种原因,它似乎无法处理某些时区,并且正在报告KDT、JDT、ICST等的错误。我不知道是否有一个支持范围更广的模块?我只是添加了我们目前使用的原始问题的代码。你知道为什么DateTime似乎不能处理某些时区吗?不幸的是,我不知道如何让它支持这些时区;它们不会出现在DateTime::TimeZone模块()的列表中。您可能需要将它们转换为Olson样式的名称,如KDT=>Asia/Seoul。您可以提供示例Perl代码,将API返回的datetime对象转换为您建议的UTC格式吗?如果可能的话,我更喜欢使用Perl模块来解析datetime输入字符串,而不是regex,这样会更灵活一些。要添加对其他时区的支持,您可能需要修改
zoneinfo
文件来添加缺少的时区,并让datetime时区工具编译所需的模块,以创建自定义时区建造@维文-你能提供更多的细节吗。我刚刚在原始问题中添加了我们一直使用的代码。知道为什么DateTime不能转换某些时区吗?我会将数据存储在UTC时间。不过我不确定我是否理解你的问题-你想知道如何处理将日期插入MySQL数据库的问题吗?我只是更新了这个问题,让它更清楚。我的问题是,您能否提供更好的perl实现,将API提供的datetime转换为正确的datetime格式,插入MySQL datetime字段。我同意Friedo所说的,关于datetime::format::MySQL(以及时区)。@Ether-谢谢!既然大家一致认为我需要以UTC格式存储这些日期,那么您能否提供一些示例perl代码,说明一旦我有了合适的DateTime对象,我将如何进行存储?您不必将它们存储在UTC中,尽管如果您对DateTime进行一些计算,您会看到性能的提高。但是,您需要做的是将正确的时区字符串传递给DateTime构造函数,例如,
$my$dt=DateTime->new(…,timezone=>“America/Los_Angeles”)@gbacon-这正是我要找的。最后一个问题。然后,我必须在API最初给出的时区中显示项目的时间。您建议我将时区存储在MySQL表中的哪种格式以便于转换回来,以及我将使用哪种Perl代码将存储在GMT和timezone中的datetime转换为类似“2010年2月19日星期五-下午2:30 JDT”的格式?@gbacon-如果有一种方法可以将时区存储在MySQL中,使我能够通过一个SQL查询(无perl)返回本地datetime中存储的datetime(以GMT为单位),那可能是一个更好的解决方案。@Russell谁的本地datetime?与API或承载数据库的计算机给出的时间相同?@gbacon-与API给出的时间相同。@gbacon-感谢您的帮助!虽然我们使用的最终结果有点不同,但它基于您的建议,似乎适用于我们通过API获取的所有项目。
$ ./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