Timezone

Fieldtype for storing timezone values with dynamic UTC offsets.

Timezone Fieldtype and Inputfield for ProcessWire

Module Name: FieldtypeTimezone / InputfieldTimezone
Author: Maxim Alex
Version: 1.0.0
License: Mozilla Public License 2.0
Icon: clock-o

Overview


Simple and reliable module for ProcessWire that provides timezone functionality. The module automatically calculates current UTC offsets taking into account Daylight Saving Time (DST).

✨ Key Features

  • Dynamic UTC offsets - automatic calculation of current offsets with DST support
  • Simplicity - no complex settings, works out of the box
  • Performance - intelligent caching (24 hours)
  • Reliability - strict validation at all levels
  • Complete coverage - all major world timezones
  • ProcessWire 3.x - full compatibility

Display Format


Timezones are displayed in the format:

Country → City (UTC+X)

Examples:

United States → New York (UTC-5) Japan → Tokyo (UTC+9) United Kingdom → London (UTC+0) Australia → Sydney (UTC+11)

UTC offsets are calculated dynamically, so for timezones with DST the values change automatically:

  • America/New_York: UTC-5 in winter, UTC-4 in summer
  • Europe/London: UTC+0 in winter, UTC+1 in summer

Requirements


  • ProcessWire 3.0.0 or higher
  • PHP 8.1 or higher
  • InputfieldTimezone module (installs automatically)

Installation


Option 1: Via Git

cd /path/to/processwire/site/modules/ git clone https://github.com/mxmsmnv/FieldtypeTimezone.git

Option 2: Manual Installation

  1. Download the ZIP archive
  2. Extract to /site/modules/FieldtypeTimezone/
  3. Ensure the structure is correct:
   /site/modules/FieldtypeTimezone/    ├── FieldtypeTimezone.module.php    ├── InputfieldTimezone.module.php    └── README.md

Module Activation

  1. Log in to your ProcessWire admin panel
  2. Go to ModulesSite
  3. Find FieldtypeTimezone and click Install
  4. InputfieldTimezone will be installed automatically

Usage


Creating a Field

  1. Go to SetupFieldsAdd New
  2. Enter field name (e.g., user_timezone)
  3. Select type Timezone
  4. Save the field
  5. Add the field to desired templates

No additional configuration required - everything works out of the box!

Working with the Field in Templates

Basic Usage

// Get timezone value $timezone = $page->user_timezone; echo $timezone; // Outputs: America/New_York  // Check for empty value if ($page->user_timezone) {     echo "Timezone: " . $page->user_timezone; }

Working with DateTime

// Create DateTime object with user's timezone if ($page->user_timezone) {     $tz = new \DateTimeZone($page->user_timezone);     $datetime = new \DateTime('now', $tz);      echo "Current time in user's timezone: " . $datetime->format('F j, Y \a\t g:i A T');     // Outputs: Current time in user's timezone: December 31, 2025 at 5:13 PM EST }

Time Conversion

// Convert UTC time to user's timezone function convertToUserTimezone($utcTime, $userTimezone) {     $utc = new \DateTimeZone('UTC');     $tz = new \DateTimeZone($userTimezone);      $datetime = new \DateTime($utcTime, $utc);     $datetime->setTimezone($tz);      return $datetime->format('F j, Y \a\t g:i A T'); }  // Usage $utcTime = '2025-12-31 18:30:00'; $localTime = convertToUserTimezone($utcTime, $page->user_timezone); echo $localTime; // December 31, 2025 at 2:30 PM EST (for America/New_York)

Getting Timezone Information

// Get detailed timezone information $fieldtype = $fields->get('user_timezone')->type; $info = $fieldtype->getTimezoneInfo($page->user_timezone);  if ($info) {     echo "Identifier: " . $info['identifier'] . "<br>";     echo "Offset: " . $info['offset_formatted'] . "<br>";     echo "Abbreviation: " . $info['abbreviation'] . "<br>"; }

Programmatic Value Setting

// Set timezone programmatically $page->of(false); $page->user_timezone = 'Europe/London'; $page->save('user_timezone'); $page->of(true);  // Or when creating a page $newPage = new Page(); $newPage->template = 'user'; $newPage->parent = $pages->get('/users/'); $newPage->title = 'John Doe'; $newPage->user_timezone = 'Asia/Tokyo'; $newPage->save();

Displaying User's Current Time

// Current time widget if ($user->timezone) {     $tz = new \DateTimeZone($user->timezone);     $now = new \DateTime('now', $tz);      echo "<div>";     echo "<strong>Your local time:</strong> ";     echo $now->format('l, F j, Y - g:i A T');     echo "</div>";     // Outputs: Tuesday, December 31, 2025 - 5:13 PM EST }

