2012-03-15 61 views
0

我想要做的是转换一些存档的CSV数据。它在几千个文件上运行得很好。我解析出日期并将其转换为时间戳。然而,在一个文件中,它不能工作。我使用(int) $string将解析的字符串转换为int值 - >它返回int(0)。我也用intval() - >相同的结果。当我使用var_dump($string)时,我得到了一些奇怪的输出,例如string(9) "2008",实际上应该是string(4) "2008"。我试图在字符串上使用preg_match,但没有成功。这是一个编码问题?PHP解析/类型转换问题

下面是一些代码,它只是非常标准的东西:

date_default_timezone_set('UTC'); 
$ms = 0; 
function convert_csv($filename) 
{ 
$target = "tmp.csv"; 
$fp = fopen("$filename","r") or die("Can't read the file!"); 
$fpo = fopen("$target","w") or die("Can't read the file!"); 
while($line = fgets($fp,1024)) 
{ 
    $linearr = explode(",","$line"); 

    $time = $linearr[2]; 
    $bid = $linearr[3]; 
    $ask = $linearr[4]; 
    $time = explode(" ",$time); 
    $date = explode("-",$time[0]); 
    $year = (int) $date[0]); 
    $month = (int)$date[1]; 
    $day = (int)$date[2]; 
    $time = explode(":",$time[1]); 

    $hour = (int)$time[0]; 
    $minute = (int)$time[1]; 
    $second = (int)$time[2]; 
    $time = mktime($hour,$minute,$second,$month,$day,$year); 

    if($ms >= 9) 
    { 
     $ms = 0; 
    }else 
    { 
     $ms ++; 
    } 
    $time = $time.'00'.$ms; 
    $newline = "$time,$ask,$bid,0,0\n"; 
    fwrite($fpo,$newline); 

} 
fclose($fp); 
fclose($fpo); 
unlink($filename); 
rename($target,$filename); 

}

下面是对文件的链接,我们正在谈论:

+1

请给我们看一些代码。你也得到了'string(9)“2008”'? – Dogbert 2012-03-15 12:13:11

+0

字符串的十六进制转储肯定是一个好主意,因为看起来太高的字符串长度表示存在输出查看器不能或不会显示的字节。 – 2012-03-15 12:16:51

+0

感谢您的意见,我只是添加了代码! – user871784 2012-03-15 12:19:29

回答

2

该文件似乎被编码在UTF-16,所以确实是一个编码问题。如果UTF-16被解释为单字节编码,则string(9)是由您获得的空字节引起的。

由于它们是二进制安全的,因此无法识别编码,因此这使得文件很难用fgets等函数进行读取。您可以读取内存中的整个文件并执行编码转换,但这非常低效。

我不确定是否可以使用原生PHP函数以UTF-16正确读取文件。您可能需要编写或使用外部库。

+0

哈哈谢谢,我明白了这一秒!:) – user871784 2012-03-15 12:31:21

0

您可以尝试使用iconv转换文件以规划ascii。

如果您是有iconv命令在Linux或类似的系统:

$的iconv -f -t UTF-16 ASCII EUR_USD_Week1.csv> clean.csv

否则,你可能会发现PHP的iconv功能有用:

http://php.net/manual/en/function.iconv.php