2

Note: I've tagged this question with 'Apex' because there doesn't seem to be any other way to resolve it. I'm able to call on an Apex Action in a flow, but I need help with the code.

Background

My org's timezone is GMT+10 or GMT+11, depending on whether or not daylight savings is in effect.

I have a flow which takes a date (StartDate) and converts it to a date/time value. I need the date/time value to be 9:30am on the same day as the date value.

As you know, Salesforce stores dates in GMT. So if the date value is 1/10/2019, the DATETIMEVALUE(StartDate) resolves to 1/10/2019 10am.

Which means DATETIMEVALUE(StartDate) - 0.5/24 resolves to 1/10/2019 9:30am - which is the date and time that I need.

Issue

The problem is, due to daylight savings, if the date is 1/11/2019, the same formula results to 1/11/2019 10:30am.

Question

How can I ensure that the date/time value derived from the date field (StartDate) is always the same date at 9:30am?

I'm starting to think this can only be achieved via Apex. This should be okay as I'm able to call on an Apex Action from a flow.

Things I've Tried

  1. Using this formula: DATETIMEVALUE(TEXT(YEAR(StartDate)) & "-" & TEXT(MONTH(StartDate)) & "-" & TEXT(DAY(StartDate)) & " 09:30:00")

  2. Using this formula with Today()

  3. Using this formula with StartDate

Any help would be much appreciated.

1 Answer 1

2

Well, let's say a particular time zone is the one you want the "9:30 AM" of. For argument's sake let's make it Australia/Sydney (full list here: https://www.australia.gov.au/about-australia/facts-and-figures/time-zones-and-daylight-saving).

// assume a Date object inputDate exists already
Timezone tz = Timezone.getTimeZone('Australia/Sydney');
Integer offset = tz.getOffset(inputDate);
Time t = Time.newInstance(9, 30, 0, 0);
Datetime dt = newInstanceGmt(inputDate, t).addSeconds(-offset/60);

I may or may not have made an error at this hour, but the idea is:

  • Get a reference to the time zone in question
  • Get the offset for it on the day of the input date - note that in North American time zones I usually need to use inputdate+1 here because at midnight GMT we haven't changed time zones yet. I think for UTC+10/11 you would have already shifted by midnight GMT though.
  • Create a Time instance (which is zone-free) and create a GMT DateTime matching the input day and time
  • And finally, shift it the opposite direction of the offset, so that you get it in the right zone.
4
  • Thank you for your answer, my understanding is that I need to create an Apex Class, annotate it using '@InvocableMethod', and pass the StartDate (from the Campaign record) to it by using the '@InvocableVariable' annotation. Is that correct? Would you be able to help me by providing all of the required code for the Apex Class? Sorry for the trouble, I'm not a developer so this isn't my area of expertise.
    – M H
    Commented May 28, 2019 at 13:12
  • I figured out how to make the Apex class invokable. I also noticed two issues with the last line of code you supplied, one with the syntax of 'newInstanceGmt' and the other with the offset. Both issues have been resolved and the code works like a charm! Thanks again for your help.
    – M H
    Commented Jun 4, 2019 at 3:37
  • Welcome. What did you change? I can edit my answer.
    – Charles T
    Commented Jun 4, 2019 at 4:28
  • 1
    Last line should be: Datetime dt = Datetime.newInstanceGmt(startDate, t).addSeconds(-offset/1000);. To make the Apex class invocable, a number of additional changes need to be made, which you can see here. I think editing the last line of the code in your answer should be sufficient for this question, you could just mention that additional changes are needed if the code needs to be invocable.
    – M H
    Commented Jun 4, 2019 at 5:25

You must log in to answer this question.

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