Hi,

The xml feed which i am trying to fetch contains date as shown below

I tried to map with the my cck date field (date or datetime tried both ), it gives me an error message :
warning: DateTime::__construct() [datetime.--construct]: Failed to parse time string (18/06/2010) at position 0 (1): Unexpected character in /../sites/all/modules/feeds/plugins/FeedsParser.inc on line 388.

In my cck date field i have set the custom input format to d/m/Y which should ideally match with the date format in the xml file, however it doesn't import anything stops with the error message mentioned above.
I am using extensible xml parser mentioned in http://drupal.org/node/631104

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alex_b’s picture

Can you post the feed you are parsing?

Sagar Ramgade’s picture

<XML>
−
<DAY DATE="18/06/2010" SPORT_ID="1">
−
<COMPETITION ID="1623" LIVE_TABLE="Y" ODDS="N" DETAILS="Y" PHOTOS="/football/editorial/gallery_story_6212992.xml" IMPORTANCE="1" TABLELASTUPDATED="1276877145">
<NAME>FIFA World Cup</NAME>
<SNAME>World Cup</SNAME>
<SROUND>Group C</SROUND>
<ROUND>Group C</ROUND>
−
<MATCHES>
−
<MATCHSUMMARY SPORTID="1" ID="301078" PAID="3222287" CPID="1623" SBID="12338705" TVCHANNEL="" FXDATE="18/06/2010" CURRENTDATE="" ENDDATE="" TIME="15:00" LONGCOMPETITIONNAME="FIFA World Cup" SHORTCOMPETITIONNAME="World Cup" LONGROUNDNAME="Group C" SHORTROUNDNAME="Group C" DETSLASTUPDATED="1276877144" COMMSLASTUPDATED="1276878060" STATSLASTUPDATED="1" TABLELASTUPDATED="1276877145" COMMENTARY="/football/commentary/301078_1276878060.xml" GALLERYLASTUPDATED="1276877820" GALLERY="/football/editorial/gallery_match_301078_1276877820.xml" PLAYERSTATS="Y">
<HOMETEAMNAME ID="1225" SNAME="Slovenia">Slovenia</HOMETEAMNAME>
−
<HOMETEAMSCORE>
<SCORE AGG="">2</SCORE>
</HOMETEAMSCORE>
<AWAYTEAMNAME ID="1202" SNAME="USA">United States of America</AWAYTEAMNAME>
−
<AWAYTEAMSCORE>
<SCORE AGG="">1</SCORE>
</AWAYTEAMSCORE>
<MATCHSTATUS STATUS="4"/>
</MATCHSUMMARY>
−
<MATCHSUMMARY SPORTID="1" ID="301080" PAID="3222289" CPID="1623" SBID="12071187" TVCHANNEL="" FXDATE="18/06/2010" CURRENTDATE="" ENDDATE="" TIME="19:30" LONGCOMPETITIONNAME="FIFA World Cup" SHORTCOMPETITIONNAME="World Cup" LONGROUNDNAME="Group C" SHORTROUNDNAME="Group C" DETSLASTUPDATED="1" COMMSLASTUPDATED="1276862160" STATSLASTUPDATED="1" TABLELASTUPDATED="1276515114" COMMENTARY="/football/commentary/301080_1276862160.xml" GALLERYLASTUPDATED="1" GALLERY="" PLAYERSTATS="N">
<HOMETEAMNAME ID="52" SNAME="England">England</HOMETEAMNAME>
−
<HOMETEAMSCORE>
<SCORE AGG=""/>
</HOMETEAMSCORE>
<AWAYTEAMNAME ID="2241" SNAME="Algeria">Algeria</AWAYTEAMNAME>
−
<AWAYTEAMSCORE>
<SCORE AGG=""/>
</AWAYTEAMSCORE>
<MATCHSTATUS STATUS="0"/>
</MATCHSUMMARY>
</MATCHES>
</COMPETITION>
−
<COMPETITION ID="1624" LIVE_TABLE="Y" ODDS="N" DETAILS="Y" PHOTOS="/football/editorial/gallery_story_6212992.xml" IMPORTANCE="1" TABLELASTUPDATED="1276871208">
<NAME>FIFA World Cup</NAME>
<SNAME>World Cup</SNAME>
<SROUND>Group D</SROUND>
<ROUND>Group D</ROUND>
−
<MATCHES>
−
<MATCHSUMMARY SPORTID="1" ID="301082" PAID="3222291" CPID="1624" SBID="12338363" TVCHANNEL="" FXDATE="18/06/2010" CURRENTDATE="" ENDDATE="" TIME="12:30" LONGCOMPETITIONNAME="FIFA World Cup" SHORTCOMPETITIONNAME="World Cup" LONGROUNDNAME="Group D" SHORTROUNDNAME="Group D" DETSLASTUPDATED="1276870928" COMMSLASTUPDATED="1276871700" STATSLASTUPDATED="1" TABLELASTUPDATED="1276871208" COMMENTARY="/football/commentary/301082_1276871700.xml" GALLERYLASTUPDATED="1276871040" GALLERY="/football/editorial/gallery_match_301082_1276871040.xml" PLAYERSTATS="Y">
<HOMETEAMNAME ID="221" SNAME="Germany">Germany</HOMETEAMNAME>
−
<HOMETEAMSCORE>
<SCORE AGG="">0</SCORE>
</HOMETEAMSCORE>
<AWAYTEAMNAME ID="1227" SNAME="Serbia">Serbia</AWAYTEAMNAME>
−
<AWAYTEAMSCORE>
<SCORE AGG="">1</SCORE>
</AWAYTEAMSCORE>
<MATCHSTATUS STATUS="5"/>
</MATCHSUMMARY>
</MATCHES>
</COMPETITION>
</DAY>
</XML>

