Are you still looking for solution to display local time for the Account in Salesforce? If yes, you have come to the right place! I am sure you will get a lot from this post, so please read on!

Before getting started, let me give you guys a little background of the situation here. Salesforce CRM is our company's main CRM system for managing our clients and stuff. We have clients in almost every state in United States and we also have clients from countries other than United States as well.

The thing is, our support team is based in China and 95% of our clients are located in United States. They are actually having a hard time to call or contact the customer at the "right" time due to the timezone offset. It is hard to tell from the account address either since they are not familiar with US address as well. Hence, as a almighty Salesforce Administrator of the company, I was asked to provide solution and here we go!

AppExchange is the first place that I look for. I am quite surprised to find out that there aren't many apps or components to do a very simple task like showing local time for the account. The closest that I am getting at is this component:

local-time-lwc-component

Unfortunately, the component cannot be installed due to component's deprecation, so I decided to get down another road, which is to create the component myself!

This is the lightning component that I developed (code will be explained in a bit):

local-timezone

Lightning component that displays the account's local time and the user's current time (browser)

The component is inspired by this website which makes use of Google Timezone API to get the local time based on the location. If you are not sure how to generate the API key, please check it out yourself as I will not explain it here (very easy, you can do it!).


Well, long story short, let's get to the main part here.

First of all, we are going to create a new Lightning Component, let's called it LocalDateTimeComponent.cmp:

<!-- LocalDateTimeComponent.cmp -->
<aura:component implements="flexipage:availableForRecordHome,flexipage:availableForAllPageTypes,force:hasRecordId" access="global" >
	
	<aura:attribute name="localTimezoneString" type="String"/>
    <aura:attribute name="localTimeString" type="String"/>
    <aura:attribute name="localDateString" type="String"/>
    <aura:attribute name="browserTimezoneString" type="String"/>
    <aura:attribute name="browserTimeString" type="String"/>
    <aura:attribute name="browserDateString" type="String"/>
    
    <aura:attribute name="record" type="Account" />
    
    <force:recordData layoutType="FULL"
                      recordId="{!v.recordId}"
                      fields="Name,BillingLongitude,BillingLatitude"
                      targetFields="{!v.record}"
                      recordUpdated="{!c.recordUpdated}" />
    
    <lightning:card>
        <lightning:layout verticalAlign="stretch" multipleRows="true" class="x-large">
            <lightning:layoutItem flexibility="auto" padding="around-small" class="custom-box">
                <p style="margin-bottom:1em;">Account Local Time</p>
                
                <h1 style="font-weight:700;font-size:2em;margin-top:0.8em;margin-bottom:0.2em;">{!v.localTimeString}</h1>
                <h3>{!v.localDateString}</h3>
                <h3>{!v.localTimezoneString}</h3>
            </lightning:layoutItem>
            <lightning:layoutItem flexibility="auto" padding="around-small" class="custom-box">
                <p>My Browser Time</p>
                
                <h1 style="font-weight:700;font-size:2em;margin-top:0.8em;margin-bottom:0.2em;">{!v.browserTimeString}</h1>
                <h3>{!v.browserDateString}</h3>
                <h3>{!v.browserTimezoneString}</h3>
                
            </lightning:layoutItem>

        </lightning:layout>
    </lightning:card>     
</aura:component>

In LocalDateTimeComponent.cmp, we use <force:recordData /> to load the record data and once the record is loaded, the recordUpdated method will be called. Next, we will work on our controller:

// LocalDateTimeComponentController.js
({
    
    recordUpdated: function(component, event, helper) {
        
        var apikey = 'your-google-api-key';
        var location = component.get("v.record").BillingLatitude + ',' + component.get("v.record").BillingLongitude 
        var daysofweek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
        
        var targetDate = new Date(); // Current date/time of user computer
        var timestamp = targetDate.getTime() / 1000 + targetDate.getTimezoneOffset() * 60; // Current UTC date/time expressed as seconds since midnight, January 1, 1970 UTC
        var apicall = 'https://maps.googleapis.com/maps/api/timezone/json?location=' + location + '&timestamp=' + timestamp + '&key=' + apikey ;       
                
        var xhr = new XMLHttpRequest();
        xhr.open('GET', apicall); 
        xhr.onload = function(){
            if (xhr.status === 200){ 
                var output = JSON.parse(xhr.responseText); // convert returned JSON string to JSON object
                if (output.status == 'OK'){ 
                    var offsets = output.dstOffset * 1000 + output.rawOffset * 1000; // get DST and time zone offsets in milliseconds
                    var localDate = new Date(timestamp * 1000 + offsets); // Date object containing current time of target location
                    var refreshDate = new Date(); // get current date again to calculate time elapsed between targetDate and now
                    var millisecondselapsed = refreshDate - targetDate; // get amount of time elapsed between targetDate and now
                    localDate.setMilliseconds(localDate.getMilliseconds() + millisecondselapsed); // update localDate to account for any time elapsed
                    setInterval(function(){
                        localDate.setSeconds(localDate.getSeconds() + 1);
                        targetDate.setSeconds(targetDate.getSeconds() + 1);

                        component.set('v.browserTimeString',targetDate.toLocaleTimeString() );
                        component.set('v.browserDateString', targetDate.toLocaleDateString() + ' (' + daysofweek[ targetDate.getDay() ] + ')');
                        component.set('v.browserTimezoneString',  'Timezone: ' + Intl.DateTimeFormat().resolvedOptions().timeZone + '' );
                        component.set('v.localTimeString',localDate.toLocaleTimeString() );
                        component.set('v.localDateString', localDate.toLocaleDateString() + ' (' + daysofweek[ localDate.getDay() ] + ')');
                        component.set('v.localTimezoneString', 'Timezone: ' + output.timeZoneId + '' );                        
                    }, 1000);
                }
                
            } else{
                console.log('Request failed.  Returned status of ' + xhr.status);
            }
            
            
        }
        xhr.send();      

    }
})

In LocalDateTimeComponentController.js, we will make an API call to Google endpoint. A standard Google Map Timezone API call looks like this:

GET https://maps.googleapis.com/maps/api/timezone/json?location=40.747817,-73.984694&timestamp=1578999905&key=YOUR_API_KEY

A successful API call will return the following response:

{
	"dstOffset" : 0,
	"rawOffset" : 18000,
	"status" : "OK",
	"timeZoneId" : "America/New_York",
	"timeZoneName" : "Eastern Standard Time"
}

You might ask, how do we get location=40.747817,-73.984694?

Well, the latitude and longitude are actually retrieved from the field BillingLatitude and BillingLongitude in Account, and thanks to Salesforce's Data Integration Rules, those latitude and longitude can be automatically calculated after you activate the rules.

data-integration-rules

Let's get back to the code. With a successful response, we can then calculate for the local date/time of the account. We use setInterval to update the date/time every second as though the clock is ticking!

local-timezone

Lightning component that displays the account's local time and the user's current time (browser)

NOTE: The majority of the code is inspired by this article.


Well, that's all about it! I hope you enjoy reading this post!

Post was published on , last updated on .

Like the content? Support the author by paypal.me!