Java验证日期是否在当前周

时间:2018-05-31 04:00:48

标签: java date java-date

我的日期是字符串“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
}

验证总是失败,即使在今天的日期也会在每个日期产生错误。我查看了其他问题中提出的其他方法,结果是一样的。我错过了什么导致该方法不能产生正确的结果。

2 个答案:

答案 0 :(得分:2)

问题是日期格式05/30/2018dd/MM/yyyy不匹配。

改为使用MM/dd/yyyy

答案 1 :(得分:2)

TL;博士

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

你正在使用几年前由现代 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/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的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

如果我们将ThreeTen-Extra库添加到项目中,这项处理周的工作会更容易。然后我们可以使用它的YearWeek类。

YearWeek yearWeekThen = YearWeek.from( ld ) ;
YearWeek yearWeekNow = YearWeek.now( ZoneId.of( "Europe/Berlin" ) ) ;

boolean isDateInCurrentWeek = yearWeekThen.equals( yearWeekNow ) ;

关于 java.time

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

现在位于Joda-Timemaintenance 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的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore