Apex Visualforce – Time Field from SOQL in Apex Not Populating Time in

apexspring22visualforce

There is a time field in Salesforce Attendee_Arrival_Time__c.
When querying in apex it is displaying time as 01:49:00.000Z and due to that it is not populating time in visualforce <apex:input type='time'/> tag.
I want to display it in Time only and not in String format.
Please help!

<apex:input type="time" id="arrivalTime" value="{!arrivalTime}" />

Best Answer

This is a change in Spring '22 where Time is now rendered, when converted to string to populate an apex:input value attribute, as hh:mm:ss.sssZ, instead of hh:mm as it is up to Winter '22. Identified as a regression bug by Salesforce R&D: see later.

To work around this, before a fix is available, you will need to work around this by updating your Apex controller to use String instead of Time and handle the conversion between the two for yourself.

From Time to String:

Time x = ...;
String xAsString = x.hour().format().leftPad(2, '0') + ':' + x.minute().format().leftPad(2, '0');

From String to Time:

String xAsString = ...;
String[] parts = xAsString.split(':');
Time x = Time.newInstance(Integer.valueOf(parts[0]), Integer.valueOf(parts[1]), 0, 0);

Use the String to populate the input and to receive the inputs updated value and handle the conversion as needed to/from the Time field in the controller. You can, I believe, keep the use of input type "time".

Note that one option is to still have the Time properties, but don't use them in the page, just in the controller. You can then:

  1. Add an equivalent String property to the controller. It's setter should set the underlying String property but also use the String to Time conversion to set the Time property if the converted value is different to the Time property value.
  2. Add a setter to the Time property that sets the underlying Time property and performs a Time to String conversion. If the result of that conversion is different to the String property value, set the String property.

The page is updated to use the equivalent String property instead of the Time property.

Total PITA. Will update if I get an answer as to if this is a bug or not.

UPDATE:

I have raised this as a Partner Support Case (#41955625) and await a response.

The following is a minimum viable reproduction:

Controller:

public with sharing class TimeIsBrokenController {
    public Time actualStartTime { get; set; }

    public TimeIsBrokenController() {
        actualStartTime = Time.newInstance(10, 13, 23, 0);
    }
}

Page (TimeIsBroken.page):

<apex:page id="TimeIsBroken" controller="TimeIsBrokenController" docType="html-5.0">
    <apex:form id="frmLoad">
        <apex:input type="time" value="{!actualStartTime}" title="Time is Broken"/>
    </apex:form>
</apex:page>

For Winter '22 this page renders as follows:

Winter 22 illustrating what is rendered into the "value" property

On the other hand Spring '22 renders like this:

Spring 22 illustrating the bad value rendered into "value" property

I ran the first on a Scratch org for Winter '22, and the second on a Scratch org for Spring '22, just setting the "release" property in the config/project-scratch-def.json.

FURTHER UPDATE

I am told by support that this is caused by this known issue which will be fixed by Salesforce's bug fix W-10436600. No idea of delivery timescales at this point.

(HOPEFULLY) FINAL UPDATE

From Salesforce Support:

This bug appears to be a regression in 236

Bug : Work ID W-10436600

Scheduled build is 236.6

Planned Start Time: 8:30 am IST /3:00 am GMT, Feb 05

Planned End Time: 8:35 am IST / 3:05amGMT, Feb 05

Related Topic