有时java.util.Date失败之前

时间:2017-02-13 15:14:06

标签: java simpledateformat java-6 java.util.date

我支持Java 1.6代码,在那里进行日期比较。

static final SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");

static void process(Message message) {
 String now =formatter.format(new Date());
 String end = formatter.format("01-12-2017");

 Date endDay = formatter.parse(end);
 Date currentDay = formatter.parse(now);

 if(endDay.before(currentDay)){
    System.out.println("Send a notification indicating the end day has been reached, so the message is not processed.");
 }else {
    System.out.println("Process the message and applies some business rules");
 }
}

我知道代码不是最好的,但是160,000个事务中的3个已经失败并且if块中的代码被执行了。我打算使用日历,但这里可能发生了什么?

2 个答案:

答案 0 :(得分:4)

TL;博士

使用线程安全的java.time类而不是thread- unsafe 旧版SimpleDateFormat类。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uuuu" ) ;
ZoneId z = ZoneId.of( "America/Montreal" ) ;
…
LocalDate.parse( "01-12-2017" , f )
         .isBefore( LocalDate.now( z ) )

旧版日期时间类不是线程安全的

我注意到您使用singleton作为格式化程序,SimpleDateFormat的单个静态实例。那个legacy thread-safe,如JavaDoc类所述:

  

<强>同步

     

日期格式未同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问格式,则必须在外部进行同步。

您的偶然错误报告似乎没有任何正当理由告诉我您一次使用该对象来自多个线程。名为process的静态方法,以及您在服务器评论中的提及,让我更加怀疑。在运行时偶尔会遇到线程之间的冲突。

避免使用旧版日期时间类。

您使用的是麻烦的旧日期时间类,现在是legacy,取而代之的是java.time类。许多java.time功能都被反向移植到Java 6&amp; 7 ThreeTen-Backport

java.time类使用immutable objects,并且设计为线程安全的。所以说package documentation

LocalDate

您正在使用日期时间对象作为仅日期值。 java.time类包含一种表示仅限日期的方法。 LocalDate类表示没有时间且没有时区的仅限日期的值。

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId类是线程安全的。因此,您可以保留一个实例,以便跨线程重复使用。

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

将日期表示为字符串时,我建议使用标准ISO 8601格式。仅限日期,即YYYY-MM-DD,例如2017-01-23。在解析/生成字符串时,java.time类默认使用这些标准格式。

LocalDate target = LocalDate.parse( "2017-01-23" );

如果格式无法控制,请使用DateTimeFormatter,如许多其他问题&amp;堆栈溢出的答案。此类 是线程安全的,因此您可以保留一个实例,以便跨线程重复使用。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uuuu" );
LocalDate target = LocalDate.parse( "01-12-2017" , f );

isEqualisBeforeisAfter等方法进行比较。

if( target.isBefore( today ) ){
    System.out.println( "Send a notification indicating the end day has been reached, so the message is not processed." );
} else {
    System.out.println( "Process the message and applies some business rules" );
}

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

答案 1 :(得分:0)

您认为Javas class LinearEquations[T <% Double](var y: MLVector[T],var rows: MLMatrix[T]) { def largestPivot(p: Int): Int = { var pivot = rows(p)(p).abs //Error here: value abs is not a member of type parameter T //more code } 库不是最适合处理日期的库。特别是当我们谈论type MLMatrix[T] = Array[Array[T]] 时。

我的建议是与 Joda Time 取得联系。 Here您可以找到图书馆所需的一切。根据我的个人经验,它的工作方式更稳定,更容易理解。