So confused! and I've spent 2 days on this!

I have a custom db table with an ISO format date (2009-01-01T00:00:00), and I'm trying to have it show up as a date field. I thought I had everything set correctly: My table is completely defined in views, and the table data is recognized, and I've implemented hook_date_api_fields in my custom module, defining it as a DATE_ISO sql_type. I've even got a year-based date filter that's working perfectly to filter by this same field

BUT whenever I try to display the field, every field lists the year as 1969, so it looks like it's reading it as unix time (the default). Any idea how to tell views that it should be interpretting it as ISO for the field and not just for the filter? I'm going loony over here!

It seems worth mentioning that this is a user base table, in case that might be the root of the problem.

In date_api_fields.inc, It completely gives the impression that custom modules should be able to use Date API, so I'm going to list this as a bug. Here are the apparently relevant portions of date_api_fields.inc, but I haven't been able to track down the problem:

    // Allow custom modules to provide date fields.
    elseif ($handler_name == 'views_handler_field_date') {
      foreach (module_implements('date_api_fields') as $module) {
        $function = $module .'_date_api_fields';
        if ($custom = $function("$table_name.$field_name")) {
          $type = 'custom';
          break;
        }
      }
    }
      // Allow the custom fields to over-write values.
      if (!empty($custom)) {
	    dsm($custom);
        foreach ($custom as $key => $val) {
          $fields['name'][$name][$key] = $val;
        }
      }

Thanks anyone!

Comments

patcon’s picture

