profile date fields not importing correctly

Andro01 - September 9, 2007 - 12:18
Project:User Import
Version:6.x-1.2
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:patch (to be ported)
Description

Great module, like the way it works. Only thing I can't figure out is the format for uploading date fields in the profiles. What is the format I am supposed to use?

#1

mshaver - October 4, 2007 - 20:54

I have a date cell formated as "d-mmm-yy" and it seems to come through just fine.

#2

BarryHoggard - January 18, 2008 - 06:53

I am unable to get a profile field that is a date to work. I have an expiration date in the old system I'm importing. I've tried these formats:

31-12-2010
01-September-2008
"Mon, 01 Sep 2008 00:00:00 UTC"

The imports run without any warnings, but the profile_expire_date is still empty so that when I try to view the data it defaults to today's date.

What is the proper date format? Here a typical line of my file:

First,Last,password,31-12-2010

#3

ferrangil - February 21, 2008 - 16:04

I never tried but I think the default date in Drupal looks like
2004-02-12T15:19:21+00:00

but I'm not sure...
just try to put some dates from one of the rows in the .csv and see if the date keeps on the system.

#4

pivica - June 2, 2008 - 14:29
Component:Documentation» Code
Category:support request» bug report
Priority:minor» normal

I think i found a bug in _user_import_save_profile function. Problem is that profile module save date fields in serialized format so its not possible to just save dates like plain texts. I have modified _user_import_save_profile function to work correctly with date fields (although not sure is this the best way):

function _user_import_save_profile($field, $uid, $value) {
    // BEGIN CHANGE
    // It seems that drupal saves date profile fields in serialized format.
    $type = db_result(db_query("SELECT type FROM {profile_fields} WHERE fid = %d", $field));
    if ($type == 'date' && $value != '') {
      // Assuming MM/DD/YYYY format.
      list($month, $day, $year) = split('/', $value);
      $value = serialize( array('month' => $month, 'day' => $day, 'year' => $year) );
    }
    // END CHANGE

    $profile = db_query("INSERT INTO {profile_values} (fid,uid,value) VALUES(%d,%d,'%s')", $field, $uid, $value);
    return;
}

For more info take a look to http://api.drupal.org/api/function/profile_save_profile/5 and http://api.drupal.org/api/function/_profile_field_serialize/5

#5

hoggo - June 19, 2008 - 23:03

I have experienced the smae problems trying to import a date field and believe you have hit the nail right on the head with your code change.

For anyone (like me) preparing their data for import using Excel, remember to format the date fields as 'm/d/yyyy' before saving as CSV and importing. If you leave the formatting at the default 'mm/d/yyyy' or 'mm/dd/yyyy' you will end up with leading zeroes on at least the month field for months up to September and they will not import properly (defaulting instead to January).

#6

mizengineer - August 1, 2008 - 15:26

Have applied the modifications in #4 to the user_import.module and formatted as m/d/yyyy as suggested in #5 and this works! Thanks very much, I've spent way to long trying to solve this problem and the suggestions in #1 to format the date as d-mmm-yy does NOT work. Wonder if this should be a formal patch?

#7

jrborba - October 7, 2008 - 23:29

Good "patch" in #4 for this wonder module.
For other date formats, like dd/M/yyyy (in my case), simply change the order of list and serialized array.
Dont forget the "M". "MM" doesnt works.

*********ADDED LATER***********

My imported fields are repeated. Even if I import in M/dd/yyyy format (not a date problem). I identify this problem in view module, in a list of users, and check in the database table. In every user imported, only in 3 fields of profile (of 10) information are included, but the same fields are included with empty values (repeated). The other fields are empty, and are OK. After a look in the profile over an administration interface and SAVING, the problem are solved, with the empty duplicated fields deleted by drupal. I will dont do this with 1200 included users........................

Any suggestion?

Regards,

#8

ferrangil - October 8, 2008 - 14:06

Solved in here:

http://drupal.org/node/174322

There's one comment at the end that suggests to comment one line, and you will not have any duplicate field.

Cheers

#9

jrborba - October 8, 2008 - 18:53

Man,

You are the best. Kill my headache!!!

Thanks a lot.

regards,

#10

