0

I have a date and time stamp in the format 02 December 2016 18:00pm.

This is generated by jQuery selector:

"datestamp": $('span.article_info__published').text(),

How can I convert it to the format 2007-07-24T12:50:00+01:00?

If possible, I'd like to do it on the same line. Otherwise it needs to accommodate this sort of construction...

result = {
    "other": $('div.article__header h1').text(),
    "datestamp": $('span.article_info__published').text(),
    "more": $('meta[name="twitter:image"]').attr("content"),
    "assorted": $('figcaption.caption').text(),
};

(I can't remember the name of the destination format... I think ISO 8601?)

Update: the following returns "invalid date"...

var myDate = new Date("02 December 2016 18:00pm");

document.write(myDate);
Salman A
  • 262,204
  • 82
  • 430
  • 521
Robert Andrews
  • 1,209
  • 4
  • 23
  • 47
  • The input date is not a Date object. – Robert Andrews Jul 08 '18 at 19:37
  • I have an answer to provide. It isn't the one linked. – Robert Andrews Jul 08 '18 at 20:54
  • I think the use of jQuery is obscuring your actual question. Selector "span.article_info__published" is not peculiar to jQuery, it's a standard CSS selector. What you should actually ask is how to transform the string "02 December 2016 18:00pm" to ISO 8601 format with the offset of the host system (though why you need the offset is not stated). – RobG Jul 08 '18 at 22:48
  • 1
    Are you sure it is `18:00pm` and not `06:00pm`? – Salman A Jul 08 '18 at 23:55
  • Possible duplicate of [Converting a string to a date in JavaScript](https://stackoverflow.com/questions/5619202/converting-a-string-to-a-date-in-javascript) – Heretic Monkey Jul 09 '18 at 00:15

2 Answers2

0

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');
RobG
  • 142,382
  • 31
  • 172
  • 209
0

For the string to be interpretable as a date for conversion, I needed to remove the time "pm" from the back of the string first.

var date = "02 December 2016 18:00pm"

date = date.slice(0, -2);

var myDate = new Date(date);

document.write(myDate);
Robert Andrews
  • 1,209
  • 4
  • 23
  • 47