Convert JavaScript DateTime to UTC with no milliseconds

Ectropy picture Ectropy · Jun 11, 2014 · Viewed 9.1k times · Source

Right now I'm trying to parse a date that's written in a human-readable format into a DateTime String that a SharePoint list will accept. In order to do this I've determined that I need a String in a format similar to ISO that looks like: 2007-08-20T00:00:00Z. It seems that SharePoint only accepts DateTimes that are in UTC with no milliseconds included (for whatever reason, SharePoint gives errors and won't accept the DateTime when you include the milliseconds), so I need to convert my local time into a UTC time before converting it to the ISO string.

Here's the process that the code below is using.

  1. First I use DateJS to parse my human-date into a JavaScript Date. (Works fine, but apparently DateJS has been abandoned, so maybe I should change this to use MomentJS.)
  2. Next I tried to create a new moment in UTC. (This line is very, very wrong, and crashes my program.)
  3. Then I have SPServices convert it into an ISO. SPServices drops the milliseconds off the DateTime so that SharePoint will accept it. (Works fine).

I'm sure there has to be a more elegant/working way to achieve this, instead of stitching together 3 different libraries. I'm just not sure what it is.

var jScriptStartDate = Date.parse("6/29/2014 8:30am"); //JS Date
var jScriptStartDateUTC = moment(jScriptStartDate).utc(); //local date to UTC.
var startDate = $().SPServices.SPConvertDateToISO({ //Sharepoint ISO 8601 format
   dateToConvert: jScriptStartDateUTC,
   dateOffset: "" //Sharepoint dates only accept UTC times, aka no dateOffset.
});
newItem.set_item('EventDate', startDate); //EventDate is internal for StartTime

Answer

Matt Johnson-Pint picture Matt Johnson-Pint · Jun 12, 2014

You can just use moment.js, and this is all in the documentation.

moment('6/29/2014 8:30am','M/D/YYYY h:mma').toISOString()

This assumes all of the following:

  • The source value is in the user's time zone (that is - the time zone of the machine where the JavaScript code is running)

  • The input will always be in the specified format

It's also worth mentioning that if you put a space before the "am", that most modern browsers can do this natively without any library:

new Date('6/29/2014 8:30 am').toISOString()

If you take that approach, realize that the date parts are ordered according to the users locale, which might be m/d/y, or d/m/y or y/m/d.

Also, you said in the title "... with no milliseconds", but didn't elaborate on that in your question. I'm fairly certain you can pass the milliseconds without issue. There's no good reason to go out of your way to remove them. But if you must, then that would be like this with moment:

moment('6/29/2014 8:30am','M/D/YYYY h:mma').utc().format('YYYY-MM-DD[T]HH:mm:ss[Z]')