Gil*_*ert 27 java datetime java-8
我需要获得两个ZonedDateTime实例来表示当前周的开始和结束.
ZonedDateTime currentDateTime = ZonedDateTime.now();
ZonedDateTime startOfThisWeek = currentDateTime.with(DayOfWeek.MONDAY).truncatedTo(ChronoUnit.DAYS).plusMinutes(1);
ZonedDateTime endOfThisWeek = startOfThisWeek.plusDays(6);
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd kk:mm");
String startweek = startOfThisWeek.format(df);
String endweek = endOfThisWeek.format(df);
System.out.println(startweek);
System.out.println(endweek);
Run Code Online (Sandbox Code Playgroud)
输出:
2018-06-18 24:01
2018-06-24 24:01
Run Code Online (Sandbox Code Playgroud)
这个字符串代表什么?是在2018-06-18上午午夜后1分钟?如果是这样,为什么24:01是有效时间?我认为在24小时制表示中它应该是00:01.
编辑:有没有办法格式化这个显示00:01而不将字符串转换为新的字符串?
Bas*_*que 37
kk为HH.2018-06-18 24:01
...变为:
2018-06-18 00:01
提示:调试时,请使用默认的标准ISO 8601格式生成String.
ZonedDateTime.now(
ZoneId.of( "Africa/Tunis" )
)
.truncatedTo( ChronoUnit.DAYS )
.with(
TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY )
)
.toString()
Run Code Online (Sandbox Code Playgroud)
2018-06-18T00:00 + 01:00 [非洲/突尼斯]
k = 1-24小时(实际上是24-23)在由乔恩Vernee删除答案是正确的:您正在使用k其记录为使用运行从1到24的24小时时钟表示时间的一天.
在文档中不太清楚的是,第一个小时被计为24,而不是0.所以最好说明当天从24-23开始,也就是说24, 1, 2, 3, … , 22, 23.该值24代表一天中的第一个小时,而不是最后一个小时.
这是一个使用时间的简单示例,仅用于演示此行为.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "kk:mm" );
LocalTime lt = LocalTime.MIN;
String output = lt.format( f );
System.out.println( lt.toString() ); // Standard ISO 8601 format, 00-24.
System.out.println( output ); // `kk` format is 24, 1 , 2, … , 22 , 23.
Run Code Online (Sandbox Code Playgroud)
00:00
24:00
请注意,java.time的这种kk行为,其中一天中的整个第一个小时标记为异常,非标准,并且不常用.见维基百科.显然,这种风格偶尔会在一些特殊情况下使用,其中营业时间超过午夜,例如广播.24
至于你的期望......
在24小时制表示中它应该是00:01.
如果您想要0-23,请使用"H",如文档所示.
首先,查看默认的ISO 8601格式输出.
ZonedDateTime currentDateTime = ZonedDateTime.now();
ZonedDateTime startOfThisWeek = currentDateTime.with( DayOfWeek.MONDAY ).truncatedTo( ChronoUnit.DAYS ).plusMinutes( 1 );
ZonedDateTime endOfThisWeek = startOfThisWeek.plusDays( 6 );
System.out.println( startOfThisWeek );
System.out.println( endOfThisWeek );
Run Code Online (Sandbox Code Playgroud)
2018-06-18T00:01-07:00 [美国/洛杉矶]
2018-06-24T00:01-07:00 [美国/洛杉矶]
现在,您的自定义格式.将格式模式从更改kk为HH.
DateTimeFormatter df = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm" );
String startweek = startOfThisWeek.format( df );
String endweek = endOfThisWeek.format( df );
System.out.println( startweek );
System.out.println( endweek );
Run Code Online (Sandbox Code Playgroud)
2018-06-18 00:01
2018-06-24 00:01
其他一些说明......
如果您要代表本周,则无需添加一分钟.表示时间跨度的一般最佳实践是半开放方法,其中开头是包容性的,而结尾是排他性的.因此,一个星期从一个星期一的第一个时刻开始,一直到下一个星期一的第一个时刻,但不包括.
此外,我建议总是ZoneId明确地传递一个,now即使这是ZoneId.systemDefault为了让你的意图清晰.
调整到星期一有一个问题,如果今天已经是星期一该怎么办.使用TemporalAdjuster找到的这对实现中的任何一个TemporalAdjusters来指定您的行为选择:
示例代码.
ZonedDateTime now = ZonedDateTime.now( ZoneId.of( "Africa/Tunis" ) ) ; // Or `ZoneId.systemDefault()`.
ZonedDateTime weekStart = now.truncatedTo( ChronoUnit.DAYS ).with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) );
ZonedDateTime weekStop = weekStart.plusWeeks( 1L ) ;
Run Code Online (Sandbox Code Playgroud)
对于跟踪和调试,始终使用标准ISO 8601格式生成表示日期时间对象值的String,而不是如您的问题所示的自定义格式.该java.time类默认情况下,其使用标准格式toString的方法.
String outputStart = weekStart.toString() ;
String outputStop = weekStop.toString() ;
Run Code Online (Sandbox Code Playgroud)
2018-06-18T00:00 + 01:00 [非洲/突尼斯]
2018-06-25T00:00 + 01:00 [非洲/突尼斯]
如果您想要仅限日期的值,请使用LocalDateTime.
您可以使用ThreeTen-Extra项目中的LocalDateRange或Interval类在单个对象中表示您的时间范围.
最后一个提示:让java.time通过使用DateTimeFormatter.ofLocalized…方法自动本地化生成的字符串Locale来确定人类语言和文化规范的格式,从而完成繁重的工作.