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
Bob DeRosierBob DeRosier 

datetime format GMT

I want to change a time, where I have datetime and a timezone, to GMT (actually I want ISO8601).   I the local time for an event and the timezone for it, but the conversions I tried don't change the time in GMT when the timezone changes.  That is the underlying problem.

The specific problem I have is:

I have this line of code:
string modStartDT = StartDT.format(('yyyy-MM-dd\'T\'HH:mm:ss','America/New_York'); 

The developer guide https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_datetime.htm says that 
.format(dateFormatString, timezone)   is valid.

However, compiling the class produces this error for the above line
Error: Compile Error: expecting a right parentheses, found ',' 

I am using v38 of the SalesForce API.

If you know of another way solve my problem, I am open to that as well.
Nissam PSNissam PS
Hi Bob,

You have a extra "(" in the beginning. Make sure to have this format.

Datetime myDT = Datetime.now();
String myDate = myDT.format('h:mm a');

Thanks!
Bob DeRosierBob DeRosier
that was easy to fix, but removing the extra '('  now gives  'Error: Compile Error: Illegal assignment from String to Datetime'  
Nissam PSNissam PS
Have you tried with Date.parse()?

From the documentation, Constructs a Date from a String. The format of the String depends on the local date format.

date mydate = date.parse('12/27/2009');
Bob DeRosierBob DeRosier
The DateTime I want is already in SalesForce DateTime format.   It looks like .format(dateFormatString, timezone)   isn't behaving correctly,which seems an unlikely bug given how often datetime functions are used.
Alain CabonAlain Cabon
Hi Bob,

DateTime field values are stored as Coordinated Universal Time (UTC or GMT). When a dateTime value is returned in Salesforce, it’s adjusted for the time zone specified in your org preferences. 

https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_dateformats.htm (https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_dateformats.htm?search_text=UTC)

1)  Company Profile: GMT+01:00
User-added imageUser-added image

2) Convert a date using the local time or GMT time.

Local time = 15 h 20 min 45 seconds ( GMT+01:00)
GMT time = 14 h 20 min 45 seconds
Datetime StartDT = Datetime.newInstanceGmt(2017,1,7,14,20,45);
system.debug('StartDT (local time): ' + StartDT.format('yyyy-MM-dd\'T\'HH:mm:ss'));
string modStartDT = StartDT.format('yyyy-MM-dd\'T\'HH:mm:ss','America/New_York'); 
system.debug('modStartDT (local time): ' + modStartDT);
or
Datetime StartDT = Datetime.newInstance(2017,1,7,15,20,45);
system.debug('StartDT (local time): ' + StartDT.format('yyyy-MM-dd\'T\'HH:mm:ss'));
string modStartDT = StartDT.format('yyyy-MM-dd\'T\'HH:mm:ss','America/New_York'); 
system.debug('modStartDT (local time): ' + modStartDT);

StartDT (local time) :        2017-01-07T15:20:45  (GMT+01:00) Paris
modStartDT (local time) : 2017-01-07T09:20:45  (GMT-05:00)  New-York

New-York, local time = Paris, local time - 6 hours.

Best regards
Alain
 
Bob DeRosierBob DeRosier
The application I am using is needs to know the local time and offset and does not know the timezone of the org. I'm not sure why the error on .format went away. I ended up writing some code to convert dateTime and timezone to a time with the offset appended to the end, which I can then pass the application. For an event, people will physically attend, they want to know what time it starts in the local time zone, not in their home time zone.    
 
public string gmt(DateTime DT, String strTz) {
        string local = DT.format('yyyy-MM-dd\'T\'HH:mm:ss');    
        Timezone tz = Timezone.getTimeZone(strTz);                
        
        integer correction = tz.getOffset(dt);
        integer absCorr = correction;
        integer sign = 1;

//      abs apparently doesn't work on integers ?
        if (correction < 0) {
            absCorr = -1 * correction;
            sign = -1;
        }
//      use the time function to convert the offset (in ms) to hours and minutes        
        time t1 = time.newInstance(0, 0, 0, absCorr );
        
//      add leading 0 if needed        
        string offh = ( (t1.hour() < 10) ? '0'+ string.ValueOf( t1.hour()) : string.ValueOf( t1.hour()) );
        string offm = ( (t1.minute() < 10) ? '0'+ string.ValueOf( t1.minute()) : string.ValueOf( t1.minute()) );

        string gmt = local + ( sign == -1 ? '-'+offh+offm :'+'+offh+offm );

        return  gmt;
    }