我的日期是字符串“05/30/2018”的形式,我想确定它是在当前这周。我使用这种方法将其转换为日期格式:
public Date convertStringToDate(String dateString) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
Date dateInString = null;
try {
Date date = formatter.parse(dateString);
dateInString = date;
System.out.println(date);
System.out.println(formatter.format(date));
} catch (ParseException e) {
e.printStackTrace();
}
return dateInString;
}
要检查它是否在同一周内使用此方法:
public boolean isDateInCurrentWeek(Date date) {
Calendar currentCalendar = Calendar.getInstance();
int week = currentCalendar.get(Calendar.WEEK_OF_YEAR);
int year = currentCalendar.get(Calendar.YEAR);
Calendar targetCalendar = Calendar.getInstance();
targetCalendar.setTime(date);
int targetWeek = targetCalendar.get(Calendar.WEEK_OF_YEAR);
int targetYear = targetCalendar.get(Calendar.YEAR);
boolean belongs = (week == targetWeek && year == targetYear);
return belongs;
}
我使用这两种方法:
if(CustomDateClass.isDateInCurrentWeek(convertStringToDate(trans.getTransactionDate()))){
// perform some task
}
验证总是失败,即使在今天的日期也会在每个日期产生错误。我查看了其他问题中提出的其他方法,结果是一样的。我错过了什么导致该方法不能产生正确的结果。
答案 0 :(得分:2)
问题是日期格式05/30/2018
与dd/MM/yyyy
不匹配。
改为使用MM/dd/yyyy
。
答案 1 :(得分:2)
org.threeten.extra.YearWeek.from( // Represent a standard ISO 8601 week, starting on a Monday, where week # 1 contains first Thursday of the calendar year.
java.time.LocalDate.parse( // Parse an input string into a `LocalDate` object, representing a date-only value without time-of-day and without time zone.
"05/30/2018" ,
DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) // Define a formatting pattern to match the input string. The Question’s code failed to do so correctly.
)
) // Returns a `YearWeek` object.
.equals(
YearWeek.now( // Get the current standard ISO 8601 week.
ZoneId.of( "Atlantic/Canary" ) // Get the week for today’s date as seen in the wall-clock time in use by the people of a certain region (a time zone).
) // Returns a `YearWeek` object.
)
Answer by Arvind是正确的,因为格式化模式无法与输入字符串匹配。但是你也有其他问题。
你正在使用几年前由现代 java.time 类取代的糟糕的旧日期时间类。
LocalDate
解析将输入字符串解析为LocalDate
。顺便说一下,在将日期时间值作为文本交换时,尽可能使用标准ISO 8601格式。
String input = "05/30/2018" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
ld.toString():2018-05-30
您必须定义“周”的含义。您使用麻烦的Calendar
类会导致一周由JVM当前Locale
的文化规范定义。
我怀疑您可能希望在一周的定义中更加具体,以便您的结果在运行时不会发生变化。
例如,我们可以使用标准ISO 8601 definition of week。标准周从星期一开始,第1周有日历年的第一个星期四。这一年持有52或53周。该日历年的最后/前几天可能会在下一个/上一周的基础上着陆。
我们可以使用IsoFields
枚举来访问LocalDate
的基于周的年份和周数。
int weekOfWeekBasedYear = ld.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int weekBasedYear = ld.get ( IsoFields.WEEK_BASED_YEAR );
让我们以标准的ISO 8601格式制作这些值的字符串。该标准要求我们使用a leading zero填充任何一位数的周数。
String weekIso =
weekBasedYear +
"-W" +
String.format("%02d", weekOfWeekBasedYear)
;
2018-W22
您想要将输入日期的周与当前周进行比较。要获得当前的一周,我们需要当前的日期。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。
如果未指定时区,则JVM会隐式应用其当前的默认时区。该默认值可能随时更改,因此您的结果可能会有所不同。最好明确指定您期望/预期的时区作为参数。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
如果要使用JVM的当前默认时区,请求它并作为参数传递。如果省略,则隐式应用JVM的当前默认值。最好是明确的,因为默认情况下可以在运行时期间由JVM中任何应用程序的任何线程中的任何代码随时更改。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
int todayWeekOfWeekBasedYear = ld.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int todayWeekBasedYear = ld.get ( IsoFields.WEEK_BASED_YEAR );
按照上面的说法创建一个字符串。
String todayWeekIso = todayWeekBasedYear + "-W" + String.format("%02d", todayWeekOfWeekBasedYear) ;
比较
boolean isDateInCurrentWeek = weekIso.equalsIgnoreCase( todayWeekIso ) ;
DateTimeFormatter.ISO_WEEK_DATE
而不是提取一周&用于构建String的年份数字,我们可以让DateTimeFormatter
执行相同的工作。常量DateTimeFormatter.ISO_WEEK_DATE
生成标准ISO 8601周格式的字符串,包括星期几编号(星期一到星期日为1-7)。
String inputWeekDate = ld.format( DateTimeFormatter.ISO_WEEK_DATE ) ;
2018-W22-3
本周做同样的事情。
String currentWeekDate = today.format( DateTimeFormatter.ISO_WEEK_DATE ) ;
2018-W22-3
截断最后两个字符,连字符和星期几。
String inputWeek = inputWeekDate.substring( 0 , 8 ) ;
String currentWeek = currentWeekDate.substring( 0 , 8 ) ;
比较
boolean isDateInCurrentWeek = inputWeek.equalsIgnoreCase( currentWeek ) ;
如果我们将ThreeTen-Extra库添加到项目中,这项处理周的工作会更容易。然后我们可以使用它的YearWeek
类。
YearWeek yearWeekThen = YearWeek.from( ld ) ;
YearWeek yearWeekNow = YearWeek.now( ZoneId.of( "Europe/Berlin" ) ) ;
boolean isDateInCurrentWeek = yearWeekThen.equals( yearWeekNow ) ;
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。