function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
MohandaasMohandaas 

DateTime in local Time Zone

In my apex code, system.now() returns the current Datetime based on a GMT calendar. My aim is to get the date time value in my local time zone.Since we have day light saving, I didn't think  about manipulating the time difference.

 

I would appreciate your suggestions.

 

Under personal information, I have set the time zone as "Time Zone(GMT-05:00) Eastern Daylight Time (America/New_York)".

 

 

 

 

Shoby Abdi.ax910Shoby Abdi.ax910

Hi 

 

Try the following 

 

datetime myDateTime = datetime.now();

string mydtstring = mydatetime.format();

System.debug(mydtstring);

 

This is in the Apex documentation under the Datetime Methods

JamsieJamsie

Hi cloud nine,

 

try this...

 

public class Utility {

 

    public static Datetime getLocalDateTime(Datetime z)
    {    
        Datetime l = z.Date();
        l = l.addHours(z.hour());
        l = l.addMinutes(z.minute());
        l = l.addSeconds(z.second());
        
        return l;
    }

}

 

Datetime gmt = Datetime.Now();

Datetime local = Utility.getLocalDateTime(Datetime.Now());

System.Debug('GMT Time: ' + gmtNow);

System.Debug('Local Time: ' + local);

 

 

MohandaasMohandaas

Jamsie, Shoby appreciate your time.

 

Here is an alternate method, straight forward.

 

Datetime current = System.now(); // returns date time value in GMT time zone.

 

Date currDate = current.date();

Date currTime = current.time();

 

Datetime local = datetime.newinstance(currDate,currTime); // This will return date time in my local time zone.

JamsieJamsie

Hi Cloud Nine,

 

that's a bit neater.  Funnily enough I built a method to convert from local to GMT using the same pattern...


/*-----------------------------------------------------------------------------------------------------
    //getGMT(Datetime l)
    // -------------------------------------
    // Returns GMT datetime from the passed local datetime.
    //---------------------------------------------------------------------------------------------------*/

    public static Datetime getGMT(Datetime l)
    {    
        Date d = l.dateGmt();
        Time t = l.timeGmt();
        
return Datetime.newInstance(d,t);
    }

 

Ironically I found out I don't need either of these if I use BusinessHours.addGmt instead of BusinessHours.add.

The joys of timezones and daylight savings. :smileyvery-happy:

FrankCabrejaFrankCabreja

How about this one-liner?: 

 

system.now().format()

 

This returns the system time in the local time zone for the company, I believe.

ptepptep

Big warning to anyone using this code on an Authenticated Sites Visualforce page!  These functions will return the results in the timezone of the current user -- the user logged in or if no one is logged in, as the special Sites Guest User. This user is set to have a GMT timezone by default. I've been trying to figure out why this wasn't working for a while and it turns out it was working, but the local timezone was GMT because I was viewing the page as the guest user. To find the guest user and change its timezone, go to Develop > Sites > Your site label > Public Access Settings > Assigned Users

 

natronnatron

Here's what I did using the new TimeZone object which returns the user's time zone offset in milliseconds.

 

T is a Task object.

 

TimeZone tz = UserInfo.getTimeZone();
DateTime localTime = T.CreatedDate.AddSeconds(tz.getOffset(T.CreatedDate)/1000);

NZArchitectNZArchitect

Some of these answers are misleading if you do not understand the full stack.

You need to ask yourself what do you plan to do with the DATE / DATETIME data you have in you trigger or controller.
Is the data going into a standard field for display or a custom VF field, or being sent back to the Database?
Do you need compare datetimes against start/end of month/week/year.

There is a real danger here, if you convert to LOCAL but you do not convert back before you save.
Native salesforce fields will represent themselves in Local TIme via the UI, even though they are stored  and processed in GMT.

Of course no timezone info is ever stored, just year --> second


You must know the input of your method and the output.

E.g. most answers described above input in GMT and output in LOCAL. You will need to convert back again.

IMPORTANT: do not use a convert to local twice otherwise you will be 2x your time zome out.
THINK: Input need to match output at the top level. Yes convert down to LOCAL to process but then convert back to GMT.

Please see this for a demonstration, run in your execute anon:

You will see that 2 runs through the first method cause twice the timezone adjustment.

integer i = 1;
public Datetime getLocalDateTime(Datetime g)
    {    
System.Debug('Initial g : '+i+' : ' + g);
System.Debug('Initial g.format(): '+i+' : ' + g.format());
        
        Datetime l = g.Date();
System.Debug('During l: '+i+' : ' + l);
System.Debug('During l.format(): '+i+' : ' + l.format());
        l = l.addHours(g.hour());
        l = l.addMinutes(g.minute());
        l = l.addSeconds(g.second());
System.Debug('After l: '+i+' : ' + l);
System.Debug('************Note Processing to Local twice moves it away by a factor of 2****************');
System.Debug('After l.format(): '+i+' : ' + l.format());
        i++;
        return l;
    }

public Datetime getGMTDateTime(Datetime g)
    {    
System.Debug('G Initial g         : '+i+' : ' + g);
System.Debug('G Initial g.format(): '+i+' : ' + g.format());
        
        Datetime g2 = g.DateGMT();
System.Debug('During g2: '+i+' : ' + g2);
System.Debug('During g2.format(): '+i+' : ' + g2.format());
        g2 = g2.addHours(g.hourGMT());
        g2 = g2.addMinutes(g.minuteGMT());
        g2 = g2.addSeconds(g.secondGMT());
System.Debug('After g2: '+i+' : ' + g2);
System.Debug('************Note processing with GMT does nothing to the result****************');
System.Debug('After g2.format(): '+i+' : ' + g2.format());
        i++;
        return g2;
    }
 
Datetime gmt = Datetime.Now();
Datetime l_once = getLocalDateTime(gmt);
Datetime l_twice = getLocalDateTime(l_once);
System.Debug('****************************');
System.Debug(' ');
System.Debug('***********************');
Datetime g_once = getGMTDateTime(gmt);
Datetime g_twice = getGMTDateTime(g_once);
System.Debug('****************************');
Mohammad AnisMohammad Anis
Hi All,

To get the current Datetime in the local time zone, you can use the following working code:

Datetime now = Datetime.now(); Integer offset = UserInfo.getTimezone().getOffset(now); Datetime local = now.addSeconds(offset/1000);

If it helps don't forget to mark this as a best answer!!!

Thanks,
Mohammad Anis
Duncan Barr 2Duncan Barr 2
Hi Guys!

This use case now has a fairly simple answer. As a previous answer stated, using System.now().format() will give you local time of the current user. If that user is an API call, the "local timezone" is likely to be Zulu time AKA: UTC (Universal Time Code). However, the dateTime.format function accepts a few inputs that can help you specify a format and timezone which takes daylight saving and all that jazz into account.

Put simply, if you want to get local time in a specified timezone, try the following example:
String now = System.now().format('dd/MM/yyyy HH:mm:ss', 'Australia/Melbourne');
System.debug(now);

// expected result: 24/07/2020 10:10:26
...and Bob' s your uncle!

Bonus info: if you want the timezone as well (unforntunately it's longform) you can do:
String city = 'Australia/Melbourne';
String now = System.now().format('dd/MM/yyyy HH:mm:ss', city) + ' ' + TimeZone.getTimeZone(city).getDisplayName();

System.debug(now);

// expected result: 24/07/2020 10:10:26 (GMT+10:00) Australian Eastern Standard Time (Australia/Melbourne)

If this helped you out, mark it as best answer. Hopefully it helped some people out :)

Duncan