tl;博士
LocalDate
.now( ZoneId.of( "Pacific/Auckland" ) ) // Get the date-only value for the current moment in a specified time zone.
.minusWeeks( 1 ) // Go back in time one week.
.atStartOfDay( ZoneId.of( "Pacific/Auckland" ) ) // Determine the first moment of the day for that date in the specified time zone.
.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // Generate a string in standard ISO 8601 format.
.replace( "T" , " " ) // Replace the standard "T" separating date portion from time-of-day portion with a SPACE character.
java.time
现代方法使用 java.time 类。
LocalDate 类表示没有时间和时区的仅日期值。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。
以continent/region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 3-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。
ZoneId z = ZoneId.forID( "America/Montreal" ) ;
LocalDate now = LocalDate.now ( z ) ;
使用minus… 和plus… 方法做一些数学运算。
LocalDate weekAgo = now.minusWeeks( 1 );
让 java.time 为您想要的时区确定一天中的第一个时刻。不要假设这一天从00:00:00 开始。夏令时等异常意味着一天可能从另一个时间开始,例如01:00:00。
ZonedDateTime weekAgoStart = weekAgo.atStartOfDay( z ) ;
使用DateTimeFormatter 对象生成表示此ZonedDateTime 对象的字符串。搜索 Stack Overflow 以获取有关该课程的更多讨论。
DateTimeFormatter f = DateTimeFormatter.ISO_LOCAL_DATE_TIME ;
String output = weekAgoStart.format( f ) ;
该标准格式与您想要的很接近,但在您想要空格的中间有一个T。所以用空格替换T。
output = output.replace( "T" , " " ) ;
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
从哪里获得 java.time 类?
乔达时间
更新: Joda-Time 项目现在处于维护模式。团队建议迁移到 java.time 类。
使用Joda-Time 库使日期时间工作更容易。
注意时区的使用。如果省略,则您正在使用 UTC 或 JVM 的当前默认时区。
DateTime now = DateTime.now ( DateTimeZone.forID( "America/Montreal" ) ) ;
DateTime weekAgo = now.minusWeeks( 1 );
DateTime weekAgoStart = weekAgo.withTimeAtStartOfDay();