【问题标题】:How to get previous month from current month in java?如何在java中从当前月份获取上个月?
【发布时间】:2021-12-03 02:40:28
【问题描述】:

我有以下场景。

String currentMonth = SEP/2021

我要String previous month = AUG/2021.

如何在 java 中实现这一点?

【问题讨论】:

  • 代码 sn-p 不会编译顺便说一句
  • 你可以有一个数字字符串对的地图并查找它们。

标签: java date calendar java-time yearmonth


【解决方案1】:

java.time

您可以使用java.time API 来执行此操作。

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());
    }
}

输出:

Aug/2021
AUG/2021

ONLINE DEMO

通过 Trail: Date Time 了解有关 modern Date-Time API* 的更多信息。


* 如果您正在为一个 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring。请注意,Android 8.0 Oreo 已经提供了support for java.time

【讨论】:

    【解决方案2】:
        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);
    

    【讨论】:

    • 输入是SEP/2021,而不是Sep/2021
    • Sep 和 SEP 的语义区别是什么?
    • 好吧,应该问自己一个更好的问题:为什么 Java 架构师决定引入 DateTimeFormatterBuilder#parseCaseInsensitive(您可以查看我的演示答案)?对于输入 SEP/2021,您的代码将失败,该输入可能是来自某些 API 或通过某些其他输入源(例如键盘)的响应的一部分。
    【解决方案3】:

    java.time

    我从您的问题中了解到,您的输入和输出都具有相同的格式,并且月份缩写全部为大写,这是非标准的。我们当然可以处理。我相信在一些基础工作上付出努力,这样当我开始真正的工作时,我就可以用一种简单的方式来完成它。在这种情况下,我正在为您的格式构建一个格式化程序,然后我可以使用它来解析输入和格式化输出。

        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);
    

    输出是期望的:

    2021 年 8 月

    DateTimeFormatterBuilder 的两个参数 appendText 方法允许我们为字段定义自己的文本。在这种情况下,我使用它来指定我们的大写月份缩写。该方法接受从数字到文本的映射,因此我们需要一个映射 1=JAN、2=FEB 等。我正在从Month 枚举的值开始的流操作中构建映射。

    链接

    Oracle tutorial: Date Time 解释如何使用 java.time。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多