【问题标题】:Calculate previous 12 months from given month - SimpleDateFormat从给定月份计算前 12 个月 - SimpleDateFormat
【发布时间】:2021-09-02 23:15:12
【问题描述】:

我正在尝试从给定月份(取自 DB)将前 12 个月放入一个数组列表中。

List<String> allDates = new ArrayList<String>();    

sqlQuery="select max(date) from Table_Name";

maxDate="Jan-2016"; (Result from Query);

从 maxDate 获取前 12 个月,我使用 SimpleDateFormat。

我想从 Given Month (maxDate) 计算前 12 个月,而不是从当前月份,我尝试了以下代码。

//  Parsing maxDate to an integer (say Jan-2016 = 0, Feb-2016= 1)
Date date = new SimpleDateFormat("MMM-yyyy").parse(maxDate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int month=cal.get(Calendar.MONTH);
        System.out.println("month : "+month);

// Looping to get previous 12 months from current month.
SimpleDateFormat month_date = new SimpleDateFormat("MMM-yyyy");
          for (int i = 12; i > 0; i--) {
                Calendar calendar1 = Calendar.getInstance();
                calendar1.add(Calendar.MONTH, -i);
                String month_name1 = month_date.format(calendar1.getTime());
                allDates.add(month_name1);
            }
            System.out.println(allDates);

由于月份是从 (0 - 11) 编号的,所以我无法实现。 请提出一个想法来计算给定月份的前 12 个月。感谢您的帮助!

【问题讨论】:

  • 它们需要按降序排列吗?你能带走一年,然后及时向前迭代吗?另外,allDates 是什么类型的对象?
  • 我需要它按降序排列,这样我才能获得前 12 个月的数据。 allDates 这里是ArrayList。我需要将这 12 个月添加到 allDates。

标签: java date simpledateformat


【解决方案1】:

问题在于,在循环中,您始终基于当前日期而不是 maxDate 进行计算。

List<String> allDates = new ArrayList<>();
String maxDate = "Jan-2016";
SimpleDateFormat monthDate = new SimpleDateFormat("MMM-yyyy");
Calendar cal = Calendar.getInstance();
cal.setTime(monthDate.parse(maxDate));
for (int i = 1; i <= 12; i++) {
    String month_name1 = monthDate.format(cal.getTime());
    allDates.add(month_name1);
    cal.add(Calendar.MONTH, -1);
}
System.out.println(allDates);

输出

[Jan-2016, Dec-2015, Nov-2015, Oct-2015, Sep-2015, Aug-2015, Jul-2015, Jun-2015, \
 May-2015, Apr-2015, Mar-2015, Feb-2015]

edit简短说明 sn-p 的作用。

  1. 从给定的maxDate 创建一个Calendar 并将其分配给cal
  2. cal中当前日期的字符串Mon-Year添加到列表allDates
  3. 从日历中减去一个月cal.add(Calendar.MONTH, -1)
  4. 重复步骤 2. 和 3. 十二次

正如巴兹尔所说。如果您想稍后将allDates 中的值处理为Date / Calendar,请考虑不要在两者之间生成字符串列表。

【讨论】:

  • 非常感谢!您能否解释一下这一行,cal.add(Calendar.MONTH, -1); 我看到您使用了 -1 而不是循环 i ?我还希望将 Jan-2016 包含在 ArrayList allDates 中,我该如何实现?
  • @Disera 我修改了 sn-p 并添加了一个简短的解释它的作用。
  • 非常感谢您的解释!
【解决方案2】:

ISO 8601

将日期时间值表示为文本有一个合理的标准:ISO 8601

因此,与其将您的年月值序列化为Jan-2016,我强烈建议您使用标准格式2016-01。这种格式即使跨英语以外的其他语言也能直观地阅读。

java.time

您正在使用与最早版本的 Java 捆绑在一起的麻烦的旧日期时间类。正如您所了解的,他们糟糕的设计选择之一是从零开始的月份数字,从 0 到 11。

Sun 和 Oracle 放弃了这些旧类,用 Java 8 及更高版本中内置的 java.time 框架取代了它们。

YearMonth

在这些类中正是您所需要的:YearMonth。顾名思义,是一年和一个月的组合。

与其处理字符串,不如传递这种类型的对象。鉴于该类是内置于 Java 中的,因此您可以在整个代码库中依赖该类。

解析

要解析您的非标准字符串,请定义一个格式化程序。指定一个Locale 用于翻译月份名称的人类语言。

DateTimeFormatter formatter = formatter.ofPattern( "MMM-yyyy" );
formatter = formatter.withLocale( Locale.US ) ;
YearMonth stop = YearMonth.parse( "Jan-2016" , formatter );

要解析标准字符串,不需要格式化程序。 java.time 类默认支持解析/生成 ISO 8601 字符串。

YearMonth stop = YearMonth.parse( "2016-01" );

日期时间数学

YearMonth 类提供了加减时间的方法。

YearMonth start = stop.minusYears( 1 );

定义一个YearMonth类型的集合。

List<YearMonth> yearMonths = new ArrayList<>( 12 );

循环,每次递增一个月,直到到达停止月份。您要求 Half-Open 方法,其中时间跨度的开始是包含,而结束是独占。这种半开放式方法在日期时间工作中很常见。

YearMonth yearMonth = start ;
while ( yearMonth.isBefore( stop ) ) {
    yearMonths.add( yearMonth ) ;  // Add each incremented YearMonth to our collection.
    // Set up next loop.
    yearMonth = yearMonth.plusMonths( 1 );
}

【讨论】:

  • 感谢您的信息! YearMonth 类很有用。
  • 在 yearMonth 对象实例上找不到 addMonths 方法。相反,在文档中找到了这个:plusMonths(1)。在这种情况下,您必须将结果分配给迭代变量
  • @Tobet 是的,你是对的,我的立场是正确的。代码现已修复。谢谢。
【解决方案3】:
public static void main(String[] args) {        
    Calendar c = Calendar.getInstance();
    c.setTime(new Date()); //Give Your Date
    c.add(Calendar.MONTH, -12);
    Date fromDate = c.getTime();
    Date toDate = new Date(); //Give Your Date

    System.out.println("from "+fromDate);
    System.out.println(" to "+fromDate);
}

SQL 查询:

select * from TABLE where Date between fromDate and toDate;

【讨论】:

  • 感谢您的贡献。并不是说我可以看到您对其他答案中没有的问题做出了任何贡献。我相信有人要求一份 12 个月的清单。
猜你喜欢
  • 2021-08-12
  • 1970-01-01
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多