Details
-
Type:
Bug
-
Status: Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: 5.13.0
-
Fix Version/s: 5.13.1
-
Component/s: Staff Interface
-
Labels:None
Description
Summary
When editing a service's Advanced Options without changing any date fields and saving the form, the date_added and date_renews fields shift backwards by 1 day (e.g., from 2025-12-21 to 2025-12-20).
Description
A double timezone conversion issue occurs when saving the Advanced Options form for a service. The dates stored in UTC are displayed without timezone information, then incorrectly converted back to UTC on save, causing them to shift backwards by the timezone offset.
Steps to Reproduce
- Set a timezone with a POSITIVE offset like +8
- Navigate to a client's profile page
- Select a service and go to the "Advanced Options" tab
- Note the current date_added and date_renews values (e.g., 2025-12-21)
- Click "Save" without making any changes
- Observe the dates have shifted backwards by 1 day (e.g., 2025-12-20)
Expected Behavior
Saving the Advanced Options form without making changes should preserve all date fields exactly as they were.
Actual Behavior
Date fields (date_added, date_renews, date_last_renewed, date_paid_through, date_suspended, date_canceled) shift backwards by 1 day on each save operation. The offset corresponds to the company timezone setting.
Root Cause Analysis
Database Storage: Dates are correctly stored in UTC format
2025-12-21 00:00:00 (UTC)
View Display (admin_clients_editserviceadvanced.pdt:31):
$this->Form->fieldText($field, isset($vars->{$field}) ? substr($vars->{$field}, 0, 10) : null, ...);
- Only displays first 10 characters (date portion): 2025-12-21
- Timezone information is stripped and lost
On Save (admin_clients.php:7974-7980):
// Format dates $params = (array) $vars; foreach ($params as $key => &$field) { if (str_contains($key, 'date_')) { $field = empty($field) ? null : $this->Services->dateToUtc($field) . 'Z'; } }
The dateToUtc() Method (app_model.php:148-169):
$dt->setTimezone(Configure::get('Blesta.company_timezone'), 'UTC');
return $dt->format($format, $date);
- Interprets the input date (2025-12-21) as if it's in the company timezone, not UTC
- Converts to UTC, causing an incorrect shift
Example with Company Timezone Ahead of UTC
- Database: 2025-12-21 00:00:00 UTC
- Form displays: 2025-12-21
- System interprets as: 2025-12-21 00:00:00 [Company TZ]
- Converts to UTC: 2025-12-20 23:00:00 UTC (if company TZ is UTC+1)
- Saved as: 2025-12-20
Affected Files
- public_html/app/controllers/admin_clients.php (lines 7974-7980)
- public_html/app/views/admin/default/admin_clients_editserviceadvanced.pdt (line 31)
- public_html/app/app_model.php (dateToUtc method, lines 148-169)
Suggested Solutions
Option 1: Preserve timezone information in the form
- Display dates with the 'Z' suffix in hidden fields to indicate UTC
- Prevents misinterpretation during conversion
Option 2: Skip conversion for unchanged dates
- Compare submitted values with original service values
- Only convert dates that have been modified
Option 3: Append timezone indicator when displaying
- Modify the view to include substr($vars->{$field}, 0, 19) . 'Z' instead of just the first 10 characters
- Ensures dateToUtc() properly recognizes the date as already being in UTC
Impact
- Severity: Medium-High
- Data integrity issue that compounds on each save
- Affects all installations where company timezone differs from UTC
- Can cause billing and renewal date calculation errors
Activity
| Field | Original Value | New Value |
|---|---|---|
| Sprint | 5.14.0 Sprint 1 [ 222 ] |
| Rank | Ranked higher |
| Sprint | 5.14.0 Sprint 1 [ 222 ] | 5.14.0 Sprint 1, 5.14.0 Sprint 2 [ 222, 224 ] |
| Rank | Ranked higher |
| Assignee | Paul Phillips [ admin ] |
| Status | Open [ 1 ] | In Review [ 5 ] |
| Resolution | Fixed [ 1 ] |
| Status | In Review [ 5 ] | Closed [ 6 ] |