ferrangil - October 14, 2008 - 16:11
Status:active» fixed

You're welcome :)

#11

Anonymous (not verified) - October 28, 2008 - 16:11
Status:fixed» closed

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

#12

ardnet - April 22, 2009 - 04:08
Version:5.x-1.3» 5.x-2.8
Status:closed» needs review

Hi all,
First of all, the version of user_import module that i use is: user_import-5.x-2.8.tar.gz
For the date format, I have tried suggestion in #4, but i think this code need to implement more in the profile_user_import_save_profile function, which is in profile.inc

I implement like the one below:

function profile_user_import_save_profile($field, $uid, $value, $updated, $update_setting, &$data) {  

// when the profile field is displayed on the registration form an empty value is automatically saved by the Profile module
$exists = db_result(db_query("SELECT value FROM {profile_values} WHERE fid = %d AND uid = %d LIMIT 1", $field->fid, $uid));

if($field->type == "date"){
  // Assuming MM/DD/YYYY format.
      list($month, $day, $year) = split('/', $value);
      $value = serialize( array('month' => $month, 'day' => $day, 'year' => $year) );
}

if ($updated) {
switch ($update_setting) {
case UPDATE_NONE:
return;

case UPDATE_ADD:
        if (empty($value) || (!empty($exists) && $exists != '')) return;

case UPDATE_REPLACE:

if (empty($value) && $update_setting == UPDATE_REPLACE) {

db_query("DELETE FROM {profile_values} WHERE fid = %d AND uid = %d", $field->fid, $uid);
unset($data[$field->name]);
return;
}

if ((empty($exists) && $exists != '') || $exists === FALSE) {
db_query("INSERT INTO {profile_values} (fid,uid,value) VALUES(%d,%d,'%s')", $field->fid, $uid, $value);
}
else {
db_query("UPDATE {profile_values} SET value = '%s' WHERE fid = %d AND uid = %d LIMIT 1", $value, $field->fid, $uid);
}

$data[$field->name] = $value;
return;
}

}
else {

if (empty($value)) return;

if ((empty($exists) && $exists != '') || $exists === FALSE) { 
db_query("INSERT INTO {profile_values} (fid,uid,value) VALUES(%d,%d,'%s')", $field->fid, $uid, $value);
}
else { 
db_query("UPDATE {profile_values} SET value = '%s' WHERE fid = %d AND uid = %d LIMIT 1", $value, $field->fid, $uid);
$data[$field->name] = $value;
}
}

return;  
}

And also need some little changes in function profile_user_import_after_save, which is like the one below:

function profile_user_import_after_save($settings, $account, $password, $fields, $updated, $update_setting_per_module) {

// get all fields
  $profile_fields = profile_get_fields();
$data = $old_data = unserialize($account->data);

  foreach ($profile_fields as $field) {
profile_user_import_save_profile($field, $account->uid, $fields['profile'][$field->fid][0], $updated, $update_setting_per_module['profile'], $data);
}

// data column in the user table needs to be updated
if ($data != $old_data) {  
//db_query("UPDATE {users} SET data = '%s' WHERE uid = %d LIMIT 1", serialize($data), $account->uid);
db_query("UPDATE {users} SET data = '%s' WHERE uid = %d LIMIT 1", 'a:0:{}', $account->uid);
}

  return;
}

Note that, without changes in function profile_user_import_after_save, your date will still not display properly, even though the value in table profile_values already in a form of serialized array.

So the correct date format should be: MM/DD/YYYY

Thanks.

#13

Justin W Freeman - May 20, 2009 - 23:52

I have created a patch with the code in #12.

It also adds a select option on the configure page (admin/user/user_import/configure) that allows you to select a date format to use (more date format options can be added if required).
The option only appears if the profile module is enabled.

The patch is against 5.x-2.8 and seems to work correctly in my testing.

AttachmentSize
user_import_profile_date_field.patch 17.03 KB

#14

Justin W Freeman - May 20, 2009 - 23:55
Title:date format» profile date fields not importing correctly

Renaming to properly describe the issue

#15

Justin W Freeman - May 21, 2009 - 00:28

Here is a 6 version of this patch.

I have not been able to test it yet, I just did a quick port of the 5 patch as all the changed code seems to be the same across both versions.

