1

I currently have the following function:

public String formatForGermany(Datetime targetTime) {
    return this.format(targetTime, 'Europe/Berlin');
}

private String format(Datetime targetTime, String zone) {
    Integer offset = TimeZone.getTimeZone(zone)
            .getOffset(targetTime);
    return targetTime.addSeconds(offset / 1000)
            .format('HH:mm');
}

This works fine the input value is GMT.

However, it seems in some contexts (TBD), Salesforce seems to anticipate this transformation is wanted and does it for me, in which case the offset gets applied twice, with the result that I display (for example) 14:00 instead of 12:00.

Is there some way I can check whether the time has already been offset and either not apply it or adjust the offset accordingly?

3
  • 1
    It is all down to the user's locale. If the user is in Germany already Salesforce will automatically handle offsets for them, converting between their timezone and UTC when data is presented or saved as required.
    – Phil W
    Sep 16 '20 at 11:56
  • @PhilW, so the best way to handle this is to check the User's locale, nothing in the Datetime itself? Sep 16 '20 at 12:07
  • 1
    Right - the Datetime has nothing to tell you. It is actually a UTC value under the hood, with Salesforce doing appropriate to- and from- user timezone conversions as needed.
    – Phil W
    Sep 16 '20 at 12:27
3

One option is to take the UTC Datetime value, convert it to Berlin time then extract the date and time (using the dateGmt() and timeGmt() methods on Datetime) values and present these as separate Date and Time values. Note that Salesforce only applies user-timezone-processing to Datetime values. Separate Date and Time values have no timezone so no offsetting is applied by Salesforce.

3

With thanks to @Phil W whose feedback put me on the right track, I've modified my code to the following which seems to work:

public String formatForGermany(Datetime targetTime) {
    return this.format(targetTime, 'Europe/Berlin');
}

private String format(Datetime appointmentDatetime, String zone) {
    Integer offset = TimeZone.getTimeZone(zone)
            .getOffset(appointmentDatetime);
    Time targetTime = appointmentDatetime.timeGmt()
            .addSeconds(offset / 1000);
    return this.leftPage(targetTime.hour())
            + ':' + this.leftPage(targetTime.minute());
}

private String leftPage(Integer value) {
    return String.valueOf(value)
            .leftPad(2, '0');
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.