0

I am trying to create a List of date type which contains every Friday of the month in it. So for example, for the month of March, the list would contain the dates of March 3rd, 10th, 17th, 24th and 31st. Is there any standard function that would calculate this for me? Or perhaps a standard object that I could query which is simply a calendar so I could use the date query functions? I am not looking for something like

DAY_IN_WEEK(CreatedDate) = 6

In which it would get every friday from a query, but simply a list of Fridays for that month regardless of querying an object.

3
4

While the other approaches listed here work, they are dependent on locale. I would prefer an approach that will work for anyone, anywhere, which you can do by comparing the month start to a known Sunday. For example:

static Date knownSunday = Date.newInstance(2017, 1, 1);
public static List<Date> getFridays(Integer year, Integer month)
{
    Date monthStart = Date.newInstance(year, month, 1);
    Integer daysAfterSunday = Math.mod(knownSunday.daysBetween(monthStart), 7);
    Date firstFriday = monthStart.addDays(5 - daysAfterSunday);
    if (firstFriday < monthStart)
        firstFriday = firstFriday.addDays(7);

    Datetime pointer = Datetime.newInstance(firstFriday, Time.newInstance(0,0,0,0));
    List<Date> fridays = new List<Date>();
    while (pointer.month() == month)
    {
        fridays.add(pointer.date());
        pointer = pointer.addDays(7);
    }
    return fridays;
}

You can test it out in Execute Anonymous with values for this year:

for (Integer month = 1; month < 13; month++)
    system.debug(JSON.serialize(getFridays(2017, month)));

["2017-01-06","2017-01-13","2017-01-20","2017-01-27"]

["2017-02-03","2017-02-10","2017-02-17","2017-02-24"]

["2017-03-03","2017-03-10","2017-03-17","2017-03-24","2017-03-31"]

["2017-04-07","2017-04-14","2017-04-21","2017-04-28"]

["2017-05-05","2017-05-12","2017-05-19","2017-05-26"]

["2017-06-02","2017-06-09","2017-06-16","2017-06-23","2017-06-30"]

["2017-07-07","2017-07-14","2017-07-21","2017-07-28"]

["2017-08-04","2017-08-11","2017-08-18","2017-08-25"]

["2017-09-01","2017-09-08","2017-09-15","2017-09-22","2017-09-29"]

["2017-10-06","2017-10-13","2017-10-20","2017-10-27"]

["2017-11-03","2017-11-09","2017-11-16","2017-11-23","2017-11-30"]

["2017-12-01","2017-12-08","2017-12-15","2017-12-22","2017-12-29"]

1
  • take a look at the latest answer here. I did some testing with your code using 2021, 2022, and 2023 and found that all three years computes the wrong dates for Fridays in November, leading to more Fridays depending on the year. I think using newInstanceGmt may be a better approach to avoid time zone and daylight savings causing a shift in date math but dates and times are always tricky. @user3709326 attempts to use 8AM as a way to avoid it (I think the assumption is no country has DST start or stop at that time) but I'm not confident it's accurate without seeing tests.
    – nbrown
    Oct 6 '21 at 21:44
2

Using this function:

public List<Datetime> fridaysInMonth(Integer month_no, Integer year_no) {
    List<Datetime> days_in_month = new List<Datetime>();
    Datetime d = Datetime.newInstance(Date.newInstance(year_no, month_no, 1), Time.newInstance(0, 0, 0, 0));
    Integer count = 0;
    while (count <= 31) {
        Datetime that_day = d.addDays(count);
        if (that_day.month() != month_no) {
            break;
        }

        // format('u') gives you the day in week (Friday being the day 5)
        if (that_day.format('u') == '5') {
            days_in_month.add(that_day);
        }

        count++;
    }
    return days_in_month;
}

System.debug(fridaysInMonth(3, 2017)); gives me the following result:

20:18:56:008 USER_DEBUG [27]|DEBUG|(2017-03-03 03:00:00, 2017-03-10 03:00:00, 2017-03-17 03:00:00, 2017-03-24 03:00:00, 2017-03-31 03:00:00)

Basically it will output only the dates you want. And of course you can change the code to get only the days, for example.

1
  • 1
    The format('u') is also locale dependent, so in some areas it should start from Sunday and others Monday. The documentation on Datetime.format implies as much, though I haven't tested it. Otherwise I do prefer this approach to the others listed.
    – Adrian Larson
    Mar 17 '17 at 0:00
0

I don't know of any true native methods to retrieve the list but you could do something like this:

List<Date> getFridays(Integer year, Integer month) {
  List<Date> toReturn = new List<Date>();
  DateTime checkDate = Date.newInstance(year, month, 1);
  DateTime endDate = checkDate.addMonths(1);
  while(checkDate < endDate){
    if(checkDate.format('E') == 'Fri'){
      toReturn.add(checkDate.date());
      checkdate = checkdate.addDays(7);
     } else {
      checkDate = checkDate.addDays(1);
     }
  }
  return toReturn; 
}
1
  • 1
    Locale dependent. This wouldn't work for someone whose language isn't English, for instance.
    – Adrian Larson
    Mar 16 '17 at 19:39
0

Don't have a high enough reputation to reply to the accepted answer, be careful of when Daylight savings time ends in November. For the calendar year 2023, the pasted solution will calculate 5 Fridays, when there are only 4.

The pointer variable is GMT 04:00:00 which is the previous day and throws off the calculation
Pointer = 2023-11-03 04:00:00
["2023-11-03","2023-11-09","2023-11-16","2023-11-23","2023-11-30"]

Pointer = 2023-12-01 05:00:00
["2023-12-01","2023-12-08","2023-12-15","2023-12-22","2023-12-29"]

I used a later hour in the day to prevent that, 8 in my example

Datetime pointer = Datetime.newInstance(firstFriday, Time.newInstance(8,0,0,0));

Pointer = 2023-11-03 12:00:00
["2023-11-03","2023-11-10","2023-11-17","2023-11-24"]
Pointer = 2023-12-01 13:00:00
["2023-12-01","2023-12-08","2023-12-15","2023-12-22","2023-12-29"]

It's a solid solution, with a small tweak

-1

you could loop through the dates of the month, using code from this link

https://developer.salesforce.com/forums/?id=906F00000008zOCIAY

Datetime dt = System.now();
System.debug(dt.format('EEEE'));
Will give you Friday
To get Fri - use dt.format('EEE'); 

see also this link which has a solution that just uses numbers: How Can I Tell the Day of the Week of a Date?

MOD(DATEVALUE( Date_Field__c ) - DATE(1985,7,1),7)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.