How to get the last business day of the month?

Asked

Viewed 7,424 times

11

Is there a reliable Brazilian library of holidays that we can integrate and get the last working day of some month?

Anyway, if there is no such library, how could I get the last weekday of any month? (Formatted in a Calendar or a Date.)

Example of code required

Calendar hoje = Calendar.getInstance();
Calendar ultimoDiaUtil = getUltimoDiaUtil(hoje);
  • 3

    You can get the last day of the month by adding -1 day to a date representing the first day of the following month. And if you want the last day of the week, just go back to the days until you find a Friday (if the last day is no longer). In a maximum of two iterations you get the desired day.

  • 1

    It should be simple to keep a configuration file (an XML maybe) with national and state holidays. In the interaction @Renan mentioned, just ignore the dates that fall on a configured holiday. Reliable sources of holiday information are 1 and 2.

  • @Renan your solution is very good, since the author does not need to consider the holidays, because it does not implement it?

  • @Math because I am a zero left in Java and do not know the date and time types of the framework. If it were . NET or Javascript I could help more. If anyone wants to give a full answer below with my idea, feel free :)

3 answers

12


You can get the last day of the month by adding -1 day to a date representing the first day of the following month. And if you want the last day of the week, just go back to the days until you find a Friday (if the last day is no longer). In a maximum of two iterations you get the desired day.

It works as long as you don’t consider the holidays.

If you want to consider the holidays, simply blot them out and add one more condition in the loop by checking if the date is not a holiday, if it is a holiday continue to decrease until the condition is not met and falls outside the while.

Implementing @Renan’s idea plus the part of code that checks whether it’s a holiday:

public static void main(String[] args) {
    DateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/YYYY");
    Calendar hoje = Calendar.getInstance();
    Calendar ultimoDiaUtilDoMes = getUltimoDiaUtilDoMes(hoje);
    System.out.println(DATE_FORMAT.format(ultimoDiaUtilDoMes.getTime()));
}
public static Calendar getUltimoDiaUtilDoMes(Calendar calendar) {
    //muda a data da variável para o último dia do mês
    calendar.add(Calendar.MONTH, 1);  
    calendar.set(Calendar.DAY_OF_MONTH, 1);  
    calendar.add(Calendar.DATE, -1);
    //enquanto for sábado, domingo ou feriado
    while(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY ||
            calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY || 
            ehFeriado(calendar)) {
        //decrementa a data em um dia
        calendar.add(Calendar.DATE, -1);            
    }
    return calendar;
}
public static boolean ehFeriado(Calendar calendar) {
    Calendar feriado = Calendar.getInstance();
    //considerando 30 de abril como feriado
    feriado.set(calendar.get(Calendar.YEAR), Calendar.APRIL, 30);
    if(calendar.get(Calendar.DAY_OF_YEAR) == feriado.get(Calendar.DAY_OF_YEAR)) {
        return true;
    }
    else {
        return false;
    }
}

Returns:

29/04/2014

'Cause my code says today’s a holiday, so it showed yesterday’s date.

For the comparison made in the code:

calendar.get(Calendar.DAY_OF_YEAR) == feriado.get(Calendar.DAY_OF_YEAR)

working out it is necessary that the holiday year be set as the same year of the date it will compare, so:

feriado.set(
    calendar.get(Calendar.YEAR), //ano de feriado igual ao ano de calendar
    Calendar.APRIL, //constante estática da classe Calendar
    30);

for the calendar.get(Calendar.DAY_OF_YEAR) returns a integer that says what is the day of that year, so if it is set April 30 of a year any would give difference of a day if compare the date of a leap year with the same date of a non-leap year.

To consider the holidays whose date varies from year to year one must discover the account that is made and implement it for example in a method ehFeriadoQueVaria() and add it to while().

Edition for future reference:

Schedule of Holidays made available by Google in format XML.

  • Não me lembro de nenhum feriado que vai no final do mês Carnival and holy week can fall at the end of the month. New Year’s Eve as far as I remember is an optional holiday in Brazil. And the way things are going, Halloween (October 31) is soon a holiday. These are the national ones - there may still be state or municipal holidays that fall on the last day of the month. Other than that, +1

  • @Renan you deserve half the points I earn, rsrs.. I’ll edit. PS: as far as I know New Year’s Eve is not a holiday, January 1st it is. Really carnival and regional holidays can be a problem.

  • @Renan in fact carnival is only holiday in Rio and Bahia, in the rest of the country is optional, holy week is even holiday, and varies from year to year, it would take a beautiful of an account (if there is one) to calculate them. Regional holidays usually do not change date, so it would be no problem.

  • Carnival and holy week are based on the moon. They seem random, but it is a known account. I can confirm that Mardi Gras is a holiday in every state in the Northeast, as far as I know. Originally it was a Catholic holiday and was one of the few that the dictatorship could not remove from the official calendar in past ages, to get an idea of its importance...

  • 1

    @Renan I can say that carnival is not a holiday in SP, because I’ve worked in carnival and I won nothing else for it, rs..

  • Very interesting guys. Really the idea of this iteration made the calculation really fast. And the idea of putting in an XML is a good one too. I think it doesn’t pay to be tempted to make calculations to find... I think it is better for each year to add a file with the same information...

  • People, taking advantage of the interesting ideas of this post, I found an agenda that I would say to be reliable, with the holidays of Brazil (national only) already in XML. The agenda provided by Google. If it was necessary to add regional holidays, simply download the file, import it into a custom schedule and then export it again. Missing methods to read XML and retrieve information...

Show 2 more comments

-2

Calendar c = Calendar.getInstance();
    //alterar para o mes de abril
    c.set(Calendar.MONDAY, Calendar.APRIL);
    //pega o ultimo dia do mes de abril
    int ultimoDia =c.getActualMaximum(Calendar.DAY_OF_MONTH);
  • 1

    and to catch the last working day?

-2

Not to follow too large and complex codes, I suggest, this code made by me, and you suggest to follow the tutorials on the Oracle site itself!

import java.time.LocalDate;

public class testee {

    public static void main(String[] args) {
        System.out.println("primeiro dia do mês: " + principioDoMes(LocalDate.now()));
        System.out.println("ultimo dia do mês: " + fimDoMes(LocalDate.now()));
    }

    private static LocalDate principioDoMes(LocalDate l) {

        String local = l.toString();
        int ano = Integer.parseInt(local.split("-")[0]);
        int mes = Integer.parseInt(local.split("-")[1]);

        return LocalDate.of(ano, mes, 1);
    }

    private static LocalDate fimDoMes(LocalDate l) {
        return principioDoMes(l.plusMonths(1)).minusDays(1);
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.