17

I'd like a clever way to handle this in all my code from now on.

I have some existing methods that do date calculations in apex...some use the businessHours object and some don't. Many surface results to visualforce pages and work nicely.

When I retrieve them by jsRemoting, I get back javascript date, which is really date time. So if my apex date is 4/5/2013, I'm getting back 4/4/2013 at 6pm...it like it took the apex date at midnight (start of the day) and timeline shifted it for US central time (my locale).

It gets even uglier when I have to validate do jquery mobile html form stuff...so I'm converting that date time in JS to a string to prepopulate a form field. Then depending on what the user enters, I have to validate it against a min/man date from apex...and I'm dealing with the date being ok, but depending on what times are entered, the hours being not ok.

Is there a way to "fix" what comes back from apex? Or am I better off doing all this on the client side? JS date manipulation is not as elegant as apex.

5 Answers 5

14

Well I came across this problem and this gets uglier when you are converting the double value returned from apex into date, the timezone offset gets added into the time and can even change the date!!!.

Well to fix this I wrote a simple js function which nulifies the effect by subtracting the offset back from the date.

function normalizeDate(mydate){
   mydate = new Date(mydate );
   mydate = new Date(mydate - mydate.getTimezoneOffset() * 60000);
   return mydate;
 }

You can use the above function and try doing something like this :

 //obj is record returned by js remoting 
    obj.Custom_Date__c = normalizeDate(obj.Custom_Date__c);

You can even extend the above js function to print a date string

function normalizeDateExtended(mydate){
    mydate = new Date(mydate);
    data = new Date(mydate -  mydate.getTimezoneOffset() * 60000);
    var d = mydate.getDate();
    var m = mydate.getMonth()+1;
    var y = mydate.getFullYear();
    return ''+ (m<=9?'0'+m:m) +'-' + (d<=9?'0'+d:d)+'-' + y;
}
3
  • Avi, I'm not at my pc to try this now, but it looks like exactly what I need. Commented Feb 16, 2013 at 0:56
  • 2
    No need to adjust the timezone, just use getUTCDate(), getUTCMonth() and getUTCFullYear().
    – tomlogic
    Commented Feb 17, 2013 at 17:35
  • 1
    @tomlogic has a good point, here is much cleaner code using his method: function normalizeDate(dateVal){ var convertedDate = new Date(dateVal); convertedDate = new Date(convertedDate.getUTCFullYear(), convertedDate.getUTCMonth(), convertedDate.getUTCDate()); return convertedDate; } Sorry for the formatting, it doesn't work well in comments. Commented Mar 18, 2014 at 22:29
9

IMHO better to keep the API clean and marshall on the client. Dates go on the wire as UTC doubles.

When you receive the dates:

var date = new Date(object.CustomField__c); //CustomField__c is 1360108800000

When you transmit the dates:

var object = {CustomField__c: new Date('February 15, 2013 15:00:00').getTime()}
1
  • 2
    +1 -- you'll run into fewer problems passing dates between Apex and Javascript in UTC (which it does by default) than by trying to adjust for timezone. Let the web browser apply the user's time zone to displaying the DateTime.
    – tomlogic
    Commented Feb 17, 2013 at 17:34
0

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_datetime.htm

Have a look at time Zone methods .In apex there are options to return the Date-time in GMT

By default the Time returned is in the form of your Local in the UI while in salesforce its stored in GMT

Datetime input field cast to another timezone

The above thread we discussed on it and you may find it helpful

TimeZone tz = UserInfo.getTimeZone();
System.debug('Display name: ' + tz.getDisplayName());
System.debug('ID: ' + tz.getID());
System.debug('Offset: ' + tz.getOffset(DateTime.newInstance(2012,10,23,12,0,0)));
// Not during daylight saving time for the America/Los_Angeles time zone
 System.debug('Offset: ' + tz.getOffset(DateTime.newInstance(2012,11,23,12,0,0)));
  System.debug('String format: ' + tz.toString());

Salesforce recently in API 27.0 launched Time Zone methods and that may be helpful also .I have added snippet above .

0
0

What are you doing with the Date object in Javascript once it's been created? How are you converting it to a string to insert into the field?

Have you looked at the methods available on the Date object?

Could you make use of getUTCMonth(), getUTCDate(), and getUTCFullYear()?

As long as you use the UTC methods when displaying and creating your Date objects, you should be OK.

0

Just as a followup to the question--

We've taken to including moment.js anytime we'll be dealing with dates or times in javascript.

Then this is the magic function to add:

function timeZoneShift(d){
    return moment(d).add('minutes', moment(d).zone()).toDate();
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .