BluSky
BluSky

Reputation: 83

How to extract date from string using javascript

How does one extract a date from a string using javascript? It can be in the following formats:

31.07.2014

07.31.2014

2014.07.31 the same format but divided by spaces or / or - 31 07 2014 31/07/2014 31-07-2014

the string may contain other character like

Teen.Wolf.S04E06.Orphaned.28.07.2014.HDTV

so how to extract date from these type of name.

I thought of first extracting all the numbers and then comparing if it is greater than 12 to make sure it is month or date. I don't know much about regEx (Regular Expressions) so if it is used please explain a little thank you

Upvotes: 7

Views: 24374

Answers (6)

Jasper Cuvelier
Jasper Cuvelier

Reputation: 573

I had a similar usecase and I used and changed @lpg's answer to fit my needs. I needed to parse invoice dates that will have all sorts of date formats. I included an option to parse month names. As I live in Belgium, most dates are formatted dd-mm-yyyy or dd-mmmm-yyyy , so I assumed dates will most likely have this format. It's easy to swap parts of the regex to swap months and days. Some explanation is included in the comments of the code.

It's also easy enough to translate month names. Note: In dutch we don't use the format "may 3th 2023" so I didn't include this.

I ended up using this:

function parseStringedDate(d) {


  /*
  Valid separators => . - / *space* (dot dash slash and space)
  Detexted formats => 
  dd mm yyyy 
  d mm yyyy
  d m yyyy
  yyyy mm dd
  yyyy m d
  d mmmm yyyy
  mmmm d yyyy
  */


  // Object to map month names to numbers
  const monthsConfig = {
    "januari": 0,
    "februari": 1,
    "maart": 2,
    "april": 3,
    "mei": 4,
    "juni": 5,
    "juli": 6,
    "augustus": 7,
    "september": 8,
    "oktober": 9,
    "november": 10,
    "december": 11
  };

  var day, month, year, result, dateSplitted;

  // dd-mm-yyyy  || d-mm-yyyy || mm-dd-yyyy || m-d-yyyy || mm-d-yyyy || m-dd-yyyy
  result = d.match("[0-9]{1,2}([\-/ \.])[0-9]{1,2}[\-/ \.][0-9]{4}");
  if (null != result) {
    dateSplitted = result[0].split(result[1]);
    day = parseInt(dateSplitted[0]);
    month = parseInt(dateSplitted[1]) - 1;
    year = parseInt(dateSplitted[2]);
  }


  // yyyy-mm-dd || yyyy-mm-d || yyyy-m-dd || yyyy-m-d || yyyy-mm-d || yyyy-dd-m || yyyy-d-mm
  result = d.match("[0-9]{4}([\-/ \.])[0-9]{1,2}[\-/ \.][0-9]{1,2}");
  if (null != result) {
    dateSplitted = result[0].split(result[1]);
    day = dateSplitted[2];
    month = parseInt(dateSplitted[1]) - 1;
    year = dateSplitted[0];
  }

  // dd-mmmm-yyyy || d-mmmm-yyyy
  result = d.match("[0-9]{1,2}([\-/ \.])[a-zA-Z]{3,}[\-/ \.][0-9]{4}");
  if (null != result) {
    dateSplitted = result[0].split(result[1]);
    day = dateSplitted[0];
    month = monthsConfig[dateSplitted[1]]
    year = dateSplitted[2];
  }

  // mmmm-dd-yyyy
  result = d.match("[a-zA-Z]{3,}[\-/ \.][0-9]{1,2}([\-/ \.])[0-9]{4}");
  if (null != result) {
    dateSplitted = result[0].split(result[1]);
    month = monthsConfig[dateSplitted[0]]
    day = dateSplitted[1];
    year = dateSplitted[2];
  }


  day = parseInt(day)
  month = parseInt(month)
  year = parseInt(year)


  if (!day || month === undefined || !year) {
    throw new Error("Invalid date format...")
  }

  // If the month is larger then 11, it is not a month, but a day for sure. Swap variables...
  if (month > 11) {
    let aux
    aux = day;
    day = month;
    month = aux;
    month-- // what was tought to be a day, was actually a month, so we need to substract 1, as months are zero based.
    day++   // restore the day, we accidently changed the day -1 in the previous code because we tought it was a month.
  }


  const jsDate = new Date(year, month, day)

  if (!jsDate instanceof Date) {
    throw new Error("Invalid date format...")
  }

  return jsDate.toISOString().split('T')[0]

}

