Home > other >  Convert a list of dates to date range in Angular Using Moment Js
Convert a list of dates to date range in Angular Using Moment Js

Time:08-16

I am having a date list like below

let dates = ["2022-12-20", "2022-12-21", "2022-12-22", "2022-12-27", "2022-12-30","2022-12-31", "2023-01-01"];

I would like to convert the date array to a range of dates, as shown in the below output

let result = ["20 Dec - 22 Dec", "27 Dec 2022", "30 Dec - 1 Jan "];

Below is my code:

fun(dates)
{
    let startDate = this.dates[0], endDateIndex = - 1, finalDateString = "", arr = [];
    for (let i = 1; i < dates.length; i  ) {

        if (moment(startDate).add(i, 'days').format("YYYY-MM-DD") == moment(dates[i]).format("YYYY-MM-DD")) {
            endDateIndex = i;
        }
        else {
            finalDateString  = endDateIndex > 0 ? moment(startDate).format("DD MMM")   " - "  
                moment(dates[endDateIndex]).format("DD MMM") : '';
            if (endDateIndex == -1) {
                finalDateString = finalDateString   " "   moment(startDate).format("DD MMM")   ","
            }
            startDate = dates[i];
            endDateIndex = -1;
        }
    }
    arr.push(finalDateString);
    return arr;
}

In my code, I am getting the wrong result in the date range. Kindly guide me to build logic.

CodePudding user response:

You could reduce your dates into date ranges first:

[
  { "start": "2022-12-20", "end": "2022-12-22" },
  { "start": "2022-12-27" },
  { "start": "2022-12-30", "end": "2023-01-01" }
]

Then format the ranges afterwards.

const dates = [
  "2022-12-20", "2022-12-21", "2022-12-22",
  "2022-12-27",
  "2022-12-30", "2022-12-31", "2023-01-01"
];

const parseDate = (date) => moment(date, 'YYYY-MM-DD');

const pushOrSetEnd = (results, last, prev, curr) => {
  if (moment.duration(parseDate(curr).diff(parseDate(prev))).asDays() <= 1) {
      last.end = curr;
    } else {
      results.push({ start: curr });
    }
};

const reduceDatesIntoRanges = (dates) =>
  dates.slice(1).reduce((acc, date) => {
    const last = acc[acc.length - 1];
    pushOrSetEnd(acc, last, last.end ? last.end : last.start, date);
    return acc;
  }, [{ start: dates[0] }]);

const dateRanges = reduceDatesIntoRanges(dates);

const formatDateWithYear = (date) => parseDate(date).format('D MMM YYYY');

const formatDate = (date) => parseDate(date).format('D MMM');

const formatDateRange = ({ start, end }) => `${formatDate(start)} - ${formatDate(end)}`;

const formattedDateRanges = dateRanges.map(dateRange =>
  !dateRange.end ? formatDateWithYear(dateRange.start) : formatDateRange(dateRange));

console.log(formattedDateRanges);
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>

<!--

const expected = [
  "20 Dec - 22 Dec",
  "27 Dec 2022",
  "30 Dec - 1 Jan"
];

-->

CodePudding user response:

Maybe this will work for you

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
<script>
let dates = ["2022-12-20", "2022-12-21", "2022-12-22", "2022-12-27", "2022-12-30","2022-12-31", "2023-01-01"];
let expectedResult = ["20 Dec - 22 Dec", "27 Dec 2022", "30 Dec - 1 Jan "];

function organizePeriods(dates) {
    let startDate = dates[0], endDateIndex = - 1, finalDateString = "", arr = [], periodLength = 1;
    for (let i = 1; i < dates.length; i  ) {
      if (moment(startDate).add(periodLength, 'days').format("YYYY-MM-DD") === moment(dates[i]).format("YYYY-MM-DD"))  {
        periodLength  ;
        endDateIndex = i;
        if (i < dates.length - 1) {
          continue
        }
      }
      if (endDateIndex > 0) {
          finalDateString = moment(startDate).format("DD MMM")   " - "   moment(dates[endDateIndex]).format("DD MMM");
        } else if (endDateIndex === -1) {
          finalDateString = moment(startDate).format("DD MMM")
        }
        arr.push(finalDateString);
        startDate = dates[i];
        endDateIndex = -1;
        periodLength = 1;
        finalDateString = ""
    }
    return arr;
}

console.log("result", organizePeriods(dates));
console.log("expected result", expectedResult);
</script>

  • Related