How to find the nearest day of the week with date-fns
Asked Answered
L

3

9

I want to be able to find out the nearest Day of the week in the past based on the current date with date-fns. Say I need to find nearest Friday, Wednesday, Thursday etc in the past based on the current date.

I looked in to the documentation and can see only these tow methods https://date-fns.org/docs/closestTo and https://date-fns.org/v1.29.0/docs/getDay that I thought might help but the one I am looking for is missing.

Any thoughts?

Lamellar answered 11/1, 2019 at 7:54 Comment(0)
S
13

// use require or import in your code
// const { getISODay, addDays } = require("date-fns");
const { getISODay, addDays } = dateFns;

function getDayInPast(dayOfWeek, fromDate = new Date()) {
  // follow the getISODay format (7 for Sunday, 1 for Monday)
  const dayOfWeekMap = {
    Mon: 1,
    Tue: 2,
    Wed: 3,
    Thur: 4,
    Fri: 5,
    Sat: 6,
    Sun: 7,
  };

  // dayOfWeekMap[dayOfWeek] get the ISODay for the desired dayOfWeek
  const targetISODay = dayOfWeekMap[dayOfWeek];
  const fromISODay = getISODay(fromDate);

  // targetISODay >= fromISODay means we need to trace back to last week
  // e.g. target is Wed(3), from is Tue(2)
  // hence, need to -7 the account for the offset of a week
  const offsetDays =
    targetISODay >= fromISODay
      ? -7 + (targetISODay - fromISODay)
      : targetISODay - fromISODay;

  return addDays(fromDate, offsetDays);
}

console.log(getDayInPast("Mon"));
console.log(getDayInPast("Tue"));
console.log(getDayInPast("Wed"));
console.log(getDayInPast("Thur"));
console.log(getDayInPast("Fri"));
console.log(getDayInPast("Sat"));
console.log(getDayInPast("Sun"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.min.js"></script>

Thanks @giraff for pointing out the issue about offset in the previous version

Stucker answered 11/1, 2019 at 14:34 Comment(3)
Are you sure this is correct? For me, that gives sometimes a week to much in the past. E.g. Current day is Tuesday, looking for the Monday in the past -> offsetDay should be -1, not -8.Tasman
See my version below, you can edit it into your answer if you want.Tasman
@giraff, Thanks for pointing out. The answer was posted quite a while ago and I don't remember the thought at that moment. But judging from the function name, it seems that I interpreted the question as getting the day in the past week. I will modify the answer.Stucker
D
8
import { previousFriday } from 'date-fns';


console.log(previousFriday(new Date()));
Divvy answered 29/6, 2022 at 20:3 Comment(0)
P
0

A generic way to get any previous day using a Date object is to use date-fns' previousDay function (https://date-fns.org/v3.6.0/docs/previousDay). It takes a Date and date ordinal (i.e., 0-6, representing Sunday through Saturday to conform with the return value of Date.getDay() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay).

const { useState } = React;
const { previousDay } = dateFns;

const weekdays = [
  'Sunday',
  'Monday',
  'Tuesday',
  'Wednesday',
  'Thursday',
  'Friday',
  'Saturday',
];

const WeekdaySelect = () => {
  const [selectedDay, setSelectedDay] = useState(weekdays.indexOf('Friday'));
  const now = new Date();
  const selectedDayPrevious = previousDay(now, selectedDay).toUTCString();

  return (
    <div
      style={{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center'
      }}>
        <div>{selectedDayPrevious}</div>
        <div>
          {weekdays.map((weekday, i) => (
            <button
              key={weekday}
              type="button"
              onClick={() => setSelectedDay(i)}
              style={{
                margin: '0.2rem'
              }}
            >
              {weekday}
            </button>
          ))}
        </div>
    </div>
  );
};

ReactDOM.createRoot(
  document.getElementById("root")
).render(
  <WeekdaySelect />
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/cdn.min.js"></script>
<div id="root"></div>
Proselytism answered 18/8 at 10:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.