Upvotes: 0

Venkatesan
Venkatesan

Reputation: 178

RegEX will help you to extract date with Different Type of format and It returns as Array,

let str="dd/mm/yyyy06/06/2018 yyyy/mm/dd 2018/02/12 d/m/yy 1/1/18 dd/mm/yy 18/12/12 mm/d/yyyy 12/2/2018 m/dd/yyyy 1/12/2018 yy/m/d 18/1/1 yy/mm/d 18/12/1 yyyy/2018/1/1";
str.match(/(\d{1,4}([.\-/])\d{1,2}([.\-/])\d{1,4})/g);

Reference Link From regextester

Upvotes: 4

Jack C
Jack C

Reputation: 1084

function myFunction() {
    var str = "Teen.Wolf.Orphaned.28.07.2014.HDTV";
    var res = str.split(".");


    var text = "";
    var x;
    for (x in res) {
        if (!isNaN(res[x])) {
            text += res[x];
            if (text.length == 2) { text += ','} 
            else if (text.length == 5) { text += ',' } 
        }
    }

    document.write(text);
}

This will write "28,07,2014"

NOTE: only use this way if the strings will always be in a format similar to the ones you posted above.

Upvotes: 0

lpg
lpg

Reputation: 4937

Maybe this could help you (Demo Fiddle here):

function getDate(d)
{
    var day, month, year;

    result = d.match("[0-9]{2}([\-/ \.])[0-9]{2}[\-/ \.][0-9]{4}");
    if(null != result) {
        dateSplitted = result[0].split(result[1]);
        day = dateSplitted[0];
        month = dateSplitted[1];
        year = dateSplitted[2];
    }
    result = d.match("[0-9]{4}([\-/ \.])[0-9]{2}[\-/ \.][0-9]{2}");
    if(null != result) {
        dateSplitted = result[0].split(result[1]);
        day = dateSplitted[2];
        month = dateSplitted[1];
        year = dateSplitted[0];
    }

    if(month>12) {
        aux = day;
        day = month;
        month = aux;
    }

    return year+"/"+month+"/"+day;
}

Upvotes: 6

Vlad Cazacu
Vlad Cazacu

Reputation: 1540

I think you can use regex for this. The main three expressions that you need are the following:

[0-9]{4} // year
(0[1-9]|1[0-2]) // month
(0[1-9]|[1-2][0-9]|3[0-1]) // day

You can combine these to fit the formats you mentioned, for example, to match "31.07.2014":

(0[1-9]|[1-2][0-9]|3[0-1])\.(0[1-9]|1[0-2])\.[0-9]{4}

Or "31/07/2014":

(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\/[0-9]{4}

You can decide which formats you need and create one regex expression separating the formats with the OR operator |.

Upvotes: 1

Nick
Nick

Reputation: 156

probably use a regex like

/(\d{4}([.\-/ ])\d{2}\2\d{2}|\d{2}([.\-/ ])\d{2}\3\d{4})/

\d - a digit (equivilant to character class [0-9]
{n} - match n characters
[.\-/ ] - character class matches a single . - / or space (- needs to be escaped because it indicates a range in a character class
\n - a backreference matches the nth match so / will match another / and not a -, /, space or .

you can pull out the first part of the regex and inspect it, it is the same as the second part, except the 4 digits and 2 digits have been swapped

/\d{4}([.\-/ ])\d{2}\1\d{2}/

Upvotes: 8

Related Questions