0

We have a simple intake form with the following attributes. So you can think of the object records would be as follows:

ID Military Time Time Zone Add Days (from today's date)
1 0700 America/Chicago 3
2 0600 America/Chicago 4
3 0600 America/New York 1

As you probably already know, a lot of the Date and DateTime methods in salesforce work's off of the User Context's Locale Time Zone or GMT.

Now we have user's around the country with different locale settings.

For example, when a user who's locale is in (GMT-04:00) Eastern Daylight Time (America/New_York) is executing the method, we would want the return to be specific to the record's time zone.

User's Local - (GMT-04:00) Eastern Daylight Time (America/New_York)

Today's Date is 3/24/2022

ID Display Output
1 3/27/2022 7:00 AM CDT
2 3/28/2022 6:00 AM CDT
3 3/25/2022 6:00 AM EDT

I tried different approaches like for example the Record ID 1

String militaryTime= '0700';
Time timeValue= Time.newInstance(Integer.valueOf(militaryTime.substring(0, 2)), Integer.valueOf(militaryTime.substring(2, 4)), 0, 0);


DateTime dateTimeVal = DateTime.newInstance(Date.Today().addDays(3), timeValue);


System.Debug(dateTimeVal); //Returns 2022-03-27 11:00:00
System.Debug(dateTimeVal.format('MM/dd/yyyy HH:ss a z')); //Returns 03/27/2022 07:00 AM EDT
System.Debug(dateTimeVal.format('MM/dd/yyyy HH:ss a z','America/Chicago')); //Returns 03/27/2022 06:00 AM CDT

Somehow it is not returning 3/27/2022 7:00 AM CDT, is there anything I am doing wrong here?

8
  • 2
    I'm confused by "we would want the return to be specific to the record's time zone" since records don't have timezones. Only Users do. Can you please clarify? Are you saying you have a field to hold the time zone in the record and you want the record's "Military Time" to be considered in that time zone?
    – Phil W
    Mar 24, 2022 at 22:06
  • Worth remembering that System.debug always outputs Datetime values in UTC (or as Salesforce calls it GMT).
    – Phil W
    Mar 24, 2022 at 22:07
  • Hi @PhilW yes, correct. We would want to consider the military time in that time zone.
    – jojopogi
    Mar 24, 2022 at 22:09
  • OK, so do you want to calculate the Datetime for the required date and military time in the required timezone and then have it shown in the user's timezone?
    – Phil W
    Mar 24, 2022 at 22:11
  • @PhilW - nope, we just want it to be displayed in the required timezone associated with that entry.
    – jojopogi
    Mar 24, 2022 at 22:14

1 Answer 1

1

You can handle creating a Datetime in a target Time Zone from "local date and time" details using the following code. Here I have explicitly selected a problematic date/time in the target Time Zone to show why we need to adjust when traversing a DST transition between UTC and the target Time Zone:

// Define the local date and local time
Date d = Date.newInstance(2022, 03, 13);
Time t = Time.newInstance(6, 0, 0, 0);

// Note this renders in the user's locale format (I'm in the UK, dd/MM/yyyy)
System.debug('Input local: ' + d.format().left(10) + ' ' +
    ('0' + t.hour().format()).left(2) + ':' +
    ('0' + t.minute().format()).left(2));

// Convert this into a UTC date/time value
Datetime dt = Datetime.newInstanceGmt(d, t);

// Identify the target time zone
TimeZone target = TimeZone.getTimeZone('America/Chicago');

System.debug('In Time Zone ' + target.getID());

// Figure out the offset at this UTC "moment"
Integer offsetAtUTC = target.getOffset(dt);

// Adjust the date/time value to be in the
// target time zone
Datetime targetDatetime = dt.addSeconds(-offsetAtUTC / 1000);

// Now it is in the target time zone, we have
// a new "moment". If the UTC "moment" was
// before a DST transition but the "moment" in
// the target time zone is after that
// transition the calculation will be adrift
Integer offsetAtLocal = target.getOffset(targetDatetime);

System.debug('UTC: ' + offsetAtUTC);
System.debug('Local: ' + offsetAtLocal);

if (offsetAtLocal != offsetAtUTC) {
    // There's a drift because of a DST
    // transition. Correct it
    System.debug('Adjusting for DST transition');
    targetDatetime = targetDatetime.addSeconds((offsetAtUTC - offsetAtLocal) / 1000);
}

System.debug(targetDatetime);
System.debug(targetDatetime.format('MM/dd/yyyy HH:ss a z', target.getID()));

This outputs:

08:40:54.20 (23543330)|USER_DEBUG|[5]|DEBUG|Input local: 13/03/2022 06:00
08:40:54.20 (24306962)|USER_DEBUG|[13]|DEBUG|In Time Zone America/Chicago
08:40:54.20 (24765664)|USER_DEBUG|[29]|DEBUG|UTC: -21600000
08:40:54.20 (24843783)|USER_DEBUG|[30]|DEBUG|Local: -18000000
08:40:54.20 (24905115)|USER_DEBUG|[35]|DEBUG|Adjusting for DST transition
08:40:54.20 (25019450)|USER_DEBUG|[39]|DEBUG|2022-03-13 11:00:00
08:40:54.20 (25184662)|USER_DEBUG|[40]|DEBUG|03/13/2022 06:00 AM CDT

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .