创建X个日期的算法
Algorithm to create X number of dates
目前我有一个以 yyyyMM 格式表示日期的字符串列表,如下所示:
- 202008
- 202009
- 202010
我需要在此列表中创建 x 个条目,每个条目将月份增加一个,因此如果我要创建 3 个新条目,它们将如下所示:
- 202011
- 202012
- 202101
目前我的想法是创建一个方法来选择最新日期,解析字符串以分隔月份和年份,如果月份值 < 12 则将月份值增加 1,否则将其设置为 1 并改为增加年份。
然后我将该值添加到列表中并将其设置为最新的,重复 x 次。
我想知道是否有更优雅的解决方案我可以使用,也许使用现有的日期库(我正在使用 Java)。
YearMonth
And DateTimeFormatter
我建议您使用这些 modern date-time classes 来完成,如下所示:
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
了解有关现代 date-time API 的更多信息
由于您只是处理字符串,因此您可以创建一个方法来为您生成字符串日期,并且 return 所有这些字符串日期都在一个字符串数组中,如下所示:
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);
}
控制台 Window 将显示:
202008
202009
202010
202011
202012
202101
202102
202103
202104
202105
202106
202107
202108
202109
202110
202111
202112
202201
202202
202203
202204
202205
202206
202207
使用适当的 date-time 对象:YearMonth
不要将日期存储为列表中的字符串。正如您对数字使用 int
,对布尔值使用 boolean
(我希望如此!),对日期和时间使用适当的 date-time 对象。对于您的用例,YearMonth
class 是合适的。
就像将 int
格式化为带或不带千位分隔符的格式以及将 boolean
格式化为 yes 或 [=45= 一样容易]no,例如,将 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 格式。无论如何,为了证明您可以按照自己的方式拥有它,我正在使用格式化程序来生成您使用的 hyphen-less 格式:
private static final DateTimeFormatter YEAR_MONTH_FORMATTER
= DateTimeFormatter.ofPattern("uuuuMM");
现在转换为字符串列表是 one-liner(如果您的编辑器 window 足够宽):
List<String> datesAsStrings = dates.stream()
.map(YEAR_MONTH_FORMATTER::format)
.collect(Collectors.toList());
System.out.println(datesAsStrings);
[202008, 202009, 202010, 202011, 202012, 202101]
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601
目前我有一个以 yyyyMM 格式表示日期的字符串列表,如下所示:
- 202008
- 202009
- 202010
我需要在此列表中创建 x 个条目,每个条目将月份增加一个,因此如果我要创建 3 个新条目,它们将如下所示:
- 202011
- 202012
- 202101
目前我的想法是创建一个方法来选择最新日期,解析字符串以分隔月份和年份,如果月份值 < 12 则将月份值增加 1,否则将其设置为 1 并改为增加年份。 然后我将该值添加到列表中并将其设置为最新的,重复 x 次。
我想知道是否有更优雅的解决方案我可以使用,也许使用现有的日期库(我正在使用 Java)。
YearMonth
And DateTimeFormatter
我建议您使用这些 modern date-time classes 来完成,如下所示:
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
了解有关现代 date-time API 的更多信息
由于您只是处理字符串,因此您可以创建一个方法来为您生成字符串日期,并且 return 所有这些字符串日期都在一个字符串数组中,如下所示:
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);
}
控制台 Window 将显示:
202008
202009
202010
202011
202012
202101
202102
202103
202104
202105
202106
202107
202108
202109
202110
202111
202112
202201
202202
202203
202204
202205
202206
202207
使用适当的 date-time 对象:YearMonth
不要将日期存储为列表中的字符串。正如您对数字使用 int
,对布尔值使用 boolean
(我希望如此!),对日期和时间使用适当的 date-time 对象。对于您的用例,YearMonth
class 是合适的。
就像将 int
格式化为带或不带千位分隔符的格式以及将 boolean
格式化为 yes 或 [=45= 一样容易]no,例如,将 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 格式。无论如何,为了证明您可以按照自己的方式拥有它,我正在使用格式化程序来生成您使用的 hyphen-less 格式:
private static final DateTimeFormatter YEAR_MONTH_FORMATTER
= DateTimeFormatter.ofPattern("uuuuMM");
现在转换为字符串列表是 one-liner(如果您的编辑器 window 足够宽):
List<String> datesAsStrings = dates.stream()
.map(YEAR_MONTH_FORMATTER::format)
.collect(Collectors.toList());
System.out.println(datesAsStrings);
[202008, 202009, 202010, 202011, 202012, 202101]
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601