Storing date/time fields

Some interesting tidbits about saving/updating a date/time field of a resource.

Why

The purpose of this guide is to explain how Zotonic stores date-time data so that you can work with it in your own modules.

Assumptions

Readers are expected to be interested in authoring Zotonic Modules. To be successful you should be fairly experienced with Erlang programming.

How

When updating a resource by passing a proplist to m_rsc:update/3, Zotonic has a way of looking for specific name patterns in the proplist that tells it what items are date/time fields and which ones are not. This allows Zotonic to split those off the proplists and use the name to derive information about the date, such as expected format, if the default time should be 00:00 or 23:59, and the actual field name that should be updated.

Here is an example format: dt:ymd:0:date_end

Literally this means …

  • the characters dt:, signifying the date-time marker
  • followed by some year, month, date pattern or whatever combination
  • followed by “:”
  • followed by 1 or 0 to designate default 00:00 or 23:59
  • followed by “:”
  • followed by the field name to by updated.

Have a look at _admin_edit_date.tpl in the default site templates tosee this and other formatting options.

For example passing [ {<<"dt:ymd:0:date_end">>, <<"2011-04-05">>} ] to m_rsc:update/3 would update the date_end field.

Here is an example event callback:

event(#submit{message={edit_details, [{id, Id}]}}, Context) ->
    End_date = z_context:get_q(<<"dt:ymd:0:date_end">>, Context),
    Props1 = [
        {<<"dt:ymd:0:date_end">>, End_date}
    ],
    case m_rsc:update(Id, Props1, Context) of
       {ok, _} ->
          z_render:wire({reload, []}, Context);
       {error, _} ->
           z_render:growl_error(<<"Could not update record.">>, Context)
    end.

Of course the input field of your form could be named whatever you wish, but when you assign it to the proplist you would use the naming convention above.

Internals

The date recombination is done if and only if the input for the update (or insert) operation is a list with key/value pairs.

It is assumed the list is from a form post. Form inputs are often separate for the date and the time parts and need to be recombined to full dates.

This recombination process is done in the z_props module on conversion from the list with key/value pairs to a (nested) map.