Catching first and last date of the previous month

Asked

Viewed 3,878 times

3

I am using in Eclipse Selenium, for automatization of sending commands to a site, through JAVA files. On this site, I need to make a date query. I did so to test:

element = driver.findElement(By.name("form:dtEmissao_input"));
element.sendKeys("01/04/2016");
element = driver.findElement(By.name("form:emissFim_input"));
element.sendKeys("12/04/2016");

However, I wanted him to always take the first and last day of the previous month. How can I do that? Need to import some library into my JAVA file?

2 answers

1


You don’t need any external library! Here’s a possible solution

public static voi main(String[] args){
    Calendar c = Calendar.getInstance();
    Date d = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
    d = c.getTime();

    //subtrai 1 do mês atual para pegar o anterior
    c.add(Calendar.MONTH, -1);

    //seta primeiro dia do mês
    c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));
    d = c.getTime();
    System.out.println("Data do primeiro dia do mes passado: " + sdf.format(d));
    //seta ultimo dia do mês
    c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
    d = c.getTime();
    System.out.println("Data do ultimo dia do mes passado: " + sdf.format(d));
}

1

Using Java 8

In Java 8 this is trivial as it is part of the API.

LocalDateTime data = LocalDateTime.now();
LocalDateTime ultimoDiaDoMesAnterior = data.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
System.out.println(ultimoDiaDoMesAnterior.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));

Note that LocalDateTime does not consider time zone, so it is safer than using Date or Calendar.

Java <= 7

Using the Jodatime library

Very simple solution:

LocalDate ultimoDiaDoMesAnterior = date..minusMonths(1).dayOfMonth().withMaximumValue();

This is the recommended way for Java versions smaller than or equal to 7.

Using java.util.Calendar

With the old API it is customary to execute the operation of at least two ways.

The first is using Calendar to subtract a month and recover the last day of that month, thus:

Date data = new Date();
Calendar c = Calendar.getInstance();
c.setTime(data);
c.add(Calendar.MONTH, -1);
c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
System.out.println(new SimpleDateFormat("dd/MM/yyyy").format(c.getTime()));

The second is using Calendar to define the first day of the current month, then subtract a day to reach the end of the previous month, thus:

Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.DAY_OF_MONTH, 1);
c.add(Calendar.DAY_OF_MONTH, -1);
System.out.println(new SimpleDateFormat("dd/MM/yyyy").format(c.getTime()));

But beware of Calendar because you can easily incur spindle problems. Confusing?

Dangers of manipulating dates

It is not uncommon for user typed dates to end up with wrong values manipulated. The most classic example of this is due to daylight saving time.

Imagine your JVM is in the following pattern:

Locale.setDefault(new Locale("pt", "BR"));
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));

User entered the date 01/03/2016, represented by the line below:

Date entrada = new SimpleDateFormat("dd/MM/yyyy").parse("01/03/2016");

It is not uncommon for libraries to use date manipulation specifying a specific zone, thus:

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("America/Sao_Paulo"));
calendar.setTime(entrada);
calendar.add(Calendar.MONTH, -1);
System.out.println(new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(calendar.getTime()));

The problem in this case is that he doesn’t know that entrada was created with a Timezone other than what is being used in handling with Calendar.

So, contrary to expectations, 01/02/2016 00:00:00, the result is 29/01/2016 23:00:00. One hour "stolen" by daylight saving time.

Like Date does not store the time zone, there is no way to know with which time zone it was created and this can cause problems with several frameworks, even more in web systems. Some frameworks may assume a default fixed zone, others may assume the zone according to the location HTTP header information provided by the browser.

Anyway, the only safe way to use Calendar and Date is that all routines that do this specify the same Timezone and the same Locale in all operations. Libraries and frameworks must all be set to maintain the standard.

In the case of a web system with location support is already much more complicated, because each user can be in a different zone. The solution can be to convert everything to GMT or move the user zone to all routines that will handle dates.

Browser other questions tagged

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