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
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.