0

I have an array of objects "mainData" like so:

0: {date: "2020-07-25T16:44:43.000Z"
description: "Qwerty"
id: 89329972},
1: {date: "2020-07-25T16:46:28.000Z"
description: "Place bins please"
id: 65586316},
2: {date: "2020-07-25T16:49:12.000Z"
description: "Solve sewerege problem"
id: 84687816},
3: {date: "2020-07-27T16:34:47.000Z"
description: "Test compl"
id: 56437370},
4: {date: "2020-07-28T08:40:34.000Z"
description: "Sewerage problem in my area"
id: 92402221},
5: {date: "2020-09-09T11:42:18.000Z"
description: "problem"
id: 25613902},

Now I am allowing the user to select from and to dates by using the mui datepicker. This is how I am receiving the values:

fromDate: Sat Jul 25 2020 11:43:00
toDate: Sat Aug 08 2020 11:43:00

Now I want to filter the array from this date to that date, including the from and to dates. I tried to do it this way but it just returns an empty array. I've put the code inside useEffect which is run every time toDate changes, Also I've used Moment to make the formats of both dates same:

 useEffect( () => {
        if (fromDate !== null && toDate !== null) {
            setReportData(
                mainData.filter(
                    (obj) =>{
                        

                        return Moment(obj.date).format("DD MMM yyyy") >= Moment(fromDate).format("DD MMM yyyy") && Moment(obj.date).format("DD MMM yyyy") <= Moment(toDate).format("DD MMM yyyy")
                    }


                )
            )

           

        }

    },[toDate])

Edit

When I select a single date :

 useEffect( () => {
        if (oneDate !== null) {

            setReportData(
                mainData.filter(
                    (obj) =>{
                   

                        return new Date(obj.date.substring(0, 19)).getTime() === oneDate.getTime()
                    }


                )
            )

        }

    },[oneDate])

2 Answers 2

2

Your object's date property can be parsed directly to Date object. So then you can use getTime. Also, filter returns Date object.

So, you can change your code to this

 useEffect( () => {
    if (fromDate !== null && toDate !== null) {
        setReportData(
            mainData.filter(
                (obj) =>{
                    return new Date(obj.date).getTime() >= fromDate.getTime() && new Date(obj.date).getTime() <= toDate.getTime()
                }
            )
        )
    }

},[toDate])

If you want to consider all dates to be of local timezone, then you need to remove the last part of each date's string in order for the parse method to consider each string as local timezone date.

So previous method becomes

 useEffect( () => {
    if (fromDate !== null && toDate !== null) {
        setReportData(
            mainData.filter(
                (obj) =>{
                    return new Date(obj.date.substring(0, 19)).getTime() >= fromDate.getTime() && new Date(obj.date.substring(0, 19)).getTime() <= toDate.getTime()
                }
            )
        )
    }

},[toDate])
Sign up to request clarification or add additional context in comments.

23 Comments

ok wow this worked, but one tiny problem, it didn't return the object on the value of toDate. Although there was on object on that date in the array. Can you please tell me why?
which object and what toDate?
like for example I chose fromDate 25th and toDate 9th , it should return me an array of size 6 , but instead it returns me an array of size 5 . You may refer to the mainData array in my qs.
ok then try console.log after your if statement to see what each property has and how it is compared to the filters.
hmmm I think it has to do with the time zone, because new Date("2020-07-25T16:44:43.000Z") for example will return a different date object (and time) depending on your timezone, so maybe it is correct because that object may seem to have time included in your search criteria, but that time when converted into your local timezone, will be out of your date criteria boundaries.
|
0

We can use moment.js too. By converting the moment to expected format.

In above case we have Sat Jul 25 2020 11:43:00

Moment provides locale support format using llll, which is similar to this one, usage as follow. Initialize the format constant somewhere at top, after if statement;

const format = 'llll';

And just replace the filter return statement with :

return Moment(obj.date, format).unix() >= Moment(fromDate, format).unix() && Moment(obj.date, format).unix() <= Moment(toDate, format).unix()

2 Comments

this isnt working when I try to match a single date.
Seems like that was later edit to the question @Aldor. Can you help me in providing the format output date of oneDate, so that I add up in above answer to make it useful for feature read.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.