Here's the xml file which i am trying to map.
I have set the x-path as //XML//DAY//COMPETITION//MATCHES//MATCHSUMMARY
so i have the mapped like this :
@id GUID

//HOMETEAMNAME[@SNAME] Title

@LONGROUNDNAME Taxonomy: WorldCup Group

//HOMETEAMNAME[@SNAME] Home team term

@id matchID

Remove
//AWAYTEAMNAME[@SNAME] Away team term

@LONGCOMPETITIONNAME competition

//MATCHSTATUS[@STATUS] match status

//HOMETEAMSCORE//SCORE[@AGG] home team score

//AWAYTEAMSCORE//SCORE[@AGG] away team score

@FXDATE Match Time: Start

alex_b’s picture

Category: support » bug
Status: Active » Needs work
FileSize
1.1 KB

I can confirm that error now:

Breaks:

$date = new DateTime('18/06/2010');
print $date->format('r');

Works:

$date = strtotime('18/06/2010');
$date = new DateTime($date);
print $date->format('r');

The attached patch applies the above fix. Needs more research whether this is actually a viable solution. Also: all manual cleanup in __construct() could be eliminated by using strtotime().

oseldman’s picture

I am experiencing a similar problem. I've created a custom xml parser and am receiving the date as 24/06/2010. Importing fails if I attempt to map this to a CCK Date field.

I applied the patch above and it allows the import to go through successfully, however the Date field on the node is always set to the current date / time when the import occurs, not the date being passed in the xml.

As a side note, if the Date field does not have a timezone set it saves the date as whatever the current time is in GMT. This may be intentional, but it confused me because I'd initially turned off timezone and removed the hour/minute granularity on the field.

infojunkie’s picture

FileSize
708 bytes

The patch is #3 is not correct because strtotime uses the same formats as the DateTime constructor. Failing to convert the European date, this function returns FALSE which leads the constructor to use the current time.

Attached is a patch that uses Date API to convert the date to a format that's recognized by the DateTime object.

infojunkie’s picture

Status: Needs work » Needs review
alex_b’s picture

Version: 6.x-1.0-alpha15 » 6.x-1.x-dev
Status: Needs review » Needs work

#5 Looks like a good approach, breaks existing tests though. I like how the patch avoids a dependency of Feeds on Date by adding the conversion into the mapper.

infojunkie’s picture

I'm working on understanding why the import fails in the tests. Do you have any hints on debugging import failures in SimpleTest?

alex_b’s picture

What I use a lot for debugging is $this->show(); - a Feeds debug helper - for printing the current screen to the test report page. Further, I write debug information to a file with fopen/fwrite. error_log() won't go to the usual log as SimpleTest somehow alters the logging behavior.

I recently switched to using Feeds Test Site for all tests. I recommend it.

I'm on IRC today. Poke me if you have more questions.

jim005’s picture

#4 : Did you manage to solve this isssue ? I'got same problem with Feed xPath Parser... dates don't pass. looking for a solution...

for me (without patch) dates are :
XML sources : 2010-02-06T00:00:00+01:00
node date CCK : 2010-01-30 (yyyy-mm-dd) !!

and error during the batch insert
DateTime::setTimezone() expects parameter 1 to be DateTimeZone, null given in /home/ez-vacances/public_html/sites/all/modules/feeds/plugins/FeedsParser.inc on line 443.

#3, the first patch give me error :
warning: DateTime::__construct() [datetime.--construct]: Failed to parse time string (1280613600) at position 8 (0): Unexpected character in .../sites/all/modules/feeds/plugins/FeedsParser.inc on line 388.

#5, this first patch doesn't work neither for me... the date from my XML appears :
case 1 :
XML : 2010-05-29T00:00:00+02:00
In my cck Date field : empty
In my cck text field : 2010-07-19T00:00:00+02:00 (that field is debug only)