Title: $custom array not populated for custom date fields in date_api_fields.inc » views_handler_field_date for custom module outputs as if default UNIX date type (everything's 1969)

OK so, scratch the earlier issue. But there's still the problem that any custom fields defined in modules (regardless of the sql_type defined in the hook_date_api_fields) are output as if they were UNIX dates. Its seems that only the filter recognized it as the correct DATE_ISO type, whereas it tries to display it as DATE_UNIX (the default for the views_handler_field_date handler).

The short-term fix is to actually convert my date from ISO to UNIX in the database table, but it doesn't solve anything.

I'll update if I figure anything out.

karens’s picture

Status: Active » Fixed

There is complete information provided if you have the Advanced Views module installed. In Advanced Help, go to help/date_api/date-views-dates to see how this is supposed to work. You are supposed to tell the handler what kind of field you are using, it assumes a timestamp if you don't tell it anything.

patcon’s picture

Thanks for the reply Karen, but as I said above, I've used hook_date_api_fields, but it only affects the filter handler, not the field handler (apparently?). Unless perhaps I'm implementing it incorrectly:

function date_api_date_api_fields($field) {
  $values = array(
    // The type of date: DATE_UNIX, DATE_ISO, DATE_DATETIME.
    'sql_type' => DATE_ISO, 
    // Timezone handling options: 'none', 'site', 'date', 'utc'.
    'tz_handling' => 'none',
    // Needed only for dates that use 'date' tz_handling.
    'timezone_field' => '', 
    // Needed only for dates that use 'date' tz_handling.
    'offset_field' => '', 
    // Array of "table.field" values for related fields that should be 
    // loaded automatically in the Views SQL.
    'related_fields' => array(),
    // Granularity of this date field's db data. 
    'granularity' => array('year'),
  );
  
  switch ($field) {
    case 'results_students.year':
    case 'results_schools.year':
      return $values;
  }
}

PS - You're awesome.

Status: Fixed » Closed (fixed)

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

timtrinidad’s picture

Status: Closed (fixed) » Active

I'm getting this problem too - filters and arguments work as they should, but it seems that the display isn't aware that its a date of type DATE_ISO.

dropcube’s picture

fleetcommand’s picture

Hoping that it's going to be fixed

Anonymous’s picture

subscribe
cannot get hook_date_api_fields() to be called (it is driving me nuts).

patcon’s picture

It think I just ended up giving up on trying to display it, since filtering was my main objective (and that worked fine).

I'd suggest trying different timezone and granularity settings, and that might help sort out the bug.

patcon’s picture

Still running into this over a year later. Has anyone had any success in navigating this? I'm thinking it must be a misunderstanding on our part, as I can't imagine it being so quiet here otherwise.

Anyone have any thoughts as to what part of the setup might be missing?

patcon’s picture

Errr...

Just did a grep, and there doesn't seem to be a module_invoke_all('date_api_fields') bit anywhere in the Date module directory... just a module_invoke_all('date_api_tables')...

Could the reason it's not firing be because it doesn't exist? Isn't that function needed to create a hook? module_implements is used in one place, but I don't think that has anything to do with hooks... right?

patcon’s picture

Ok, so just did a backtrace from date_api_date_api_fields(), which is supposedly called by hook_date_api_fields() (which I would've presumed was module_invoke_all('date_api_fields')...), and it's looking like it's actually called by _date_api_fields().

Seems that this is where it happens:

    // Allow custom modules to provide date fields.
    // The is_a() function makes this work for any handler
    // that was derived from 'views_handler_field_date'.
    elseif (is_a($handler, 'views_handler_field_date')) {
      foreach (module_implements('date_api_fields') as $module) {
        $function = $module .'_date_api_fields';
        if ($custom = $function("$table_name.$field_name")) {
          $type = 'custom';
          break;
        }
      }
    }

So I guess it uses this instead of module_invoke_all(), but this only gets called when a filter is attached to a view, and not when just a field is, so I don't get how the field would ever know how to process the date data.

naringas’s picture

Could this be related to the Views module (http://drupal.org/project/views)??

I'm writing a custom node type module, and I store a date in ISO format in my Database.
The problem arises when I use the Views module (I implement hook_views_data) and I use the views_handler_field_date function (from Views) to display my date field. The date is always in 1969...

Looking at the code in 'views/handlers/views_handler_field_date.inc' from the views module; specifically the 'render($value)' function looks like it expects the date value it gets to be in UNIX format, there isn't any code that checks what kind of date to expect.

(I don't even use the Date module or Date API, so I might be out of track)

stinky’s picture

Subscribe

naringas’s picture

I fixed the issue I had (comment #13) by using the patch provided over here: http://drupal.org/node/939004#comment-3667374

I incorporated views_handler_field_date_timezone.inc (from that patch) into my module and used that as a handler for my date field and the dates were fixed...

views_handler_field_date_timezone.inc does have code that converts the dates it receives into DATE_UNIX format (date_make_date() from the Date API).

dariogcode’s picture

For the records:

I had to use hook_date_api_fields and hook_date_api_tables for declare my custom field, and in the views_data integration I have:

   'field' => array(
      'handler' => 'views_handler_field_datetime',
      'click sortable' => TRUE,
    ),
    'sort' => array(
      'handler' => 'views_handler_sort_date',
    ),
    'filter' => array(
      'handler' => 'date_api_filter_handler',
    ),

views_handler_field_datetime is the following custom handler tha convert datetime to timestamp only for display purposes:

class views_handler_field_datetime extends views_handler_field_date {

  function render($values) {
  	$value = $values->{$this->field_alias};
    if (!empty($value)) {
    	$datetime = new DateTime($value);
    	$value = $datetime->getTimestamp();
    }
    $values->{$this->field_alias} = $value;
    return parent::render($values);
  }
  
}

And Like I'm using a relationship, some fail in the filter, then I make a change in the date_api_filter_handler.inc line 450

$table_alias = !empty($this->related_table_alias) ? $this->related_table_alias : ($this->relationship ? $this->relationship  : $field['table_name']);

That is because relationship contain the correct table alias (I don't know why)

I hope this help to somebody in the near future. Thanks!

damienmckenna’s picture

Status: Active » Closed (won't fix)

Unfortunately the Drupal 6 version of the Date module is no longer supported. That said, we appreciate that you took time to work on this issue. Should this request still be relevant for Drupal 7 please feel free to reopen it. Thank you.