# 算法以创建X个日期

go评论64阅读模式

Algorithm to create X number of dates

# 问题

• 202008
• 202009
• 202010

• 202011
• 202012
• 202101

Currently I have a list of Strings that represent a date in a yyyyMM format, something like this:

• 202008
• 202009
• 202010

I need to create x number of entries in this list with each entry increasing the month by one, so if I were to create 3 new entries they would look like this:

• 202011
• 202012
• 202101

Currently my idea is to create a method to pick the latest date, parse the String to separate month and year, increase the month value by 1 if it is < 12 otherwise set it to 1 and increase the year instead.
Then I would add that value to a list and set it as the most recent, repeating x number of times.

What I want to know is if there is a more elegant solution that I could use, maybe using an existing date library (I'm using Java).

# 答案1

## `YearMonth`与`DateTimeFormatter`

``````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) {
// 测试
List<String> list = getYearMonths("202011", 3);
System.out.println(list);

// 奖励：在新行中打印获得列表的每个条目
list.forEach(System.out::println);
}

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

// 定义格式化器
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuuMM");

// 使用定义的格式化器解析年月字符串
YearMonth ym = YearMonth.parse(startWith, formatter);

for (int i = 1; i <= n; i++) {
ym = ym.plusMonths(1); // 增加一个月的YearMonth
}
return list;
}
}
``````

``````[202011, 202012, 202101]
202011
202012
202101
``````

## `YearMonth` And `DateTimeFormatter`

I recommend you do it using these modern date-time classes as shown below:

``````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&lt;String&gt; list = getYearMonths(&quot;202011&quot;, 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&lt;String&gt; getYearMonths(String startWith, int n) {
List&lt;String&gt; list = new ArrayList&lt;&gt;();

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

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

for (int i = 1; i &lt;= n; i++) {
ym = ym.plusMonths(1);// Increase YearMonth by one month
}
return list;
}
}
``````

Output:

``````[202011, 202012, 202101]
202011
202012
202101
``````

# 答案2

## 使用正确的日期时间对象：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");
// 或者可以从某个固定日期或当前月份开始
} else {
YearMonth current = Collections.max(dates);
for (int i = 0; i < numberOfNewDates; i++) {
current = current.plusMonths(1);
}
}
}
``````

``````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]
``````

## 格式化为字符串

``````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]
``````

## Use proper date-time objects: YearMonth

Don’t store your dates as strings in your list. Just as you use `int` for numbers and `boolean` for Boolean values (I hope!), use proper date-time objects for dates and times. For your use case the `YearMonth` class is appropriate.

And just as it’s easy to format an `int` into a format with or without thousand separators and a `boolean` into yes or no, for example, formatting your `YearMonth` objects into strings is trivial. So do that when you need a string, not before.

A method for extending such a list of `YearMonth` objects would be:

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

Let’s try it out:

``````	List&lt;YearMonth&gt; dates = new ArrayList&lt;YearMonth&gt;(List.of(
YearMonth.of(2020, Month.AUGUST),
YearMonth.of(2020, Month.SEPTEMBER),
YearMonth.of(2020, Month.OCTOBER)));

extendDateList(dates, 3);

System.out.println(dates);
``````

Output is:

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

## Formatting into strings

I promised you you could easily have your strings. I would suggest using the format with a hyphen printed above for two reasons: (1) it’s more readable, and (2) it’s ISO 8601 format, the international standard. In any case, to demonstrate that you can have it just the way you want, I am using a formatter to produce the hyphen-less format that you used:

``````private static final DateTimeFormatter YEAR_MONTH_FORMATTER
= DateTimeFormatter.ofPattern(&quot;uuuuMM&quot;);
``````

Now converting to a list of strings is a one-liner (if your editor window is wide enough):

``````	List&lt;String&gt; datesAsStrings = dates.stream()
.map(YEAR_MONTH_FORMATTER::format)
.collect(Collectors.toList());
System.out.println(datesAsStrings);
``````

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

# 答案3

``````public static String[] addMonthsToDateString(String startDate, int monthsToAdd) {
int year = Integer.valueOf(startDate.substring(0, 4));
int month = Integer.valueOf(startDate.substring(4));
int loopCount = ((month + monthsToAdd) - month);
String[] stringDates = new String[loopCount];

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

// Usage example:

for (String strg : desiredDates) {
System.out.println(strg);
}
``````

Console Output:

``````202008
202009
202010
202011
202012
202101
202102
202103
202104
202105
202106
202107
202108
202109
202110
202111
202112
202201
202202
202203
202204
202205
202206
202207
``````

Since you're just dealing with strings you could just create a method to produce the string dates for you and return all those string dates in a String Array, like this:

``````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 &lt; loopCount; i++) {
stringDates[i] = new StringBuilder(&quot;&quot;).append(year)
.append(String.format(&quot;%02d&quot;, month)).toString();
month++;
if (month == 13) {
year++;
month = 1;
}
}
return stringDates;
}
``````

To use this method you would need to supply a string start date ("202008") and the integer number of months you want to list (24):

``````// Get the desired list of string dates:

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

The Console Window will display:

``````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月6日 04:52:55
• 转载请务必保留本文链接：https://go.coder-hub.com/64216046.html
• algorithm
• calendar
• date
• java
• yearmonth

go 74

go 64

go 59