I can replicate it, and by removing the * 1000
and appending 3 zeros, I got "Invalid Integer". So what I believe is that 1391529600 * 1000
is being evaluated as an integer type and so overflowing.
You can create the Long value using the L
notation like so:
system.debug(DateTime.newInstance(1391529600000L));
To get the epoch from a datetime
variable you can just call the getTime()
instance method:
Datetime dt = Datetime.now();
Long l = dt.getTime();
system.debug(l);
system.debug(DateTime.newInstance(l));
produces:
USER_DEBUG|[7]|DEBUG|1391560453900
USER_DEBUG|[9]|DEBUG|2014-02-05 00:34:13
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
Best Answer
looks like I was searching for the wrong terms earlier: searching for unix epoch conversion revealed this link:
Convert Date to milliseconds and milliseconds to Date
As well as this:
http://www.codetalks.in/2013/08/salesforce-apex-unix-time-stamp-datetime.html
EDIT: Oh, also, here's the documentation of the method that works directly with Unix millisecond timestamps
datetime.newInstance(Long)
Constructs a Datetime and initializes it to represent the specified number of milliseconds since January 1, 1970, 00:00:00 GMT.
https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_datetime.htm