1

目前我有一个以 yyyyMM 格式表示日期的字符串列表,如下所示:

  • 202008
  • 202009
  • 202010

我需要在此列表中创建 x 个条目,每个条目将月份增加一个,因此如果我要创建 3 个新条目,它们将如下所示:

  • 202011
  • 202012
  • 202101

目前我的想法是创建一个方法来选择最新日期,解析字符串以分隔月份和年份,如果月份值 < 12 则将月份值增加 1,否则将其设置为 1 并改为增加年份。然后我将该值添加到列表中并将其设置为最新的,重复 x 次。

我想知道是否有更优雅的解决方案可以使用,可能使用现有的日期库(我正在使用 Java)。

4

3 回答 3

2

YearMonthDateTimeFormatter

我建议您使用这些现代日期时间类来执行此操作,如下所示:

import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Test
        List<String> list = getYearMonths("202011", 3);
        System.out.println(list);

        // Bonus: Print each entry of the obtained list, in a new line
        list.forEach(System.out::println);
    }

    public static List<String> getYearMonths(String startWith, int n) {
        List<String> list = new ArrayList<>();

        // Define Formatter
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMM");

        // Parse the year-month string using the defined formatter
        YearMonth ym = YearMonth.parse(startWith, formatter);

        for (int i = 1; i <= n; i++) {
            list.add(ym.format(formatter));
            ym = ym.plusMonths(1);// Increase YearMonth by one month
        }
        return list;
    }
}

输出:

[202011, 202012, 202101]
202011
202012
202101

在Trail: Date Time了解有关现代日期时间 API 的更多信息。

于 2020-10-05T21:01:54.233 回答
2

使用正确的日期时间对象:YearMonth

不要将日期作为字符串存储在列表中。就像您int用于数字和boolean布尔值(我希望!)一样,使用正确的日期时间对象来表示日期和时间。对于您的用例,YearMonth该类是合适的。

正如很容易将 anint格式化为带有或不带千位分隔符的格式以及将 a 格式化booleanyesno一样,例如,将YearMonth对象格式化为字符串是微不足道的。所以当你需要一个字符串时这样做,而不是之前。

扩展此类对象列表的方法YearMonth是:

public static void extendDateList(List<YearMonth> dates, int numberOfNewDates) {
    if (dates.isEmpty()) {
        throw new IllegalArgumentException("List is empty; don’t know where to pick up");
        // Or may start from some fixed date or current month
    } else {
        YearMonth current = Collections.max(dates);
        for (int i = 0; i < numberOfNewDates; i++) {
            current = current.plusMonths(1);
            dates.add(current);
        }
    }
}

让我们试一试:

    List<YearMonth> dates = new ArrayList<YearMonth>(List.of(
            YearMonth.of(2020, Month.AUGUST), 
            YearMonth.of(2020, Month.SEPTEMBER),
            YearMonth.of(2020, Month.OCTOBER)));
    
    extendDateList(dates, 3);
    
    System.out.println(dates);

输出是:

[2020-08, 2020-09, 2020-10, 2020-11, 2020-12, 2021-01]

格式化成字符串

我答应过你,你可以很容易地得到你的琴弦。我建议使用上面印有连字符的格式,原因有两个:(1) 它更具可读性,(2) 它是国际标准 ISO 8601 格式。无论如何,为了证明您可以按照自己的方式拥有它,我使用格式化程序来生成您使用的无连字符格式:

private static final DateTimeFormatter YEAR_MONTH_FORMATTER
        = DateTimeFormatter.ofPattern("uuuuMM");

现在转换为字符串列表是单行的(如果您的编辑器窗口足够宽):

    List<String> datesAsStrings = dates.stream()
            .map(YEAR_MONTH_FORMATTER::format)
            .collect(Collectors.toList());
    System.out.println(datesAsStrings);

[202008, 202009, 202010, 202011, 202012, 202101]

链接

于 2020-10-06T01:46:13.973 回答
0

由于您只是在处理字符串,因此您可以创建一个方法来为您生成字符串日期并在字符串数组中返回所有这些字符串日期,如下所示:

public static String[] addMonthsToDateString(String startDate, int monthsToAdd) {
    // Break the string date down to integers Year and month.
    int year = Integer.valueOf(startDate.substring(0, 4));
    int month = Integer.valueOf(startDate.substring(4));
    // Calculate the number of iterations we need.
    int loopCount = ((month + monthsToAdd) - month);
    // Declare and initialize the String Array we will return.
    String[] stringDates = new String[loopCount];
    
    // Generate the required Date Strings
    for (int i = 0; i < loopCount; i++) {
        stringDates[i] = new StringBuilder("").append(year)
                         .append(String.format("%02d", month)).toString();
        month++;
        if (month == 13) {
            year++;
            month = 1;
        }
    }
    return stringDates;
}

要使用此方法,您需要提供字符串开始日期(“202008”)和要列出的整数月数(24):

// Get the desired list of string dates:
String[] desiredDates = addMonthsToDateString("202008", 24);

// Display the string dates produced into the Console Window:
for (String strg : desiredDates) {
    System.out.println(strg);
}

控制台窗口将显示:

202008
202009
202010
202011
202012
202101
202102
202103
202104
202105
202106
202107
202108
202109
202110
202111
202112
202201
202202
202203
202204
202205
202206
202207
于 2020-10-05T23:06:23.417 回答