Date

by Gisle Hannemyr

This chapter is about the Date project in Drupal 7.

Table of contents

Drupal project discussed in this chapter: Date.

Introduction

Before you start, you should check the general settings for date and time and make sure they are correct.

These settings are manged by the core Locale module, but used by Date.

See alsoYou may also want to read the community documentation for Date/Calendar. It contains a presentation of the date field types, the date locale, the date API, date form elements and guides to common date and calendar applications. You should also read the debugging guidelines.

When debugging, make sure you use latest development snapshot:

drush dl date-7.x-2.x-dev
drush updb
Useful for debugging:
Epoch converter
TZ converter

D8 DateTime vs. D7 Date

Regional settings are in core. They are identical to Drupal 7 and let you set TZ for site and user. The TZ set here is referred to as “site/user time” below. The default is to use site time, unless user are allowed to set own time.

In D8 Date is replaced by the DateTime core module. This section summarizes the differences from the Drupal 7 Date module.

Here is a suummary og how dates are handled i D8 and D7. D8 has a display setting called “Time zone override” (TZO). D7 has a field setting named “Time zone hanling” (TZH). TZO overrides can be set to “none”, or to an explicit time zone (including UTC). TZH provides 5 options, described below.

Input:
D8: Always shows site/user time. Converted to UTC upon saving.
D7: TZH=none - not converted. Otherwise converted to GMT depending upon field settings.
Output:
D8: TZO=none - show site/user time. Else it shows time converted to TZO.
D7: TZH=none - show date as entered. Else show site/user time.

The D8 project has two different date fields:

field_date
field_date_value (varchar) 2018-11-11T07:00:00. TZ: None, or explicit override.
field_timestamp
field_timestamp_value (int) 1541916000. TZ: Default site/user, or explicit override.

The D8 form entry has the misfeature that the only allowed entry format uses a 12 hour clock (there is n 24 hour option): See issue #2936268.

The D7 project has three different date fields:

field_justdate
field_justdate_value (datetime) 2018-11-11 07:00:00. TZ: 5 options.
field_isodate
field_isodate_value (varchar) 2018-11-11T07:00:00. TZ: 5 options.
field_unixdate
field_unixdate_value (bigint) 1541919600. TZ: 5 options.

[Need to figure out how it works.]

Plan

Problem/Motivation

The time zone handling of the date module is not always working correctly. The problems date back to days of Drupal 6 and there are now more than 100 open issues related to time zone bugs. This is a plan for a major overhaul of the time zone handling.

For Drupal 7, there is a page describing the Date Locale & Time Zone settings. There are 5 different options for the field setting that describes how dates are processed. This is horribly complex, and to make things worse, behavior has changed over time.

In Drupal 8 the Date project is replaced by the DateTime core module. It processing of time zones is simpler than the current Date module, and can be summarized as follows:

This much simpler approach will be adequate for most use cases, but misses the setting where we explictly do not want time zone conversions (i.e. where time zone conversions are not working reliably, for dates with no times, for historical dates where timezones are irrelevant, or anytime conversion is unnecessary or undesirable).

Proposed resolution

For most part use the Drupal 8 approach, as described above, but retain the field setting “No time zone conversion” for the explicit use case where time zone conversion is not wanted. In detail:

The current 5 options in field settings will be replaced with just two options:

  1. Default site/user time zone (i.e. default site time zone unless overridden by the user – this is only option available in Drupal 8).
  2. No time zone conversion (I think we still need this one for some use cases).

If the first option is set for the field, the procedure is similar to one used by Drupal 8, i.e.:

If the second option is set for the field, the procedure is this:

The development of a new time zone handling procedure will take part in a new branch (7.x-3.x) to not interfere with the continued maintenance of Date 7.x-2.x. The 7.x-3.x shall not show up on the project page, but can only be downloaded using git by people committed to reviewing that branch.

Remaining tasks

  1. Discuss the plan, and incorporate any changes agreed upon in the plan. I will leave at least two weeks for discussions.
  2. Implement the agreed upon solution, making time zone handling robust and reliable.
  3. Documenting the behaviour of the revised time zone handling.
  4. Write expanded test cases for the revised time zone handling, to prevent future breakage.
  5. Write migrate sub-modules to migrate data from Date 7.x-2.x to 7.x-3.x
  6. After making sure the branch is functional, Vijaya Chandran will expose 7.x-3.x branch on the project page for broader testing.
  7. Get it to RTBC, Vijaya Chandran create a tagged relese 7.x-3.0.

