gpt4 book ai didi

java - 有时 java.util.Date 之前会失败

转载 作者:行者123 更新时间:2023-12-01 17:59:28 24 4
gpt4 key购买 nike

我支持进行日期比较的 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 block 中的代码被执行。我计划使用日历,但是这里可能发生了什么?

最佳答案

tl;博士

使用线程安全java.time类,而不是线程不安全遗留的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 类中所述:

Synchronization

Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

您对似乎没有充分理由的偶尔错误的报告表明,您一次从多个线程中使用该对象。名为 process 的静态方法,以及您在服务器注释中的提及,让我更加怀疑。在运行时,您偶尔会遇到线程之间的冲突。

避免遗留日期时间类。

您正在使用麻烦的旧日期时间类,现在是 legacy ,被 java.time 类取代。许多 java.time 功能已向后移植到 ThreeTen-Backport 中的 Java 6 和 7。 .

java.time 类使用 immutable objects ,并且被设计为线程安全的。 package documentation 就是这么说的。 .

本地日期

您正在将日期时间对象用于仅日期值。 java.time 类包含一种表示仅日期的方法。 LocalDate类表示仅日期值,没有时间和时区。

时区对于确定日期至关重要。对于任何特定时刻,全局各地的日期都会因地区而异。例如,Paris France 午夜过后几分钟Montréal Québec 是新的一天,但仍然是“昨天” .

指定proper time zone name格式为大洲/地区,如America/Montreal , Africa/Casablanca ,或太平洋/奥克兰。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的( !)。

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如 Stack Overflow 上的许多其他问题与解答所示。此类是线程安全的,因此您可以保留一个实例以便跨线程重复使用。

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

isEqualisBefore 等方法进行比较和 isAfter

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.Date , Calendar , & SimpleDateFormat .

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

要了解更多信息,请参阅 Oracle Tutorial 。并在 Stack Overflow 上搜索许多示例和解释。规范为JSR 310 .

从哪里获取java.time类?

关于java - 有时 java.util.Date 之前会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42207354/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com