AttachmentSize
user_import_profile_date_field_D6.patch 12.62 KB

#16

Justin W Freeman - May 21, 2009 - 00:32

I have marked #449466: date field does not seem to work as a duplicate of this issue.

#17

Justin W Freeman - May 21, 2009 - 00:34
Category:bug report» feature request

#18

Justin W Freeman - May 21, 2009 - 01:48

I have made a little change to these patches as I was having problems with days and months with a leading zero.

The patch now strips leading zeros from the day and month parts and that problem is fixed.

AttachmentSize
user_import_profile_date_field_D5_2.patch 17.01 KB
user_import_profile_date_field_D6_2.patch 12.59 KB

#19

leebroozlee - June 1, 2009 - 03:03

Hi,

Just one small typo fix affecting YYYY/MM/DD users:

-+ else if ($date_format == 'YYYY/MM/DD/') {
++ else if ($date_format == 'YYYY/MM/DD') {

Cheers,

Paul

AttachmentSize
user_import_profile_date_field_D5_3.patch 17.01 KB
user_import_profile_date_field_D6_3.patch 12.59 KB

#20

Justin W Freeman - June 1, 2009 - 03:08

Oops, thanks for fixing that.

#21

cbrody - June 18, 2009 - 13:40

Hi Justin,

I tried your patch for D6 (#19) and it doesn't seem to work, no matter which date format I use.

Cheers,
Chris

#22

Justin W Freeman - June 22, 2009 - 02:21

Can you give some more information like a date that doesn't go in or something?

#23

cbrody - June 22, 2009 - 15:47

I've attached a sample file I tried to upload. The dates import correctly if I specify a text field as the destination but then they need transforming to be of any use.

AttachmentSize
Membership data test.txt 180 bytes

#24

Justin W Freeman - June 30, 2009 - 01:08

I was able to successfully import your file in with date data going into a date field.

I am using Drupal 5.12 and User import 5.x-2.8
The field I am importing into is a date field not a text field
On admin/user/user_import/configure for Date field format: I have selected DD/MM/YYYY

Is there anything else you can think of about your set up that might affect this import?

#25

cbrody - June 30, 2009 - 09:05

Only that I'm using Drupal 6.12 and User Import 6.x-1.2.

#26

Justin W Freeman - June 30, 2009 - 23:15
Version:5.x-2.8» 6.x-1.2
Status:needs review» patch (to be ported)

That would explain why it does not work as expected. This patch is for Drupal 5 and it is rare that a module is so similar from D5 to D6 that a patch will work for both.

And seeing as this patch will more likely be accepted with a 6 version as well I'll change the issue.

This patch will have to be ported to D6.

#27

Justin W Freeman - June 30, 2009 - 23:16

I won't be able to work on porting it to 6 any time soon though so if anyone else wants to that would be great.

#28

saccard - November 3, 2009 - 15:38

It would be nice, if this could be fixed for the D6 version of the module.
For importing users with a field "birthday" I used this "workaround":
1. Open the CSV file with open office
2. Insert a new column "birthday new"
3. Enter the following formula (this is for the german OO version!)

="a:3:{s:3:" & ZEICHEN(34) & "day" & ZEICHEN(34) & ";s:" & LÄNGE(TAG(BU2))&":"&ZEICHEN(34) &TAG(BU2)&ZEICHEN(34)&";s:5:"&ZEICHEN(34)&"month"&ZEICHEN(34)&";s:"&LÄNGE(MONAT(BU2)) &":"&ZEICHEN(34)&MONAT(BU2)&ZEICHEN(34)&";s:4:"&ZEICHEN(34)&"year"&ZEICHEN(34)&";s:" &LÄNGE(JAHR(BU2))&":"&ZEICHEN(34)&JAHR(BU2)&ZEICHEN(34)&";}"

4. Copy the formula down into each row
5. Repeat steps 1 to 4 if you have more date fields
6. Import the CSV file

The formula converts a date field entry like "dd.mm.yyyy" to something like this
a:3:{s:3:"day";s:2:"31";s:5:"month";s:1:"3";s:4:"year";s:4:"2000";}
Thats what the profile field expects.

 
 

Drupal is a registered trademark of Dries Buytaert.