case 2 :
XML : 2010-08-28T00:00:00+02:00
In my cck Date field : empty
In my cck text field : 2010-07-19T00:00:00+02:00 (that field is debug only

I don't know where to go with that... please help.

gaele’s picture

The patch from #5 works for me. Using Feeds XML Parser, a custom date format 'j F Y', and month names in Dutch.

alex_b’s picture

Title: Import fails due to cck date field mapping » Import fails due to dates not converted correctly
alex_b’s picture

#860942-3: Convert dates mapped to node created or updated. Made me realize that we will need full conversion functionality not only for CCK Date fields, but also for e. g. node created or updated properties.

Hence, I am changing my opinion on the location of the fix (see #7): I think the fix to the conversion should ideally go into FeedsDateTime class wrapped in a if (module_exists('date')) class.

infojunkie’s picture

You're right. I will change the location of the fix and guard it as suggested. I haven't had time to figure out the test failures yet.

rbrownell’s picture

+1 subscribe

alex_b’s picture

Priority: Normal » Critical

I am setting this to critical, we must address this issue before we roll out stable.

Junro’s picture

Hello, just installed the Feed module in order to replace node import module.

I can import nodes (including with nodereference mapping) but Date cck field cause some problems.

I only import Date fiels with Year only. And I've got always 1970 imported. I remmeber having the same issue with my first configuration of node import module.
(See #374346: Can't import date values into Date module fields)

The solution was to set the Date timezone to Y only but is the Date mapping, we have no configuration choices.

For all my cck date fields, I've got a Start date and End date, why?

Feed module looks much more powerful that node import module, and sure much more stable with a good maintainer who likes drupal.

Is there some progress on Date mapping?

Thanks :)

rbayliss’s picture

#13 - I like the idea of using strtotime in FeedsDateTime, as it seems to work for most cases and avoids segfaults and PHP warnings, both of which are showstoppers. What about a combination of the two approaches?

if (is_string($time)) {
      $time = "@" . strtotime($time);
}

This way you can still use the Date mapper to produce a DateTime or timestamp, but if a strange date slips by, it doesn't bring everything to a grinding halt.

stella’s picture

subscribe. I can confirm the patch in #5 works.

Edit: having some problems with a year field in which the year is always the entered year minus 1, i.e. I upload 2010 in the file, and 2009 is saved to the node. :(

As best as I can figure out, the date changes from 2010-00-00 to 2009-11-30 on the $feed_element = new FeedsDateTimeElement($feed_element, NULL); line in date_feeds_set_target()

stella’s picture

It appears to be something in DateTime itself that can't handle 00 as the month and days fields. If I set my input field to be 2010-01-01 then everything works as intended.

I added the following line to the code. It's kinda hackish, but I couldn't think of anything else without delving into the depths of the date_api module, which having spent a couple of hours I this, I don't really have the energy for right now. In any case, I imagine it's by design for the date module to return 00 for unset elements.

$feed_element = str_replace('-00', '-01', $feed_element);
alex_b’s picture

Status: Needs work » Needs review
Issue tags: -xml, -Feeds
FileSize
985 bytes

This is a date module independent approach that I've just committed to the D7 branch of Feeds.

http://github.com/lxbarth/feeds

alex_b’s picture

Backport of #21 to 6.x.

This patch fixes a two quirks of PHP's DateTime under PHP 5.2.6 (likely other point releases of PHP 5.2 affected too).

- DateTime::__construct() does not respect timezone parameter
- DateTime::__construct() fails fatally if it can't parse the passed in date

alex_b’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
3.35 KB

This adds a short test.

alex_b’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

This is committed now, thank you.

http://drupal.org/cvs?commit=427350

Tests need a port to Drupal 7.

alex_b’s picture

Status: Patch (to be ported) » Fixed

Tests added to D7 branch.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

marcvangend’s picture

pachyderm’s picture

Version: 7.x-1.x-dev » 6.x-1.0-beta9
Priority: Critical » Normal
Status: Closed (fixed) » Needs review

I just wanted to check in a comment,
I've got a feed with dates in the YYYYMMDD format:
<date>20090106</date>

And it was failing to import because of this check
(~line 491 in FeedsParser.inc)
==================
/**
* Overridden constructor.
*
* @param $time
* time string, flexible format including timestamp.
* @param $tz
* PHP DateTimeZone object, NULL allowed
*/
public function __construct($time = '', $tz = NULL) {
// Assume UNIX timestamp if numeric.
if (is_numeric($time)) {
$time = "@". $time;
}
==================
That check would erroneously classify my YYYYMMDD string as a UNIX timestamp.
I propose you update it to check for 10 numeric digits:

if (is_numeric($time) && (strlen($time) == 10) ) {

That worked for me.

marcvangend’s picture

Elephant_drupal, that is not going to work. Today's date in your format (20101222) is a perfectly valid timestamp as well (somewhere in August 1970). Unix timestamps are not necessarily 10 digits long. When automatically translating human language to computer language, there is a limit to what a computer can accept as input. I'm afraid you just reached that limit.

marcvangend’s picture

Bartezz’s picture

twistor’s picture

Status: Needs review » Closed (fixed)

There's a followup issue. This should not have been re-opened.