This project is not covered by Drupal’s security advisory policy.

Hours, Minutes and Seconds Field provides a dedicated duration field type for any Drupal 10 or 11 site. Drop it onto any content type — nodes, comments, taxonomy terms, users, paragraphs, and more — and editors can enter durations in a natural time format while the module stores a precise integer (total seconds) in the database. Four built-in display formatters cover every output need: a configurable formatted string, a fully translatable natural-language sentence, a live JavaScript countdown timer, and an ISO 8601 duration string wrapped in a semantic element. A vanilla-JavaScript count-up timer rounds out the live display options. Whether you are building a video library, an event schedule, a course platform, a recipe site, or a fully decoupled headless application, Hours, Minutes and Seconds gives you the duration field your content needs — with Views integration, a developer-friendly service API, two alter hooks for extensibility, and a comprehensive config schema.

Features

Field Storage & Input

  • Single integer storage — Values are always stored as a plain INT (total seconds). No precision is ever lost regardless of the display format chosen.
  • Nine built-in input formatsh:mm, h:mm:ss, hh:mm:ss, m:ss, mm:ss, d:h:mm:ss, h, m, s — configured per field widget.
  • Min / Max constraints — Per-field-instance minimum and maximum values (in seconds) enforced on both the widget and the field-level constraint layer. Validation messages show the limit in the widget's own format (e.g. Minimum: 0:01 | Maximum: 8:00:00).
  • Negative durations — Full support for negative values in both PHP and JavaScript (e.g. a video offset of -5 seconds).
  • Format badge & seconds hint — The widget optionally shows a monospaced format badge next to the input and a raw-seconds hint below it, making it easy for editors to understand what they are entering.
  • Custom formats via alter hook — Register additional input/display format strings with hook_hour_minutes_seconds_format_alter().
  • Custom time units via alter hook — Add new units (e.g. fortnights, decades) with hook_hour_minutes_seconds_factor_alter().

Display Formatters (4 total)

  • Hours Minutes and Seconds (default) — Outputs the value as a formatted duration string using any of the nine built-in formats. Optionally enables the live JavaScript count-up timer so the displayed value increments every second from the stored offset.

    Example: 2:30:45
  • Natural language — Decomposes the value into human-readable fragments with configurable separator and last-separator strings. Tick exactly which units to include (weeks, days, hours, minutes, seconds). Singular/plural forms are handled automatically via Drupal's formatPlural() system and are fully translatable.

    Example: 2 hours, 30 minutes and 45 seconds
  • Countdown timer — Renders a live JavaScript countdown from the stored value to zero. Fires the CSS class hour-minutes-seconds--countdown-finished on completion, which you can target in your theme. An optional Finished text setting replaces the zero display with a custom message. The formatter sets #cache['max-age'] = 0 so the initial server-rendered value is always accurate.
  • ISO 8601 Duration — Outputs the value as a standards-compliant ISO 8601 duration string (e.g. PT2H30M45S), optionally wrapped in a element with a human-readable title tooltip. Ideal for microdata, JSON-LD, and machine-readable output.

    Example: PT2H30M45S

Every formatter is configured independently per view mode in Manage Display, so a Teaser can show a compact h:mm string while a Full page shows the live countdown — all from the same field.

Live Timer & Countdown

  • Zero jQuery dependency — The live timer behavior is pure vanilla JavaScript, depending only on core/drupal, core/drupalSettings, and core/once.
  • Data-attribute state — Timer state is passed via HTML data-* attributes ( data-hms-format, data-hms-since, data-hms-offset, data-hms-leading-zero, data-hms-countdown), never encoded in CSS class names.
  • Clock-drift correction — The behavior corrects for server–client clock drift by comparing the server timestamp (injected via drupalSettings.hours_minutes_seconds.servertime) with the client timestamp captured at page-load time.
  • CSS animation — A pulsing dot indicator ( ::before pseudo-element) animates on running and countdown timers; the animation is automatically suppressed when the user has prefers-reduced-motion set.
  • BEM CSS classes for theminghour-minutes-seconds--running, hour-minutes-seconds--countdown, hour-minutes-seconds--countdown-finished. Legacy underscore class aliases are retained for backward compatibility with pre-2.x theme CSS.

Views Integration

  • A custom Views field handler ( HoursMinutesSecondsViewsField) exposes HMS fields in any View with four selectable display modes: Formatted (format string), Natural language, ISO 8601, and Raw seconds.
  • Run drush cr after installation to register the plugin with the Views cache.

