Uploaded image for project: 'Blesta Core'
  1. Blesta Core
  2. CORE-5628

Service Advanced Options date shift due to double timezone conversion issue

    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

      1. Set a timezone with a POSITIVE offset like +8
      2. Navigate to a client's profile page
      3. Select a service and go to the "Advanced Options" tab
      4. Note the current date_added and date_renews values (e.g., 2025-12-21)
      5. Click "Save" without making any changes
      6. 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):

      Unable to find source-code formatter for language: php. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
      $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):

      Unable to find source-code formatter for language: php. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
      // 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):

      Unable to find source-code formatter for language: php. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
      $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

        admin Paul Phillips created issue -
        admin Paul Phillips made changes -
        Field Original Value New Value
        Sprint 5.14.0 Sprint 1 [ 222 ]
        admin Paul Phillips made changes -
        Rank Ranked higher
        jonathan Jonathan Reissmueller made changes -
        Sprint 5.14.0 Sprint 1 [ 222 ] 5.14.0 Sprint 1, 5.14.0 Sprint 2 [ 222, 224 ]
        jonathan Jonathan Reissmueller made changes -
        Rank Ranked higher
        admin Paul Phillips made changes -
        Assignee Paul Phillips [ admin ]
        admin Paul Phillips made changes -
        Status Open [ 1 ] In Review [ 5 ]
        Resolution Fixed [ 1 ]
        admin Paul Phillips made changes -
        Status In Review [ 5 ] Closed [ 6 ]

          People

          • Assignee:
            admin Paul Phillips
            Reporter:
            admin Paul Phillips
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Agile