【问题标题】:Importing date to mySql from CSV file从 CSV 文件导入日期到 mySql
【发布时间】:2013-03-13 08:23:24
【问题描述】:

我儿子在他的托管网站上为家人建立了一个设施,以将旅行数据记录在 MySql 文件中。然后将它们显示在地图上的网页上(使用谷歌地图,但由私人托管。)

不幸的是,我儿子几周前被送进了医院,现在还在那里,所以他建议如果我把它贴在这里可能会得到一个问题的答案。

mysql 数据是通过使用 php 脚本从记录器生成的 csv 文件中导入来创建的。不幸的是,我的儿子不记得他是从哪里得到剧本的。

此脚本的工作原理是日期字段除外(这是至关重要的)。

脚本如下:

$tot = 0;
$handle = fopen($_FILES["uploaded"]["tmp_name"], "r");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
    for ($c=0; $c < 1; $c++) {

if($data[0] !='Latitude'){ 
                mysql_query("INSERT INTO positions(
                Latitude,
                Longitude,
                DateOccurred,
                Altitude,
                Speed,
                Angle
                )VALUES(
                    '".mysql_real_escape_string($data[0])."',
                    '".mysql_real_escape_string($data[1])."',
                    '".mysql_real_escape_string($data[2])."',
                    '".mysql_real_escape_string($data[16])."',
                    '".mysql_real_escape_string($data[15])."',
                    '".mysql_real_escape_string($data[8])."'

                )")or die(mysql_error());
}
    $tot++;}
}
fclose($handle);    

这会将所有内容导入 mysql,除了第三项 ($data[2]),它是日期并导入为零(即 00:00:00 00:00)。

这里有没有好心的编码人员可以告诉我如何纠正这个问题,或者向我指出可以提供帮助的其他地方。

如果需要更多信息,请告诉我。

谢谢

编辑: 这是sql表结构

|//**ID**//|int(11)|No|
|FK_Users_ID|int(11)|No|
|FK_Trips_ID|int(11)|Yes|NULL
|FK_Icons_ID|int(11)|Yes|NULL
|Latitude|double|No|
|Longitude|double|No|
|Altitude|double|Yes|0
|Speed|double|Yes|0
|Angle|double|Yes|NULL
|DateAdded|timestamp|No|CURRENT_TIMESTAMP
|DateOccurred|timestamp|Yes|0000-00-00 00:00:00
|Comments|varchar(255)|Yes|NULL
|ImageURL|varchar(255)|Yes|NULL
|SignalStrength|int(11)|Yes|NULL
|SignalStrengthMax|int(11)|Yes|NULL
|SignalStrengthMin|int(11)|Yes|NULL
|BatteryStatus|tinyint(4)|Yes|NULL

这是 CSV 文件内容的示例:

Latitude,Longitude,DateOccurred,ID,IconName,Comments,TripName,ImageURL,Angle,CellID,SignalStrength,SignalStrengthMin,SignalStrengthMax,BatteryStatus,Source,Speed,Altitude
51.1923274,-3.102753383,20/03/2013 14:17,2352,,,dentist,,287.2,,,,,,0,7.71666666,13
51.19254205,-3.103862483,20/03/2013 14:17,2353,,,dentist,,285.4,,,,,,0,7.665222216,14
51.19268602,-3.105032683,20/03/2013 14:17,2354,,,dentist,,272.1,,,,,,0,9.054222214,11.1

如果还需要什么,请告诉我。

谢谢

编辑 2

我尝试了 Havelock 的解决方案 - 选项 3。

由于 DateOccurred 字段中仍然返回零,我添加了另一条指令,将 csv 中的日期插入 mysql 数据库中的“cmets”文本字段中。

代码如下

