4

我正在尝试设置 a 的年份java.util.Date

我需要解析的时间戳不包括年份所以我这样做了:

private static final SimpleDateFormat logTimeStampFormat = 
    new SimpleDateFormat("MMM dd HH:mm:ss.SSS");

boolean isAfterRefDate (String line, Date refDate) {        
    try {
        Date logTimeStamp = logTimeStampFormat.parse(line);
        logTimeStamp.setYear(2012);      // But this is deprecated!
        return logTimeStamp.after(refDate);
    } catch (ParseException e) {
        // Handle exception
    }        
}

为了避免使用不推荐使用的方法,我这样做:

private static final SimpleDateFormat logTimeStampFormat = 
    new SimpleDateFormat("MMM dd HH:mm:ss.SSS");

private static Calendar cal = Calendar.getInstance();

boolean isAfterRefDate (String line, Date refDate) {
    try {
        Date logTimeStamp = logTimeStampFormat.parse(line);
        cal.setTime(logTimeStamp);
        cal.set(Calendar.YEAR, 2012);
        logTimeStamp = cal.getTime();            
        return logTimeStamp.after(refDate);
    } catch (ParseException e) {
        // Handle exception
    }        
}

我只是不认为这是解决这个问题的最好方法。我必须首先正确设置日历对象,然后从中取回日期对象,而之前我可以直接修改日期对象。

有人可以提出更好的方法吗?

4

2 回答 2

5

有人可以提出更好的方法。

当然 - 首先尽量避免使用Dateand Calendar。改用Joda Time,效果更好。

在 a 上设置年份Date本质上是模棱两可的操作 - 今年应该是什么时区?如果您将 2013 年设置为之前的 2012 年 2 月 29 日,您会期望发生什么?

使用 Joda Time 将使您的代码在您真正期望的数据类型方面更加清晰。如果您确实需要,您始终可以在 API 边界进行Date转换。Calendar

于 2012-08-15T09:23:42.717 回答
1

java.time

有人可以提出更好的方法吗?

是的,使用java.time类。

Jon Skeet的答案是正确的,但现在已经过时了,因为 Joda-Time 团队建议迁移到 java.time 类。

MonthDay&LocalTime

我们可以将该输入字符串解析为两个单独的对象 aMonthDay和 a LocalTime。第一个显然是一个月和一个月中的一天,但没有任何年份,所以它不是一个完整的日期。第二个代表一天中的时间,但没有任何日期和任何时区。

String input = "Sep 21 12:34:56.123";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "MMM dd HH:mm:ss.SSS" );

MonthDay md = MonthDay.parse ( input , f );
LocalTime lt = LocalTime.parse ( input , f );

System.out.println ( "md: " + md + " | lt: " + lt );

医学博士:--09-21 | 时间:12:34:56.123

LocalDateTime

我们可以加一年,完全搅拌,得到一个LocalDateTime.

LocalDateTime ldt = LocalDateTime.of( ld , lt );

ZonedDateTime

这仍然不是一个实际的时刻,也不是时间线上的一个点。如果没有从 UTC 偏移或时区的上下文, aLocalDateTime就没有意义。

应用 aZoneId以获得ZonedDateTime. 现在我们有了一个有意义的时刻,时间线上的一个点。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( z );
于 2016-09-20T02:44:24.990 回答