API Methods

getTimezoneInfo($timezone)

Get complete timezone information:

$fieldtype = $fields->get('timezone_field')->type; $info = $fieldtype->getTimezoneInfo('America/New_York');  // Returns array: // [ //     'identifier' => 'America/New_York', //     'offset' => -18000, //     'offset_formatted' => 'UTC-5', //     'name' => 'America/New_York', //     'abbreviation' => 'EST' // ]

Usage Examples


Example 1: User Profile with Timezone

// In user profile template <div>     <h2><?= $page->title ?></h2>      <?php if ($page->user_timezone): ?>         <div>             <strong>Timezone:</strong>             <?php             $tz = new \DateTimeZone($page->user_timezone);             $now = new \DateTime('now', $tz);             echo $page->user_timezone . ' (Current time: ' .                  $now->format('g:i A') . ')';             ?>         </div>     <?php endif; ?> </div>

Example 2: Event Calendar

// Display event time in user's timezone foreach ($pages->find('template=event') as $event) {     $eventTime = new \DateTime($event->event_date, new \DateTimeZone('UTC'));      if ($user->timezone) {         $userTz = new \DateTimeZone($user->timezone);         $eventTime->setTimezone($userTz);     }      echo "<div>";     echo "<h3>" . $event->title . "</h3>";     echo "<time>" . $eventTime->format('l, F j, Y - g:i A T') . "</time>";     echo "</div>";     // Outputs: Tuesday, December 31, 2025 - 5:13 PM EST }

Example 3: Auto-detect Timezone (with JavaScript)

// In registration form template <script> // Automatically detect browser timezone document.addEventListener('DOMContentLoaded', function() {     const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;     const field = document.getElementById('timezone_field');      if (field && timezone) {         field.value = timezone;     } }); </script>  <select id="timezone_field" name="user_timezone">     <!-- Options will be populated by ProcessWire --> </select>

Security


Data Validation

  • Automatic sanitization of all input data
  • Validation of timezone identifiers
  • Protection against SQL injection via parameterized queries
  • Database field indexing for optimization

Error Handling

// Safe handling of invalid timezones try {     $tz = new \DateTimeZone($page->user_timezone); } catch (Exception $e) {     // Fallback to UTC     $tz = new \DateTimeZone('UTC');     $this->log->save('timezone-errors',         "Invalid timezone: {$page->user_timezone}"); }

⚡ Performance


Caching

The module automatically caches the timezone list for 24 hours:

// Manually clear cache (if needed) $cache = wire('cache'); $cache->deleteFor('InputfieldTimezone_*');

Database Optimization

The field is automatically indexed for fast lookup:

KEY data (data)

️ Extending Functionality


Adding New Timezones

If you need to add additional timezones:

// In InputfieldTimezone.module.php, extend the $timezoneMapping array protected static $timezoneMapping = [     'Your/Custom_Timezone' => ['Your Country', 'Your City'],     // ... ];

Changelog


Version 1.0.0 (2025-10-03)

Stable Release

Added:

  • Dynamic UTC offset calculation with DST support
  • Intelligent caching (24 hours)
  • Database field indexing
  • getTimezoneInfo() API method
  • Extended data validation
  • Simple and reliable functionality without complex settings

Changed:

  • Complete module architecture rewrite
  • Performance optimization
  • Improved code structure
  • Updated documentation

Fixed:

  • Removed duplicate timezone entries
  • Fixed encoding issues
  • Improved error handling

Version 0.1.0 (Beta)

  • Initial release

Support and Contribution


Report an Issue

License


This module is distributed under the Mozilla Public License 2.0.

More modules by Maxim Semenov

  • Context

    Export ProcessWire site context for AI development (JSON + TOON formats)
  • WireWall

    Advanced traffic firewall with VPN/Proxy/Tor detection, rate limiting, and JS challenge
  • LQRS URL Shortener Profile

    This site profile for ProcessWire offers a free and easy-to-use URL shortener that transforms long links into concise, shareable URLs. It is built using standard ProcessWire modules and field types.
  • Media Platform Profile

    This site profile for ProcessWire offers a fully-featured media platform for hosting and managing video content with Backblaze B2 and Cloudflare integration.
  • AgeWire

    Age verification module with Tailwind CSS support
  • 2048

    Take a break with 2048 game in ProcessWire admin
  • GeoIP

    MaxMind GeoLite2-based geolocation. Country/region/city detection with user correction support and conditional content blocks.
  • Invite Access

    Restricts site access to visitors with a valid invite code. Designed for staging environments with multiple teams.
  • WirePDF

    Convert ProcessWire pages to PDF documents with advanced typography support

All modules by Maxim Semenov

Install and use modules at your own risk. Always have a site and database backup before installing new modules.