2013-08-21 4 views
1

У меня есть файл XML. Я разбору синтаксического анализа, а затем вставляю его в свою базу данных, используя PHP. Однако узлы даты находятся в странном формате XML, который, как я полагал, составляет миллисекунду. Мои попытки преобразовать это пока не увенчались успехом, и я надеялся, что кто-то может указать на мою ошибку.php - convert xml (миллисекунды?) На читаемую дату

XML

<est__start>1335744000000</est__start> 
<est__end>1342742400000</est__end> 

Что было это намного более читаемым дата перед преобразованием

<est__start> 04-30-2012 </est__start> 
<est__end> 07-20-2012 </est__end> 

PHP

$start = $data->est__start; 
if (empty($start)) { 
    $start = ''; 
} else { 
    $start = intval($start);    
    $seconds = $start/1000; 
    $start = date("d-m-Y", $seconds); 
} 
$end = $data->est__start; 
if (empty($end)) { 
    $end = ''; 
} else { 
    $end = intval($end);    
    $seconds = $end/1000; 
    $end = date("d-m-Y", $end); 
} 

Конечный результат, однако, всегда что-то simil ar to this

25-01-1970 

и мне нужно, чтобы оно выглядело так, как перед конверсией. Как это

04-30-2012 

Поскольку я не обрабатываю исходное преобразование даты, когда он идет в файл XML, я не знаю, где я буду неправильно. Любая помощь приветствуется.

+0

Я * догадка * быстро, что 'intval' стоит на вашем пути. 'echo PHP_INT_MAX;' узнать, что система, которую вы используете, предлагает вам. Он будет закрывать секунды до 32 бит, подписанных макс. – hakre

+0

@hakre Хотя вопрос связан с преобразованием временных меток Unix, проблема OP связана с тем, как он написал код и конечный размер целых чисел. Это хороший вопрос. –

+0

Да, я быстро с обманом, вам нужно использовать поплавки, а не кастинг. Я также поместил это в свой ответ http://stackoverflow.com/a/18367563/367456, и это стандартный способ справиться с ним 32-битная система в PHP. Точность должна быть в порядке для этих случаев, иначе это потребует bcmath или gmp. – hakre

ответ

1

PHP использует значение строки SimpleXMLElement, если вы используете его в intval или же непосредственно в числовых расчетах (которые также отданных в целом).

Как я уже отмечал, мое первое быстрое предположение было правильным, оно обрезает число, а не максимальное целое число, доступное на 32-битной системе, подписанной (2 - 1) (я полагаю, вы используете один), который результаты:

2 147 483 647 
25-01-1970 

Это число кстати. является своего рода знаменитым и имеет свою страницу Википедии: 2147483647.

Вместо этого используйте функцию floatval, это дает вам то, что вы ищете:

$seconds = floatval($start)/1000; 
echo date("d-m-Y", $seconds); # prints "30-04-2012" 

Bonus: Вот некоторые код, который вы могли бы найти под рукой, чтобы иметь код преобразования в центральном месте и легко использовать:

/** 
* Class MySimpleXMLElement 
* 
* Extended SimpleXMLElement 
*/ 
class MySimpleXMLElement extends SimpleXMLElement 
{ 
    /** 
    * @param string $format 
    * 
    * @return bool|string 
    */ 
    public function getDateFromMilliseconds($format = "d-m-Y") { 
     return date("d-m-Y", floatval($this)/1000); 
    } 

    /** 
    * @param DateTimeZone $timezone 
    * 
    * @return DateTime 
    */ 
    public function createDateTimeFromMilliseconds(DateTimeZone $timezone = NULL) { 
     return new DateTime('@' . (floatval($this)/1000), $timezone); 
    } 
} 

$data = new MySimpleXMLElement('<r><est__start>1335744000000</est__start><est__end>1342742400000</est__end></r>'); 
/* @var $start MySimpleXMLElement */ 
$start = $data->est__start; 

echo $start->getDateFromMilliseconds(), "\n"; # prints "30-04-2012" 

echo $start->createDateTimeFromMilliseconds()->format('Y-m-d'); # prints "2012-04-30" 

Он работает, простирающейся от SimpleXMLElement и добавления функций даты и создания, здесь один за отформатированную строку и для более продвинутых DateTime операций, который дает обратно DateTime object.

В прошлый раз, когда я расширил SimpleXMLElement на Stackoverflow, был в answer to the "How to replace XML node with SimpleXMLElement PHP" question.

+0

это имеет большой смысл, но когда я запускаю код с 'floatval', а не' date', он выдает ошибку: 'floatval() ожидает ровно 1 параметр, 2 заданный' –

+0

ну не скорее, а дата, а не intval :) Посмотрите пример, я не заменил дату(). – hakre

+0

действительно сэр, однако проблема остается, я нахожу ее странной. Я прохожу только 1 парам. Почему он думает, что это два? –

0

Возможные UTC, и переключатель день и месяц:

echo gmdate('m-d-Y',1342742400000/1000); 

Результат:

07-20-2012 
+0

Спасибо, я проверил его сейчас, хотя это имеет смысл –

1

Вы используете intval но цифры слишком велики для int. Просто используйте:

date("m-d-Y", 1335744000000/1000); // 04-30-2012 
+0

спасибо, я проверил его сейчас, хотя это имеет смысл –

+0

Вы также можете проверить постоянную PHP 'PHP_INT_MAX'. Обратите внимание, что результаты будут различаться в зависимости от ОС сервера, на котором работает PHP (32 бит и 64 бит). –

+0

Зависит от вашего PHP_INT_SIZE ini. Попробуйте 'echo PHP_INT_SIZE;' Mine - 8, и эти числа обрабатываются просто отлично. – Geo

1

вы не проходя секунд во втором периоде:

enter image description here

+0

очень приятный улов, а не корень этой проблемы, но определенно был бы однажды, когда я понял это. Спасибо! –

Смежные вопросы