Return 从任何给定的日期间隔开始,每周 1 到 7 天
Return 1 to 7 days of a week from any given interval of dates
我想 return 一个日期间隔的天图 :
从 1 到 7 天:
From: "2016-02-09" to To: "2016-02-09" -> return : Tue
From: "2016-02-09" to To: "2016-02-12" -> return : Tue, Wed, Thu, Fri
From: "2016-02-02" to To: "2016-04-12" -> return : Tue, Wed, Thu, Fri, Sat, Sun, Mon (this should be sorted from Monday for the map)
带有 returned day as key
(字符串)和 value always = true
(布尔值)的排序映射(周从星期一开始)将被重新用于其他目的。
我想使用 joda-time 2.8.1,但我不确定如何处理日期间隔?
我设法得到了我想要的部分东西,但只用了一天 :
String input = "2016-02-09";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "yyyy-MM-dd" );
LocalDate localDate = formatter.parseLocalDate( input );
Locale locale = Locale.US;
DateTimeFormatter formatterOutput = DateTimeFormat.forPattern( "E" ).withLocale( locale );
String output = formatterOutput.print( localDate ); //Result = Tue
Joda-Time 不支持(封闭的)日历日期间隔,但仅支持瞬间间隔。所以这里有一个临时解决方法:
LocalDate start = LocalDate.parse("2016-02-09");
LocalDate end = LocalDate.parse("2016-02-12");
if (start.isAfter(end)) {
return Collections.emptyMap();
}
LocalDate current = start;
Map<Integer, Boolean> map = new TreeMap<>();
do {
map.put(current.getDayOfWeek(), Boolean.TRUE);
current = current.plusDays(1);
} while (!current.isAfter(end) && map.size() < 7);
LocalDate ref = new LocalDate(2016, 2, 7); // sunday
DateTimeFormatter f = DateTimeFormat.forPattern("E").withLocale(Locale.US);
StringBuilder sb = new StringBuilder();
for (int dayOfWeek : map.keySet()) {
String output = f.print(ref.plusDays(dayOfWeek));
sb.append(", ");
sb.append(output);
}
System.out.println(sb.delete(0, 2).insert(0, "[").append(']').toString());
// [Tue, Wed, Thu, Fri]
return map;
首先,将您的想法转移到 objects 而不是字符串。字符串可能是您的最终输出,但请将您的业务逻辑和数据保留在 objects 中。
java.time
本答案使用 Java 8 及更高版本中内置的 java.time 框架。
这些新的 classes 的灵感来自 Joda-Time 但 re-architected。由 ThreeTenExtra 项目扩展(其 Interval
class 在这里可能有用)。
DayOfWeek
java.time 框架包含一个 DayOfWeek
枚举。利用那些 objects。换句话说,不要将字符串视为 date-times;字符串是 date-time 值的文本表示。
您问题的地图和列表部分令人困惑。不确定你想要什么 collections。但我会展示基本的想法。您可以使用 DayOfWeek
objects 作为地图和列表中的键或值。
无需指定解析模式。您的字符串采用 ISO 8601 格式。 java.time classes 在 parsing/generating 字符串时默认使用 ISO 8601 格式。
List< DayOfWeek > dows = new ArrayList<>();
LocalDate start = LocalDate.parse( "2016-02-09" );
LocalDate stop = LocalDate( "2016-02-12" );
循环增加一天。当我们到达停止日期时停止。这种 "half-open" 方法通常用于 date-time 开头包含在内而结尾不包含在内的工作。例如,一周将被指定为从星期一开始,运行 直到但不包括下一个星期一。
LocalDate d = start;
while ( d.isBefore( stop ) ) {
DayOfWeek dow = DayOfWeek.from ( d );
dows.add( dow );
d = d.plusDays( 1 );
}
Set
也许您正在寻找在一段时间内出现的 day-of-week 值的不同列表。在那种情况下,添加到 Set
rather than a List
. The Set omits duplicates. If you want the results in a certain order use a SortedSet
。
输出本地化字符串
您可以生成一个字符串,其中包含本地化为人类语言并缩写为文化规范的每一天的名称。要求 DayOfWeek
枚举本地化时指定区域设置。
请注意,在某些语言(非英语)中,星期几有两种不同的拼写,具体取决于它是单独使用还是作为日期的一部分使用。 TextStyle
枚举允许您指定其中之一。
String output = dow.getDisplayName( TextStyle.SHORT_STANDALONE , Locale.CANADA_FRENCH ); // Or Locale.US etc.
更好的解决方案是只检查开始日期和结束日期。更好,因为最多有 7 次迭代:
LocalDate start = LocalDate.parse("2016-02-09");
LocalDate end = LocalDate.parse("2016-02-12");
if (start.isAfter(end)) {
return Collections.emptyMap();
}
Integer startDay = start.getDayOfWeek().getValue();
Integer endDay = end.getDayOfWeek().getValue();
if (startDay > endDay) {
endDay += 7;
}
Map<DayOfWeek, Boolean> result = new LinkedHashMap<DayOfWeek, Boolean>();
for (int i = startDay; i<=endDay; i++) {
result.put(DayOfWeek.of(i), Boolean.TRUE);
}
我想 return 一个日期间隔的天图 :
从 1 到 7 天:
From: "2016-02-09" to To: "2016-02-09" -> return : Tue From: "2016-02-09" to To: "2016-02-12" -> return : Tue, Wed, Thu, Fri From: "2016-02-02" to To: "2016-04-12" -> return : Tue, Wed, Thu, Fri, Sat, Sun, Mon (this should be sorted from Monday for the map)
带有
returned day as key
(字符串)和value always = true
(布尔值)的排序映射(周从星期一开始)将被重新用于其他目的。
我想使用 joda-time 2.8.1,但我不确定如何处理日期间隔? 我设法得到了我想要的部分东西,但只用了一天 :
String input = "2016-02-09";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "yyyy-MM-dd" );
LocalDate localDate = formatter.parseLocalDate( input );
Locale locale = Locale.US;
DateTimeFormatter formatterOutput = DateTimeFormat.forPattern( "E" ).withLocale( locale );
String output = formatterOutput.print( localDate ); //Result = Tue
Joda-Time 不支持(封闭的)日历日期间隔,但仅支持瞬间间隔。所以这里有一个临时解决方法:
LocalDate start = LocalDate.parse("2016-02-09");
LocalDate end = LocalDate.parse("2016-02-12");
if (start.isAfter(end)) {
return Collections.emptyMap();
}
LocalDate current = start;
Map<Integer, Boolean> map = new TreeMap<>();
do {
map.put(current.getDayOfWeek(), Boolean.TRUE);
current = current.plusDays(1);
} while (!current.isAfter(end) && map.size() < 7);
LocalDate ref = new LocalDate(2016, 2, 7); // sunday
DateTimeFormatter f = DateTimeFormat.forPattern("E").withLocale(Locale.US);
StringBuilder sb = new StringBuilder();
for (int dayOfWeek : map.keySet()) {
String output = f.print(ref.plusDays(dayOfWeek));
sb.append(", ");
sb.append(output);
}
System.out.println(sb.delete(0, 2).insert(0, "[").append(']').toString());
// [Tue, Wed, Thu, Fri]
return map;
首先,将您的想法转移到 objects 而不是字符串。字符串可能是您的最终输出,但请将您的业务逻辑和数据保留在 objects 中。
java.time
本答案使用 Java 8 及更高版本中内置的 java.time 框架。
这些新的 classes 的灵感来自 Joda-Time 但 re-architected。由 ThreeTenExtra 项目扩展(其 Interval
class 在这里可能有用)。
DayOfWeek
java.time 框架包含一个 DayOfWeek
枚举。利用那些 objects。换句话说,不要将字符串视为 date-times;字符串是 date-time 值的文本表示。
您问题的地图和列表部分令人困惑。不确定你想要什么 collections。但我会展示基本的想法。您可以使用 DayOfWeek
objects 作为地图和列表中的键或值。
无需指定解析模式。您的字符串采用 ISO 8601 格式。 java.time classes 在 parsing/generating 字符串时默认使用 ISO 8601 格式。
List< DayOfWeek > dows = new ArrayList<>();
LocalDate start = LocalDate.parse( "2016-02-09" );
LocalDate stop = LocalDate( "2016-02-12" );
循环增加一天。当我们到达停止日期时停止。这种 "half-open" 方法通常用于 date-time 开头包含在内而结尾不包含在内的工作。例如,一周将被指定为从星期一开始,运行 直到但不包括下一个星期一。
LocalDate d = start;
while ( d.isBefore( stop ) ) {
DayOfWeek dow = DayOfWeek.from ( d );
dows.add( dow );
d = d.plusDays( 1 );
}
Set
也许您正在寻找在一段时间内出现的 day-of-week 值的不同列表。在那种情况下,添加到 Set
rather than a List
. The Set omits duplicates. If you want the results in a certain order use a SortedSet
。
输出本地化字符串
您可以生成一个字符串,其中包含本地化为人类语言并缩写为文化规范的每一天的名称。要求 DayOfWeek
枚举本地化时指定区域设置。
请注意,在某些语言(非英语)中,星期几有两种不同的拼写,具体取决于它是单独使用还是作为日期的一部分使用。 TextStyle
枚举允许您指定其中之一。
String output = dow.getDisplayName( TextStyle.SHORT_STANDALONE , Locale.CANADA_FRENCH ); // Or Locale.US etc.
更好的解决方案是只检查开始日期和结束日期。更好,因为最多有 7 次迭代:
LocalDate start = LocalDate.parse("2016-02-09");
LocalDate end = LocalDate.parse("2016-02-12");
if (start.isAfter(end)) {
return Collections.emptyMap();
}
Integer startDay = start.getDayOfWeek().getValue();
Integer endDay = end.getDayOfWeek().getValue();
if (startDay > endDay) {
endDay += 7;
}
Map<DayOfWeek, Boolean> result = new LinkedHashMap<DayOfWeek, Boolean>();
for (int i = startDay; i<=endDay; i++) {
result.put(DayOfWeek.of(i), Boolean.TRUE);
}