Home > Net >  How to get previous month from current month in java?
How to get previous month from current month in java?

Time:10-15

I have following scenario.

String currentMonth = SEP/2021

Here I want String previous month = AUG/2021.

How can I achieve this in java?

CodePudding user response:

java.time

You can use the java.time API to do it.

import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .parseCaseInsensitive()
                                .appendPattern("MMM/uuuu")
                                .toFormatter(Locale.ROOT);

        String currentMonth = "SEP/2021";

        YearMonth currentYm = YearMonth.parse(currentMonth, dtf);
        YearMonth previousYm = currentYm.minusMonths(1);

        String previousMonth = previousYm.format(dtf);
        System.out.println(previousMonth);

        // If required, convert it into the UPPER CASE
        System.out.println(previousMonth.toUpperCase());
    }
}

Output:

Aug/2021
AUG/2021

ONLINE DEMO

Learn more about the modern Date-Time API* from Trail: Date Time.


* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8 APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time.

CodePudding user response:

    String currentMonth = "Sep/2021";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM/yyyy");
    YearMonth yearMonthCurrent = YearMonth.parse(currentMonth, formatter);
    YearMonth yearMonthPrevious = yearMonthCurrent.minusMonths(1);
    String previousMonth = formatter.format(yearMonthPrevious);

CodePudding user response:

java.time

I gather from your question that your input and output both have the same format with month abbreviation in all upper case, which is non-standard. Of course we can handle it. I believe in putting an effort into some ground work so that when I get to the real work, I can do it in a simple way. In this case I am constructing a formatter for your format that I can then use both for parsing the input and formatting the output.

    Map<Long, String> monthAbbreviations = Arrays.stream(Month.values())
            .collect(Collectors.toMap(m -> Long.valueOf(m.getValue()),
                    m -> m.getDisplayName(
                                    TextStyle.SHORT_STANDALONE, Locale.ENGLISH)
                            .toUpperCase()));
    DateTimeFormatter monthFormatter = new DateTimeFormatterBuilder()
            .appendText(ChronoField.MONTH_OF_YEAR, monthAbbreviations)
            .appendPattern("/u")
            .toFormatter();
    
    String currentMonthInput = "SEP/2021";

    YearMonth currentMonth = YearMonth.parse(currentMonthInput, monthFormatter);
    YearMonth previousMonth = currentMonth.minusMonths(1);
    String previousMonthOutput = previousMonth.format(monthFormatter);
    
    System.out.println(previousMonthOutput);

Output is the desired:

AUG/2021

The two-arg appendText method of DateTimeFormatterBuilder allows us to define our own texts for a field. In this case I use it for specifying our upper case month abbreviations. The method accepts a map from numbers to texts, so we need a map 1=JAN, 2=FEB, etc. I am constructing the map in a stream operation that starts from the values of the Month enum.

Link

Oracle tutorial: Date Time explaining how to use java.time.

  • Related