Developer Experience

  • Injectable servicehours_minutes_seconds.hour_minutes_seconds ( HoursMinutesSecondsService) provides secondsToFormatted(), formattedToSeconds(), isValid(), toArray(), toIso8601(), fromIso8601(), factorMap(), formatOptions(), and normalizeFormat().
  • Custom form element#type 'hour_minutes_seconds' can be dropped into any custom form. Accepts #format, #min, #max, #placeholder, and #default_value (stored seconds). Automatically converts the submitted formatted string to seconds on validation.
  • Two alter hookshook_hour_minutes_seconds_factor_alter() (add/modify time units) and hook_hour_minutes_seconds_format_alter() (add/remove format strings).
  • Full config schema — Typed YAML schema covers all widget settings, all four formatter settings, and field-level constraint settings, ensuring configuration is exportable and validatable.
  • Install/update hookshook_update_8001 back-fills min/max, show_seconds_hint, and live_timer defaults into existing config on upgrade; hook_update_8002 clears the render cache after the 2.x class-name changes.
  • Migrate API — No custom process plugin required. The field stores a plain integer, so the core get process plugin handles imports directly.

Accessibility

  • Every rendered carries role="timer" and an aria-label attribute populated with the plain-text formatted value.
  • The admin widget input uses a monospaced font, a clock icon, and a format badge to make the expected entry format immediately clear to all users.
  • CSS animation respects prefers-reduced-motion.

Post-Installation

  1. Add the field to a content type.

    Go to Structure → Content types → [Your Content Type] → Manage fields. Click Add field, choose Hours Minutes and Seconds from the dropdown, enter a label (e.g. Duration), and click Save and continue. On the Field settings page you can optionally set a Minimum and Maximum value in seconds to enforce constraints site-wide for this field instance.
  2. Configure the widget.

    Go to Manage form display for the content type and click the ⚙ gear icon next to the HMS field. Choose the Input format editors will type (e.g. h:mm:ss). Toggle Default placeholder to show the format string in the input until the editor starts typing, or enter a Custom placeholder. Optionally enable Show equivalent seconds hint to display the currently stored raw-seconds value below the widget.
  3. Configure the display.

    Go to Manage Display for the same content type. Set the formatter for your new field from the Format dropdown. The four options are:
    • Hours Minutes and Seconds — formatted string with optional live count-up timer.
    • Natural language — e.g. 2 hours, 30 minutes and 45 seconds.
    • Countdown timer — live JavaScript countdown with optional finished text.
    • ISO 8601 Duration — e.g. PT2H30M45S, optionally inside a element.

    Click the ⚙ gear icon to configure format, leading-zero behaviour, and formatter-specific options. Repeat for each view mode (Full content, Teaser, etc.) as needed.

  4. Clear caches.

    Run drush cr or visit Configuration → Performance → Clear all caches to register the Views field handler and any template changes.

Requirements

  • Drupal 10.x or 11.x
  • PHP 8.1 or higher
  • Drupal core module: Field (always enabled)

No third-party PHP libraries, JavaScript frameworks, CDN assets, or external services are required. The module is entirely self-contained.

Similar Projects

  • Duration Field — Also stores durations as ISO 8601 strings. Hours, Minutes and Seconds differs by storing a plain integer (total seconds) for simpler querying, sorting, and arithmetic, while providing live timer and countdown display formatters, Views integration, and a full developer service API out of the box.
  • Time Field — Stores a time-of-day value (wall-clock time). Hours, Minutes and Seconds is purpose-built for durations — arbitrary lengths of time, including values greater than 24 hours and negative offsets — rather than clock times.

Use Cases

Hours, Minutes and Seconds is well suited for:

  • Video and audio libraries — store and display track or clip lengths alongside content.
  • Event and conference sites — show session durations or live countdowns to scheduled start times.
  • Online learning platforms — display estimated reading or video time per lesson or course module.
  • Recipe sites — store preparation and cooking times with natural-language output ( 1 hour and 30 minutes).
  • Sports and fitness applications — record race times, workout durations, or rest periods.
  • Project management tools — track logged time or estimated effort per task or milestone.
  • Decoupled / headless Drupal applications — consume the stored integer directly via JSON:API or REST and format it client-side, or rely on the ISO 8601 formatter for interoperability with other systems.

Supporting This Module

If Hours, Minutes and Seconds saves you time on your project, the best way to support continued development is to:

  • Report bugs and suggest features in the project issue queue.
  • Contribute patches, test coverage, or documentation improvements.
  • Post a review on the project page — community ratings help others discover the module.
  • Help test release candidates against Drupal 10 and 11 minor updates.

When reporting an issue, please include your Drupal core version, PHP version, the steps to reproduce, and any relevant log output from Reports → Recent log messages.

Documentation

  • Full installation, configuration, theming, hook, and service API documentation is available in the README.md file included in the module.
  • The README.md covers: all nine format strings with example output, all data-* timer attributes, all CSS classes available for theming, every service method with PHP examples, both alter hooks with code samples, direct use of the #type 'hour_minutes_seconds' form element, direct theme rendering, Views integration, and a troubleshooting guide.
Supporting organizations: 
Development and Maintenance Support

Project information

Releases