Duration Field
Creates a duration Field API field that collects periods of time with configurable granularity including years, months, days, hours, minutes, and seconds.
duration_field
Install
composer require 'drupal/duration_field:8.x-2.2'
composer require 'drupal/duration_field:8.x-2.1'
Overview
The Duration Field module provides a comprehensive solution for collecting and displaying time periods in Drupal. It creates both a Form API form element and a Field API field of type 'duration'. A duration represents a time period with configurable granularity, allowing sites to collect any combination of years, months, days, hours, minutes, and seconds.
Duration values are stored internally as ISO 8601 duration strings (e.g., P1Y2M3DT4H5M6S), which provide a standardized format for representing time intervals. Additionally, the module stores the duration as seconds to enable mathematical comparison queries in the database.
The module makes no assumptions about what time units a user needs to collect, offering complete flexibility. For example, a site could configure a field to collect only hours and minutes for a work shift duration, or years and months for a contract period. The module also supports an optional weeks field for use cases that require week-based calculations.
Features
- Provides a 'duration' field type for entities with configurable time unit granularity (years, months, days, hours, minutes, seconds)
- Stores durations in ISO 8601 format for standardization and as seconds for database comparison queries
- Offers three display formatters: Human Friendly (e.g., '2 years 3 months'), Duration String (ISO 8601), and Time Format (YY/MM/DD HH:MM:SS)
- Includes Form API elements for both duration input and granularity configuration
- Supports optional weeks field in addition to standard ISO 8601 duration components
- Provides query tag 'duration_string' for comparing durations using ISO 8601 strings in database queries
- Includes services for converting between duration formats, validating ISO 8601 strings, and calculating seconds from intervals
- Extensible formatter separators via hook_duration_field_separators() and hook_duration_field_labels()
- Drush command for safely preparing module uninstallation by removing all duration field data
- Full support for AJAX and #states on duration form elements
- Configurable increment steps for duration input (e.g., 15-minute intervals)
- JSON API and serialization support through DateIntervalData normalizer
Use Cases
Employee Work Shift Duration
Create a duration field with granularity set to hours and minutes (h:i) to collect the length of work shifts. Use the Human Friendly formatter to display values like '8 hours 30 minutes' on employee schedules.
Recipe Cooking Time
Add a duration field to a Recipe content type with hours and minutes granularity. Configure the formatter with short text length and comma separator to display '1 hr, 30 min' for a recipe's total cooking time.
Project Timeline Estimates
Create a duration field with weeks enabled and months/weeks/days granularity for project management. The weeks field allows for more natural project planning while maintaining ISO 8601 compatibility.
Video/Audio Content Length
Use hours, minutes, and seconds granularity (h:i:s) for media content. The Time Format formatter displays values as '01:45:30' which is familiar to users for media playback times.
Subscription Period Configuration
Configure a duration field with years and months granularity for subscription services. The ISO 8601 string storage (e.g., 'P1Y6M') provides a standardized format for programmatic processing.
Event Duration with Database Queries
Create an events listing that filters by duration. Use the 'duration_string' query tag to find events longer than 2 hours using an ISO 8601 condition like 'PT2H' which automatically compares against the stored seconds value.
Tips
- Use the #date_increment property on duration form elements to restrict input to specific intervals (e.g., 900 for 15-minute increments, 3600 for hourly increments)
- The 'duration' Form API element can be used independently in custom forms - just add '#type' => 'duration' with optional #granularity and #required_elements properties
- For programmatic access, use the duration_field.service to convert between ISO 8601 strings, PHP DateInterval objects, and seconds as needed
- When querying durations, tag your query with 'duration_string' to compare using human-readable ISO 8601 values instead of raw seconds
- Custom separators for the Human Friendly formatter can be added by implementing both hook_duration_field_separators() and hook_duration_field_labels() in your module
Technical Details
Hooks 3
hook_duration_field_separators
Allows modules to add custom separators between time values in the Human Friendly formatter. Must be implemented alongside hook_duration_field_labels().
hook_duration_field_labels
Provides translated labels for custom separators added via hook_duration_field_separators(). Must be implemented when adding custom separators.
hook_query_duration_string_alter
Internal hook implementation that allows querying duration fields using ISO 8601 strings by converting them to seconds for comparison. Tag queries with 'duration_string' to enable this behavior.
Drush Commands 1
drush duration_field:prepare_uninstall
Prepares the Duration Field module for uninstallation by deleting all duration field data and field configurations. This is a destructive operation with confirmation prompt.
Troubleshooting 4
Run the update hooks (drush updatedb) which handle migration from the old 'value' column to the new 'duration' and 'seconds' columns, and convert granularity settings from array to string format.
Use the Drush command 'drush duration_field:prepare_uninstall' (or alias 'drush df-pu') to delete all duration field configurations and data before attempting to uninstall the module.
Ensure queries are tagged with 'duration_string' to enable automatic conversion of ISO 8601 duration conditions to seconds-based comparisons. The module uses the 'seconds' column for mathematical operations.
Enable 'Include weeks' in the field settings. Weeks are stored separately from the ISO 8601 duration string (which doesn't support weeks) and must be explicitly enabled per field.