2
votes

Currently trying to filter my data array by week, I have been able to filter by day quite easily however am struggling with dates between x and y (eg by week).

I have tried setting a start date and end date (today) and then trying to return the dates less than or equal to the start and end dates but am failing.

Data array date format: dd/mm/yyyy (01/01/2000)

The user will select which filter to use (hence switch() ) case 7 being filter by 7 days.

computed: {
    appointments: function () {

      var today = new Date();
      var dd = String(today.getDate()).padStart(2, '0');
      var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
      var yyyy = today.getFullYear();


      var data = this.$store.state.appointments;

      this.filter1_color = "grey";
      this.filter2_color = "grey";

      switch (this.dateFilter) {
        case 0:
        break;

        case 1:
        console.log("case1: " + today)
        return data.filter(word => word.date == today);

        case 7:

        /// WORKING /// (ex. edit)
        var week = [];

        var today = moment();
        var sevenDaysBefore = today.subtract(7, 'days');

        for (var i = 0; i < data.length; i++) {
          let momentDate = moment(data[i].date, 'DD/MM/YYYY')
          let newDate = momentDate.format("DD/MM/YYYY")
          if (momentDate.isBetween(sevenDaysBefore, moment(), null, '[]')) week.push(data[i]);
        }


        return week
        ///

      }


      return data;
    },

I need to filter the data to only show items in the array with dates equal to the dates in the last 7 days.

2
Can you use a library like moment js?f-CJ
@f-CJ I can, I just installed it and it looks handy dandy - still need to find a solution though.Tim Rowley
Yes it is. You need to get as result all the appointments that are in this week or just in the last 7 days?f-CJ
@f-CJ Just last 7 days is what I am trying to do.Tim Rowley

2 Answers

5
votes

You can use method isBetween of moment js library with current date. You can subtract 7 days to current date with subtract(7, 'days').

You can check more about isBetween method in moment js library documentation. The third parameter of the method is the granularity, and it seems that in your case it should 'days'

const today = moment();
const sevenDaysBefore = moment().subtract(7, 'days');

console.log('Today is ' + today.format('MMM Do YYYY'));
console.log('Is ' + today.format('MMM Do YYYY') + ' included in the last seven days?');
console.log(today.isBetween(sevenDaysBefore, today, 'day', '[]'));

console.log('Is ' + sevenDaysBefore.format('MMM Do YYYY') + ' included in the last seven days?');
console.log(sevenDaysBefore.isBetween(sevenDaysBefore, today, 'day', '[]'));

const eightDaysBefore = moment().subtract(8, 'days');
console.log('Is ' + eightDaysBefore.format('MMM Do YYYY') + ' included in the last seven days?');
console.log(eightDaysBefore.isBetween(sevenDaysBefore, today, 'day', '[]'));

const oneDayAfter = moment().add(1, 'days');
console.log('Is ' + oneDayAfter.format('MMM Do YYYY') + ' included in the last seven days?');
console.log(oneDayAfter.isBetween(sevenDaysBefore, today, 'day', '[]'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
1
votes

If you don't want to or cannot use a library like moment.js, and also don't mind an ad-hoc implementation with certain restrictions:

Note

I recommend to use a library for working with Date objects, especially when it comes to parsing a string to a date. Too many things can go wrong when doing it by hand. If possible, use the answer of @f-CJ

These parts allow you to create a Date object from a string. However, the resulting Date is always converted to local time and the string needs to have a certain formatting (the one you showed in your question). If you need support for UTC, this won't work. Also, it cannot be used to parse a date string with ISO formatting.

const OFFSET_TO_UTC = new Date().getTimezoneOffset();

function parseDateString (dateString, sep) {
  var parts = dateString.split(sep);
  return parts.map(n => Number(n));
}

function localizeDate (pattern, parts) {
  return pattern.reduce((acc, pat, i) => {
    switch (pat) {
      case 'd':
        return Object.assign(acc, { day: parts[i] });
      case 'm':
        return Object.assign(acc, { month: parts[i] });
      case 'y':
        return Object.assign(acc, { year: parts[i] });
      default:
        return acc;
    }
  }, {});
}

function toDate (localized) {
  return new Date(
    localized.year,
    localized.month - 1,
    localized.day,
    0, 0 - OFFSET_TO_UTC, 0);
}

function parseDate (pattern, sep, dateString) {
  return toDate(localizeDate(pattern, parseDateString(dateString, sep)));
}


// try it:

const dStringUS = '04/04/2019'; // mm/dd/yyyy
const dStringDE = '04.04.2019'; // dd/mm/yyyy

const dateUS = parseDate(['m', 'd', 'y'], '/', dStringUS);
const dateDE = parseDate(['d', 'm', 'y'], '.', dStringDE);

console.log(dateUS);
console.log(dateDE);

Based on it, you can write yourself a generic filtering function:

const OFFSET_TO_UTC = new Date().getTimezoneOffset();

function parseDateString (dateString, sep) {
  var parts = dateString.split(sep);
  return parts.map(n => Number(n));
}

function localizeDate (pattern, parts) {
  return pattern.reduce((acc, pat, i) => {
    switch (pat) {
      case 'd':
        return Object.assign(acc, { day: parts[i] });
      case 'm':
        return Object.assign(acc, { month: parts[i] });
      case 'y':
        return Object.assign(acc, { year: parts[i] });
      default:
        return acc;
    }
  }, {});
}

function toDate (localized) {
  return new Date(
    localized.year,
    localized.month - 1,
    localized.day,
    0, 0 - OFFSET_TO_UTC, 0);
}

function parseDate (pattern, sep, dateString) {
  return toDate(localizeDate(pattern, parseDateString(dateString, sep)));
}



const data = [{
  value: 0,
  date: '04/05/2019'
}, {
  value: 1,
  date: '04/07/2019'
}, {
  value: 2,
  date: '03/07/2019'
}];

function filterByDatePattern (pattern, sep) {
  return function (date, list) {
    return list.filter(item => {
      var itemDate = parseDate(pattern, sep, item.date);
      return itemDate >= date;
    });
  }
}

const onlyUSUntil = filterByDatePattern(['m', 'd', 'y'], '/');
console.log(onlyUSUntil(new Date(2019, 3, 1), data));