User interface changes

TBA

API changes

TBA

Data model changes

TBA

Use cases

Field settings

When the Date module saves the date and time, no TZ is saved. but when the data is saved to the database, it is converted to UTC if the input is in a known context different from UTC.

When configuring a date field, the

date05.png
The field settings for date field instance let you set the time zone handling.

“Time zone handling" pull-down menu has five settings. Four of those provide TZ conversions:

  1. Site's time zone:
    When entering data into the field, the data entered is assumed to be in the site's time zone.
  2. Date's time zone:
    [Buggy: Do not use.]
  3. User's time zone:
    When entering data into the field, the data entered is assumed to be in the user's time zone.
  4. UTC:
    When entering data into the field, the data entered is assumed to be in UTC time zone.

When the data is saved to the database, it is converted to UTC (if conversion is necessary). When retrieved from the database, the data is converted to the Site's time zone for anonymous users or the User's time zone for logged in users when user-configurable time zones is enabled.

The last setting is provided for for dates with no times, and for situations where time zone conversions are irrelevant, unnecessary or undesirable:

  1. No time zone conversion:
    The date entered is not converted when saved to the database. When retrieved from the database, the data is not converted and is displayed exactly as entered.
    Currently (ver. 7.x-2.10) this is buggy if if field type is “Date (Unix timestamp)” (Issue #2994171).

Source: User contributed documentation.

noteThe ime zone handling menu doesn't show up under field settings unless you enable collecting hour attribute.

If this has worked as documented, it would be great. Need to verify.

Unforunately, this is rather buggy. Below is the results of some tests I have run.

The time zone settings for the site and the user are:

foo
Time zone handling User input Database → Human readable Comment
No time zone conversion 2018-08-01 00:00 1533074400 2018-07-31 22:00:00 UTC Converted (bug).
1533047400

Using the Form API

Date form elements.

Legacy?

The default options for the pop-up widget are defined in the function date_popup_element_info in date_popup.module. Additional documentation is in date_api_elements.inc.

function date_popup_element_info() {
  $timepicker = date_popup_get_preferred_timepicker();
  $type['date_popup'] = array(
    '#input' => TRUE,
    '#tree' => TRUE,
    '#date_timezone' => date_default_timezone(),
    '#date_flexible' => 0,
    '#date_format' => variable_get('date_format_short', 'm/d/Y - H:i'),
    '#datepicker_options' => array(),
    '#timepicker' => variable_get('date_popup_timepicker', $timepicker),
    '#date_increment' => 1,
    '#date_year_range' => '-3:+3',
    '#date_label_position' => 'above',
    '#process' => array('date_popup_element_process'),
    '#value_callback' => 'date_popup_element_value_callback',
    '#theme_wrappers' => array('date_popup'),
    '#datepicker_options' => array('minDate' => 0, 'maxDate' => 0),
  );
  if (module_exists('ctools')) {
    $type['date_popup']['#pre_render'] = array('ctools_dependent_pre_render');
  }
  return $type;
}
#date_timezone
The timezone to be used to create this date.
#date_flexible
?
#date_format
A format string that describes the format and order of date parts to display in the edit form for this element. This makes it possible to show date parts in a custom order, or to leave some of them out.
#datepicker_options
An array of key-value pairs passed to the Javascript widget. Used for additional options such as minDate.
#timepicker
See Date Popup Timepicker and Using with date_popup Form API element .
#date_increment
Increment minutes and seconds by this amount in the timepicker.
#date_year_range
String indicating the range of years to go back and forward in a year selector. Example: “-3:+3” (3 years back and 3 years forward).
#date_label_position
Handling option for date part labels, like “Date”and “Time”. Can be “above” the widget, “within” it, or “none”. The “within” option shows the label as the first option in a select list or the default value for an empty textfield, taking up less screen space. Only “above” works with the pop-up widget.

The following options in the form builder will create a date picker field using the ISO-8601 date format. No time picker will show. Th user may navigate within the current year, and two years in the future. It will disallow entering dates in the past.

  $form['datepicker'] = array(
    '#type' => 'date_popup',
    '#date_format' => 'Y-m-d',
    '#date_year_range' => '0:+2',
    '#datepicker_options' => array('minDate' => 0),
  );

Useful hooks:

hook_date_text_process_alter()
hook_date_popup_process_alter()
hook_date_combo_process_alter()
hook_date_select_process_alter()

Source: Drupal SE.

Final word

[TBA]


Last update: 2016-09-20.