You need to firstly parse the string to get its components. You can then either generate a Date and use its methods to generate a suitable string, or you can manually reformat the string. Both approaches are very similar.
It's not clear to me why you want the timezone offset. You can get that independently, but if you just transfer all dates as UTC and ISO 8601 then you can just adopt the host timezone offset. If UTC is OK, then you just need to parse to a Date and use toISOString.
It's unusual to specify the time as "18:00pm", the pm part is redundant. Typically it would be specified as "1800hrs", "18:00" or "6:00 pm".
// Reformat string, using Date object for
// host timezone offset only
function reformatDate(s) {
function z(n){return ('0'+n).slice(-2)}
var b = s.match(/\d+|[a-z]+/gi);
var months = ['jan','feb','mar','apr','may','jun',
'jul','aug','sep','oct','nov','dec'];
var monNum = months.indexOf(b[1].substr(0,3).toLowerCase());
// Host timezone offset for given date and time
var tzOffset = new Date(b[2], monNum - 1, b[0], b[3], b[4]).getTimezoneOffset();
var tzSign = tzOffset > 0? '-' : '+';
tzOffset = Math.abs(tzOffset);
return b[2] + '-' +
z(monNum) + '-' +
b[0] + 'T' +
b[3] + ':' +
b[4] + tzSign +
z(tzOffset/60 | 0) + ':' +
z(tzOffset%60);
}
// Reformat string using Date object for
// parts and host timezone offset
function reformatDate2(s) {
function z(n){return ('0'+n).slice(-2)}
var b = s.match(/\d+|[a-z]+/gi);
var months = ['jan','feb','mar','apr','may','jun',
'jul','aug','sep','oct','nov','dec'];
var monNum = months.indexOf(b[1].substr(0,3).toLowerCase());
var d = new Date(b[2], monNum - 1, b[0], b[3], b[4]);
// Host timezone offset for given date and time
var tzOffset = d.getTimezoneOffset();
var tzSign = tzOffset > 0? '-' : '+';
tzOffset = Math.abs(tzOffset);
return d.getFullYear() + '-' +
z(d.getMonth() + 1) + '-' +
z(d.getDate()) + 'T' +
z(d.getHours()) + ':' +
z(d.getMinutes()) + tzSign +
z(tzOffset/60 | 0) + ':' +
z(tzOffset%60);
}
var s = '02 December 2016 18:00pm';
console.log(reformatDate(s));
console.log(reformatDate2(s));
As you can see, you're really only using a Date to get the timezone offset, the rest of the values can be used as-is except for the month, which must be converted to a number in both cases.
There are also a number of libraries that can help with parsing and formatting strings, such as moment.js (large, widely used, fully functional) and fecha.js (small and functional parser/formatter). In both cases you can parse the string and format it however you wish, e.g. using fecha.js:
var s = '02 December 2016 18:00pm';
// Create a Date
var d = fecha.parse(s, 'DD MMMM YYYY HH:mm');
// Format string
console.log(fecha.format(d, 'YYYY-MM-DDTHH:mmZZ'));
The parse and format can be one statement, but it's clearer as 2. With moment.js (which has better support for chaining methods):
moment(s, 'DD MMMM YYYY HH:mm').format('YYYY-MM-DDTHH:mmZZ');