if($data[0] !='Latitude'){ 
           $timestamp = strtotime($data[2]);
           mysql_query("INSERT INTO positions(
           Latitude,
           Longitude,
           DateOccurred,
           Comments,
           Altitude,
           Speed,
           Angle
           )VALUES(
               '".mysql_real_escape_string($data[0])."',
               '".mysql_real_escape_string($data[1])."',
               '".mysql_real_escape_string($data[2])."',
               '".mysql_real_escape_string(date('Y-m-d H:i:s', $timestamp))."',
               '".mysql_real_escape_string($data[16])."',
               '".mysql_real_escape_string($data[15])."',
               '".mysql_real_escape_string($data[8])."'

                )")or die(mysql_error());

结果是插入到'Comments'字段中的所有记录中的数据都被读取了

1969-12-31 18:00:00

而csv中的信息是

20/03/2013 14:17

如果我省略这些行

$timestamp = strtotime($data[2]);
and 
'".mysql_real_escape_string(date('Y-m-d H:i:s', $timestamp))."',

cmets 字段包含来自 csv 文件的正确数据(作为文本)。

我不确定这个信息有多重要 - 但我认为这可能意味着什么。

编辑 3

由于 'DateTime::createFromFormat()' 应该适用于 PHP 5.3.22,我重新访问了脚本并输入了一些代码来测试它。 我添加了这个

$date = DateTime::createFromFormat('d/m/Y H:i', $data[2]);
           echo $date->format('Y-m-d H:i:s');

回显是打印结果以查看它们是什么。 脚本现在看起来像这样

if($data[0] !='Latitude'){ 
           $date = DateTime::createFromFormat('d/m/Y H:i', $data[2]);
           echo $date->format('Y-m-d H:i:s');
           mysql_query("INSERT INTO positions(
           Latitude,
           Longitude,
           DateOccurred,
           Altitude,
           Speed,
           Angle
           )VALUES(
               '".mysql_real_escape_string($data[0])."',
               '".mysql_real_escape_string($data[1])."',
               '".mysql_real_escape_string(date('Y-m-d H:i:s'))."',
               '".mysql_real_escape_string($data[16])."',
               '".mysql_real_escape_string($data[15])."',
               '".mysql_real_escape_string($data[8])."'


                )")or die(mysql_error());
}

这导致脚本打印日期并在 mysql 字段中以正确的格式输入日期。

但是 - 正在打印和存储的日期是 当前日期和时间,而不是存储在 csv 文件中的日期,因此该语句似乎忽略了 $数据[2}

【问题讨论】:

  • 你能否从 MySQL 添加详细信息,例如运行:描述位置;这可能会提供一些关于表模式的有用信息。除此之外,该表单数据的来源可能没有得到正确处理,并导致使用“默认”值而不是上传的内容。您可以尝试显示一些 CSV 数据吗?
  • CSV 文件中的日期格式是什么?
  • $data[2] 是日期,是什么格式?
  • 发布几行 CSV 文件的示例,这将有助于解决如何处理它
  • 只需将'".mysql_real_escape_string(date('Y-m-d H:i:s'))."', 行替换为'".mysql_real_escape_string($date-&gt;format('Y-m-d H:i:s'))."',。就像现在一样,您正在从输入中正确创建日期,但您正在插入其他内容 - 这是一个新创建的日期,带有 date('Y-m-d H:i:s')

标签: php mysql


【解决方案1】:

检查一下:

// ...

$formatFromFile = 'Y-m-d'; // your format of date in csv file
$date = DateTime::createFromFormat($formatFromFile, $data[2]);

mysql_query("INSERT INTO positions(
            Latitude,
            Longitude,
            DateOccurred,
            Altitude,
            Speed,
            Angle
            )VALUES(
                '".mysql_real_escape_string($data[0])."',
                '".mysql_real_escape_string($data[1])."',
                '".mysql_real_escape_string($date->format('Y-m-d H:i:s'))."',
                '".mysql_real_escape_string($data[16])."',
                '".mysql_real_escape_string($data[15])."',
                '".mysql_real_escape_string($data[8])."'

            )")or die(mysql_error());
// ...

【讨论】:

    【解决方案2】:

    您可以使用DateTime::createFromFormat() 创建一个 DateTime 对象,然后以 MySQL 可读的方式输出它。例如,假设您的日期以“dmY”格式写入,例如'10012010' 表示 2010 年 1 月 10 日。要了解有关格式规范的更多信息,请阅读上面链接的 PHP 规范页面。

    您可以使用以下函数将“dmY”格式转换为 mysql-format

    function convert($date) {
      $d = DateTime::createFromFormat('dmY', $date);
      return $d->format('Y-m-d H:i:s');
    }
    

    附带说明一下,我建议您查看 MySQL 的 LOAD DATA INFILE,这是一个更快的选项,可以将 cvs 文件导入到表中。

    【讨论】:

    • 感谢您提供“加载数据文件”的信息和链接。当/如果他出院时,我会和我儿子一起看看这个。与此同时,我将在这里尝试一些答案。
    【解决方案3】:

    这取决于 CSV 文件上的日期格式。 阅读有关 strtotime 函数的信息,也许是解决方法

    【讨论】:

      【解决方案4】:

      在我看来,问题是由于 CSV 文件中的日期/时间格式不同。根据有关插入表中的错误数据的信息,我假设该列的类型是DATETIME。此类型具有以下格式YYYY-MM-DD HH:MM:SS,因此,如果CSV 文件中的日期格式类似于05/23/2012 5:35 p.m. 或其他格式,这不是预期的格式,则出现问题是可以理解的。在我看来,你有两个选择:

      选项 1:
      将日期保存在 CSV 文件中,以便符合 MySQL 的DATETIME。这有点像

      2013-03-23 15:45:25
      

      那么插入应该可以正常工作了。

      选项 2:
      这个选项可能比前一个更“复杂”,特别是如果你不那么倾向于(通过阅读问题的全文)。您需要在 PHP 脚本中创建一个新的 DateTime 对象,并在保存数据时使用其 format() 方法。
      不幸的是,我不知道 CSV 文件的格式,所以我只能做出一个疯狂的猜测。假设您文件中的日期格式如下03/24/2013 5:24 PM

      if($data[0] !='Latitude'){ 
                 $date = DateTime::createFromFormat('m/d/Y g:i a', $data[2]);
                 mysql_query("INSERT INTO positions(
                 Latitude,
                 Longitude,
                 DateOccurred,
                 Altitude,
                 Speed,
                 Angle
                 )VALUES(
                     '".mysql_real_escape_string($data[0])."',
                     '".mysql_real_escape_string($data[1])."',
                     '".mysql_real_escape_string($date->format('Y-m-d H:i:s'))."',
                     '".mysql_real_escape_string($data[16])."',
                     '".mysql_real_escape_string($data[15])."',
                     '".mysql_real_escape_string($data[8])."'
      
                 )")or die(mysql_error());
      }
      

      如果我对 CSV 文件中的格式(即 'm/d/Y g:i a' 部分)有误,您可以查看 DateTime documentation 以了解如何通过选择适当的格式来修复它,使其适合您的案子。

      选项 3:
      由于您的托管服务器上似乎安装了 PHP 版本

      if($data[0] !='Latitude'){ 
                 $timestamp = strtotime(str_replace('/', '-', $data[2]));
                 mysql_query("INSERT INTO positions(
                 Latitude,
                 Longitude,
                 DateOccurred,
                 Altitude,
                 Speed,
                 Angle
                 )VALUES(
                     '".mysql_real_escape_string($data[0])."',
                     '".mysql_real_escape_string($data[1])."',
                     '".mysql_real_escape_string(date('Y-m-d H:i:s', $timestamp))."',
                     '".mysql_real_escape_string($data[16])."',
                     '".mysql_real_escape_string($data[15])."',
                     '".mysql_real_escape_string($data[8])."'
      
                 )")or die(mysql_error());
      }
      

      更新
      我已编辑 $timestamp 相关行以匹配您的 CSV 文件提供的格式。

      【讨论】:

      • 谢谢。不幸的是,它破坏了脚本并出现错误 --- [23-Mar-2013 11:05:26 America/Chicago] PHP 致命错误:在 /domain.com/sql 中的非对象上调用成员函数 format() /uploadcsv3.php 在第 59 行 --- 这是替换为 $data2 的行
      • 我明白了。这表明您的托管服务器上安装了 PHP 版本 Option 3
      • 谢谢,你是对的,服务器安装了 PHP 5.3.22 版本,我可以看到。该脚本现在再次使用新的更改,但不幸的是仍然将零返回到 DateOccurred 字段;-(。我还尝试了其他方法来查看是否可以看到一个明显的问题 - 进一步编辑我的原始问题的详细信息。
      • 等等,如果你的 PHP 版本是 5.3.22,那么DateTime::createFromFormat()$date-&gt;format() 都应该没有问题。无论如何,Option 3 的问题在于字符串的格式。请参阅更新的行$timestamp = strtotime(strreplace('/', '-', $data[2]));,它应该已经解决了问题。如果您想了解更多原因 - 请参阅Documentation -> Notes -> 3rd Note
      • 对不起,我没有早点回复,但我不得不去医院看我的儿子。不幸的是使用 'strtotime(strreplace('/', '-', $data[2]));'又破了剧本。错误 - 'PHP 致命错误:在第 48 行调用 /domain.com/sql/uploadcsv7.php 中的未定义函数 strreplace()' 但是您的评论说 'DateTime::createFromFormat(),也不是 $date->format() ' 应该与 PHP V5.3.22 一起工作让我开始思考,在阅读了文档后我再次尝试。结果是对我原来的问题的进一步编辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-14
      • 1970-01-01
      • 2017-10-11
      • 2017-07-31
      • 1970-01-01
      • 2017-02-12
      相关资源
      最近更新 更多