Patrick
Patrick

Reputation: 463

convert various date formats to yyyy-mm-dd in javascript

I want to be able to convert various date formats to a single format, i.e.to yyyy-mm-dd , so for example:

20-10-1975 -> 1975-10-20 (dd-mm-yyyy -> yyyy-mm-dd) 

01-25-1961 ->1961-01-25 (mm-dd-yyyy -> yyyy-mm-dd) 

1991-10-25 -> 1991-10-25 (yyyy-mm-dd remains yyyy-mm-dd)

if possible also with the time component, so for example:

20-10-1975 13:15:22 -> 1975-10-20 13:15:22

The reason is I want to be able to sort an array on dates, but sometimes I have to deal with various formats which I don't control.

Is there a function to achieve this?

PS I am aware that sometime a date can be ambiguous, for example 6-5-2015 can be 6th of May, or 5th of June, but I am fine with this as long as the sorting works.

Upvotes: 1

Views: 1222

Answers (1)

Quentin Roy
Quentin Roy

Reputation: 7887

You can have a look at Intl.DateTimeFormat. It may help you but having never used it, I cannot help you with this.

For simple cases, you can do it manually with the help of strings' split. You will have to implement your parser for each different format you want to use though. Here is a simple example. I chose to pass by a Date to make parsing and formatting independent but you may choose to just reorder the parts.

function parse(dateString){
  var parts = dateString.split("-");
  return new Date(parts[2], parts[1], parts[0]);
}

function format(date){
  var month = date.getMonth();
  var day = date.getDay();
  return [
    date.getFullYear(),
    month > 9 ? month : "0" + month,
    day > 9 ? day : "0" + day
  ].join("-");  
}

var date = parse("20-10-1975");
console.log(format(date));

However, I would recommend to use a library which can save you some time and give you greater flexibility at the cost of an additional dependency. One of the most famous libraries to manipulate dates, for example, is moment.js. Here is an example how you can use it.

var ex1 = moment("20-10-1975", "DD-MM-YYYY")
  .format("YYYY-MM-DD");
console.log(ex1);

var ex2 = moment("01-25-1961", "MM-DD-YYYY")
  .format("YYYY-MM-DD");
console.log(ex2);

var ex3 = moment("1991-10-25", "YYYY-MM-DD")
  .format("YYYY-MM-DD");
console.log(ex3);

var ex4 = moment("20-10-1975 13:15:22", "YYYY-MM-DD HH:mm:ss")
  .format("YYYY-DD-MM HH:mm:ss");
console.log(ex4);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>

If you want to try to match to multiple formats (as it seems to be your case), you can also do this. Just provide the order at which momentjs should try to recognise your string. Here is an example.

function formatDate(dateStr, inputFormats, outputFormat){
  // Format without the hours, minutes and seconds.
  inputFormats = inputFormats || [
    "YYYY-MM-DD",
    "DD-MM-YYYY",
    "MM-DD-YYYY"
  ];
  outputFormat = outputFormat || "YYYY-MM-DD";
  
  // Try to match without the hours, minutes and seconds.
  var mDate = moment(dateStr, inputFormats, true);
  if(mDate.isValid()){
    // If that worked, give the result without them.
    return mDate.format(outputFormat);
  }
  
  // Create format with hours, minutes and seconds.
  var extendedInputFormats = inputFormats.map(function(f){
    return f + " HH:mm:ss";
  });
  // Try to match with hours, minutes and seconds.
  mDate = moment(dateStr, extendedInputFormats, true);
  if(mDate.isValid()){
    // If that worked, give the result with them.
    return mDate.format(outputFormat + " HH:mm:ss");
  }
}

console.log("20-10-1975 =>", formatDate("20-10-1975"));
console.log("01-25-1961 =>", formatDate("01-25-1961"));
console.log("1991-10-25 =>", formatDate("1991-10-25"));
console.log("20-10-1975 13:15:22 =>", formatDate("20-10-1975 13:15:22"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>

Upvotes: 3

Related Questions