[SalesForce] Set Unix timestamp value to datetime field

I want to set Unix timestamp value to datetime field.

string unixDatetime = '1510654220787';
system.debug('!!!unixDatetime='+datetime.newinstance(long.valueOf(unixDateTime)));

string s = string.valueOfGmt(datetime.newinstance(long.valueOf(unixDateTime)));
system.debug('!!!s='+s); 

DateTime dtConverted = DateTime.valueOf((datetime.newinstance(long.valueOf(unixDateTime)).format('yyyy-MM-dd HH:mm:ss')));

system.debug('!!!dtConverted='+dtConverted);

enter image description here

Account acc = [Select Id,Fully_Paid_Date__c From Account where id ='00127F000006TNUb'];

acc.Fully_Paid_Date__c=dtConverted;
update acc;

updated record value

Fully Paid Date 14/11/2017 9:10 PM

When I save this value to account object. The time value is stored as less than one hour.

Best Answer

The wording of your issue isn't very clear, but here's what I'm seeing:

  • The timestamp you're using corresponds to 2017-11-14 10:10:20
  • When you save this time to your Account, it shows either 2017-11-14 21:10:20 or 2017-11-14 09:10:20 (depending on if you really meant that the time being displayed is 9:10 PM)
  • You want the displayed time on your Account to be 2017-11-14 10:10:20

Looking at the documentation for Datetime, specifically, the description of Datetime.newInstance(milliseconds)...

newInstance(milliseconds)

Constructs a Datetime and initializes it to represent the specified number of milliseconds since January 1, 1970, 00:00:00 GMT.

Signature

public static Datetime newInstance(Long milliseconds)

Parameters

milliseconds
Type: Long

Return Value

Type: Datetime

The returned date is in the GMT time zone.

The very last line there is important. When you use Datetime.newInstance(<timestamp>), the result is the time in the GMT/UTC zone.

Datetimes in Salesforce are always stored as a timestamp in the GMT/UTC time zone. Salesforce uses the locale set in your user profile (or the org's default locale) to automatically adjust the displayed datetime to match your local time zone. Salesforce automatically does the translation in most other cases as well.

Knowing that, you're either in a UTC+1 or UTC+13 time zone. In either case, if you want your Account to display the GMT/UTC timestamp as if it were your own local time, you'll need to adjust the Datetime to your local time.

Luckily, that's fairly easy to accomplish.

Long timestamp = Long.valueOf('1510654220787');

DateTime gmtDatetime = DateTime.newInstance(timestamp);

System.TimeZone myTz = UserInfo.getTimeZone();

Integer millisecondOffsetGmt = myTz.getOffset(gmtDateTime);

DateTime localDatetime = DateTime.newInstance(timeStamp - millisecondOffsetGmt);

system.debug(gmtDatetime);    // This displays (in the debug log) 2017-11-14 10:10:20, regardless of local time
system.debug(localDatetime);  // For me, being UTC-6, this displays 2017-11-14 16:10:20 (again, in the debug log)

As for why we need to subtract the offset... That's because Salesforce adds your timezone offset to the GMT/UTC time when displaying it.

Displayed_Time = GMT_Time + Time_Zone_Offset

Since Salesforce assumes (internally) that DateTime.newInstance(milliseconds) returns GMT/UTC (and therefore doesn't need automatic adjustment), we need to pass that method the GMT/UTC timestamp that will result in our target datetime being displayed (and therefore automatically adjusted to local time)

GMT_Time = Displayed_Time - Time_Zone_Offset