0

OK lets say I have a string that changes everyday that contains the date in it

var receiveddate = "Received on Saturday 14th of July 2018"

how do I extract the date out of it to example formatreceiveddate = "2018-07-14"

I know the other way around is to use string interpolation and template literals but not how to reverse it

So what I really is asking how to transform this

Received on Saturday 14th of July 2018
Received on Saturday 5th of May 2018
Received on Monday 8th of January 2018
Received on Wednesday 19th of July 2017
Received on Sunday 1st of July 2018
Received on Tuesday 3rd of July 2018
Received on Saturday 2nd of June 2018
Received on Thursday 21st of June 2018
Received on Thursday 31st of May 2018 

into this 2018-07-14 for each date.

user3277530
  • 351
  • 6
  • 14

4 Answers4

2

There may be a more elegant way than this, but this is the first thing that came to mind. Split the string up and make a date object with it.

const dateString = "Received on Saturday 14th of July 2018";

// Split the string up by spaces
const dateParts = dateString.split(' ');

// Grab each part of the date. We parse the day as an int to just get the numeral value
const month = dateParts[5];
const day = parseInt(dateParts[3]);
const year = dateParts[6];

// Parse the date by reassembling the string
const date = new Date(month + ' ' + day + ' ' + year);

// Output in your desired format (ISO)
const formattedDate = date.getFullYear()+'-' + (date.getMonth()+1) + '-'+date.getDate();

console.log(formattedDate);
Jordan Soltman
  • 3,795
  • 17
  • 31
  • See https://stackoverflow.com/questions/25159330/convert-iso-date-to-date-format-yyyy-mm-dd-format-in-javascript if you need that leading 0 for the month. – Jordan Soltman Jul 15 '18 at 05:11
  • this one worked and yes with the help the leading 0 in the link you gave, and I also didnt need the last part since const date = new Date(month + ' ' + day + ' ' + year); already gaved me the date in the format I need I only needed to use formattedDate = date.toISOString().substring(0, 10); instead of const formattedDate = date.getFullYear()+'-' + (date.getMonth()+1) + '-'+date.getDate(); to remove the time and seconds and it had the leading 0 – user3277530 Jul 16 '18 at 03:29
  • This is absolutely wrong and not guaranteed to produce correct result. Use longer date constructor (`new Date(year, month, day`). – Salman A Jul 16 '18 at 20:22
1

If you're okay with using a third-party library, moment makes this incredibly simple:

let dtStr = moment(
   "Received on Saturday 14th of July 2018",
   "[Received on] dddd Do [of] MMMM YYYY"
).format("YYYY-MM-DD");
// dtStr = "2018-07-14"

As per the documentation, the moment constructor takes the input date as the first argument, and an optional format string as the second argument. A quick breakdown of the format string:

  • the square brackets denote escaped text
  • dddd full day of the week text
  • Do day of the month, with postfix modifier (st, th, etc.)
  • MMMM full month text
  • YYYY 4 digit year

Output format follows the same rules, which can be found here. I would only recommend this approach compared to the other answers here if you plan on doing additional time computations. Otherwise, importing a library is likely overkill!

treyhakanson
  • 4,611
  • 2
  • 16
  • 33
0

The 'string approach' with a regex is is perhaps naive compared to using actual Date objects, but it's pretty simple:

var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var regex = /received on \w+ (\d+).*?of (\w+) (\w+)/ig;
    var result;
    while (result = regex.exec(input)) {
      var month = months.indexOf(result[2]) + 1;
      console.log(result[3] + "-" + month + "-" + result[1]);
    }

//with zero-padding
var input = `Received on Saturday 14th of July 2018
Received on Saturday 5th of May 2018
Received on Monday 8th of January 2018
Received on Wednesday 19th of July 2017
Received on Sunday 1st of July 2018
Received on Tuesday 3rd of July 2018
Received on Saturday 2nd of June 2018
Received on Thursday 21st of June 2018
Received on Thursday 31st of December 2018`

var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
var regex = /received on \w+ (\d+).*?of (\w+) (\w+)/ig;
var result;
while (result = regex.exec(input)) {
  var month = months.indexOf(result[2]) + 1;
  month = /\d{2,}/.test(month) ? month : "0" + month;
  var day = result[1];
  day = /\d{2,}/.test(day) ? day : "0" + day;
  console.log(result[3] + "-" + month + "-" + day);
}
Scott Weaver
  • 7,192
  • 2
  • 31
  • 43
0

You can look for the date pattern, get the the values and use them to create a date. It's good to make the parse as least reliant on the overall string as you can so that changes are tolerated to some extent.

The following just looks for the date part at the end of the string (e.g. 14th of July 2018), it doesn't matter what the first part is. It will even tolerate a string that is just a date like "14 July 2018". E.g.

function parseString(s) {
  var months = 'jan feb mar apr may jun jul aug sep oct nov dec'.split(' '),
      parts  = s.match(/(\d+)(st|rd|th)?( ?\w*) ([a-z]+) (\d{4})$/i) || [],
      day    = parts[1],
      month  = (parts[4] || '').toLowerCase().slice(0,3),
      year   = parts[5];

  return new Date(year, months.indexOf(month), day);
}

[ 'Received on Saturday 14th of July 2018',
  'Received on Saturday 5th of May 2018',
  'Received on Monday 8th of January 2018',
  'anything you like, even War and Peace 19th July 2017',
  '31 December 2012',
  'Totally invalid string'
].forEach(s => {
  var d = parseString(s);
  console.log(isNaN(d)? d : d.toString());
});

There's a bit of error handling incase match doesn't find a match and returns null.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • Would the down voter care to explain their vote? Then I can consider the criticism and hopefully improve future answers. – RobG Jul 16 '18 at 01:51