Daylight Saving Time or not?

Even though in Salesforce you can set the correct time zone, in some cases you might be unhappily surprised by a time that is suddenly displayed in GMT rather than your own time zone.

When and why does this occur?

This problem occurs when a date, time or Date/Time value is used in a formula of which the output type is not date or Date/Time.

By default all Date/Time values are actually saved in GMT / UTC. The value is then only converted to the org's or user's time zone by the user interface.

Met Salesforce Inspector Reloaded kun je dit snel in de praktijk zien. Zoek een willekeurig datum/tijd veld op in een record in je omgeving en bekijk daarna de waarde van ditzelfde veld via Salesforce Inspector. Wat er in je User Interface uitziet als 29-03-2023 12:00, turns out to actually have 2023-03-29T10:00:00.000+0000 as the API value.

Op het moment dat je deze Datum/Tijd waarde in een formule gebruikt en het output type is niet Datum/Tijd, dan is nooit vast te stellen of het zomertijd of wintertijd is en kan de juiste correctie dus niet berekend worden.

So, when you use the Date/Time value to convert it into a Text or Time value, you will see the time in GMT and not the time in your local timezone (if it differs from GMT).

When you want to include the date and time of an appointment in a user-friendly format in an email, you will probably make use of one or more formulas that have text or time as their output.

Je wilt natuurlijk niet een onjuiste afspraaktijd aan de klant communiceren, dus kun je een correctie inbouwen op je formuleveld, maar je moet daarin ook nog rekening houden met of het nu zomertijd of wintertijd is.

Om te bepalen of de waarden van een Datum/Tijd veld in zomertijd of wintertijd is, is dit de formule die je nodig hebt. myDateTimeField moet hierin het veld zijn waarvan je wilt weten of die Datum/Tijd in zomertijd of wintertijd is.

AND(
    myDateTimeField
    >  
    DATETIMEVALUE(
        DATE(
            YEAR( DATEVALUE( myDateTimeField ) ),
            4,
            1
        ) -
        WEEKDAY(
            DATE(
                YEAR( DATEVALUE( myDateTimeField ) ),
                3,
                24
            )
        )
        + 3/24
    ),
    myDateTimeField 
    < 
    DATETIMEVALUE(
        DATE(
            YEAR( DATEVALUE( myDateTimeField ) ),
            11,
            1
        ) -
        WEEKDAY(
            DATE(
                YEAR( DATEVALUE( myDateTimeField ) ),
                10,
                24
            )
        )
        + 2/24
    )
)

Kort uitgelegd is de uitkomst van deze formule true wanneer myDateTimeField ná 3:00 uur ’s nachts op de laatste zondag van maart is en vóór 2:00 uur ’s nachts op de laatste zondag van oktober.

Daar horen wel een paar kleine disclaimers bij:

  • Het uur tussen 2:00 en 3:00 uur op de laatste zondag van maart bestaat niet (want om 2:00 uur gaat de klok vooruit en wordt het meteen 3:00 uur)
  • Het uur tussen 2:00 en 3:00 uur op de laatste zondag van oktober bestaat in werkelijkheid eerst één keer in zomertijd en meteen daarna nóg een keer in wintertijd (want de eerste keer dat het 3:00 uur wordt, gaat de klok achteruit en wordt het meteen voor de tweede keer 2:00 uur)
  • Op de laatste zondagen van maart en oktober tussen 1:00 en 3:00 is het gedrag van Salesforce met de Datum/Tijdwaarde onvoorspelbaar, dus vertrouw niet teveel op datumtijdwaarden binnen die uren.
    • Voer je een tijd in van 1:45, dan zie je 0:45 staan nadat je hebt opgeslagen
    • Op de laatste zondag van maart geeft de bovenstaande formule al na 1:00 uur zomertijd aan. Dat lijkt niet te corrigeren door in de formule nog eens 1 of 2 uur op te tellen bij de Datum/Tijdwaarde waarmee je myDateTimeField vergelijkt.

Elk Datum/Tijd veld heeft een eigen zomertijd test nodig

Let op dat je voor elk afzonderlijk Datum/Tijdveld moet controleren of de waarde van dát veld in zomer- of wintertijd valt.

Een losse formule waarmee je bepaalt of het NU wintertijd is, gaat je immers niet helpen om altijd de juist conversie te maken op een Datum/Tijd die niet NU is.

Voorbeeld

  • Appointment_Date_Time__c = 20 april 13:00 uur
  • isSummerTime__c is een formule die aangeeft of het NU zomertijd is
  • AppointmentTimeText__c is een formule die de tijd van Appointment_Date_Time__c als tekst weergeeft
  • Als de formule geschreven is zoals hieronder zal ik daar op 20 maart de output “12:00 uur” lezen, maar als ik op 1 april naar hetzelfde formuleveld kijk, staat er “13:00 uur”
TEXT(
    HOUR( TIMEVALUE( Appointment_Date_Time__c ))
    +
    IF(
        isSummerTime__c,
        2,
        1
    )
) &
":" &
TEXT(
    MINUTE( TIMEVALUE( Appointment_Date_Time__c ))
) &
" uur"

Een afzonderlijk isSummerTime veld is vanwege de kans op fouten geen goed idee. Beter schrijf je één integrale formule zoals:

TEXT(
    HOUR( TIMEVALUE( Appointment_Date_Time__c ))
    +
    IF(
        AND(
            Appointment_Date_Time__c
            >  
            DATETIMEVALUE(
                DATE(
                    YEAR( DATEVALUE( Appointment_Date_Time__c ) ),
                    4,
                    1
                ) -
                WEEKDAY(
                    DATE(
                        YEAR( DATEVALUE( Appointment_Date_Time__c ) ),
                        3,
                        24
                    )
                )
                + 3/24
            ),
            Appointment_Date_Time__c
            < 
            DATETIMEVALUE(
                DATE(
                    YEAR( DATEVALUE( Appointment_Date_Time__c ) ),
                    11,
                    1
                ) -
                WEEKDAY(
                    DATE(
                        YEAR( DATEVALUE( Appointment_Date_Time__c ) ),
                        10,
                        24
                    )
                )
                + 2/24
            )
        ),
        2,
        1
    )
) &
":" &
TEXT(
    MINUTE( TIMEVALUE( Appointment_Date_Time__c ))
) &
" uur"