避免使用旧的日期时间类
您正在使用旧的 java.util.Date/.Calendar 和 SimpleDateFormat 类。避开他们。
Date 类的 toString 在生成字符串时应用默认时区的设计选择不佳。因此,它似乎有一个时区,而实际上却没有(除了埋在下面的一个时区,它被忽略以供常规使用)。令人困惑,是的。避免它。
java.time
改为使用 Java 8 及更高版本中内置的 java.time。
首先解析为LocalDateTime,不带任何时区或偏移量。
LocalDateTime ldt = LocalDateTime.parse( "1995-12-31T23:59:59Z" );
应用time zone 或offset-from-UTC 赋予LocalDateTime 含义,使其成为时间轴上的实际时刻。您必须知道或询问该字符串打算使用的时区或偏移量,因为没有嵌入任何指示。对于这个例子,我将任意假设Québec。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zoneId );
您想要的输出末尾有一个Z,对于Zulu,这意味着UTC。
在 java.time 中,Instant 代表 UTC 时间线上的一个时刻。您可以从ZonedDateTime 中提取Instant。
Instant instant = zdt.toInstant();
Instant 类的 toString 方法会生成您所需格式的字符串。该格式是标准ISO 8601 格式之一。
String output = instant.toString();
半开
我碰巧注意到您的示例值试图获得 1995 年底。有更好的方法来执行此类搜索或比较标准。
在日期时间工作中,最佳实践称为半开放式,其中时间跨度的开始是包含,而结束是不包含。因此,一周从星期一开始,一直持续到但不包括下星期一。
定义年份是指从 1995 年第一天的第一刻开始,一直到但不包括下一年,即 1996 年第一天的第一刻。搜索任何值在该范围内不是使用 BETWEEN 而是作为:( someEvent >= firstMomentOf1995 AND someEvent < firstMomentOf1996 )(不是