Erent
Erent

Reputation: 621

Java verify that date is in current week

I have a date which is in the form of a string "05/30/2018" and i want to determine that it is in this current week.I convert it to date format using this method:

    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;
}

And to check if its within the same week i use this method :

    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;
}

And i use both methods like this:

 if(CustomDateClass.isDateInCurrentWeek(convertStringToDate(trans.getTransactionDate()))){
// perform some task
}

The verification always fails and produces a false on every date even today's date. I have looked at other methods suggested in other questions and the results are the same. What could i have missed that is causing the method not to produce the correct result.

Upvotes: 0

Views: 1523

Answers (2)

Basil Bourque
Basil Bourque

Reputation: 338276

tl;dr

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.
)

Details

The Answer by Arvind is correct in that your formatting patterns fails to match your input string. But you have other problems too.

java.time

You are using terrible old date-time classes that were supplanted years ago by the modern java.time classes.

LocalDate parsing

Parse your input string as a LocalDate. By the way, whenever possible, use standard ISO 8601 format when exchanging date-time values as text.

String input = "05/30/2018" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;

ld.toString(): 2018-05-30

Define week

You must define what you mean by "week". Your use of the troublesome Calendar class results in a week defined by the cultural norms of the JVM’ current Locale.

I suspect you may wish to be more specific in your definition of a week, so that your results do not vary at runtime.

For example, we could use the standard ISO 8601 definition of week. The standard week starts on a Monday, and week # 1 has the first Thursday of the calendar year. The year holds either 52 or 53 weeks. The last/first few days of the calendar year may land in the next/previous week-based year.

We can access the week-based year and week number of a LocalDate by using the IsoFields enum.

int weekOfWeekBasedYear = ld.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int weekBasedYear = ld.get ( IsoFields.WEEK_BASED_YEAR );

Let's make a string of those values in standard ISO 8601 format. The standard requires we pad any single-digit week number with a leading zero.

String weekIso = 
    weekBasedYear + 
    "-W" + 
    String.format("%02d", weekOfWeekBasedYear) 
;

2018-W22

Current week

You want to compare your input date’s week to the current week. To get the current week, we need the current date.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

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

If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit, as the default may be changed at any moment during runtime by any code in any thread of any app within the 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 );

Make a String as we did above.

String todayWeekIso = todayWeekBasedYear + "-W" + String.format("%02d", todayWeekOfWeekBasedYear) ;

Compare.

boolean isDateInCurrentWeek = weekIso.equalsIgnoreCase​( todayWeekIso ) ;

Shortcut: DateTimeFormatter.ISO_WEEK_DATE

Rather than extracting the week & year numbers to build a String, we can let a DateTimeFormatter do that same work. The constant DateTimeFormatter.ISO_WEEK_DATE generates a String in standard ISO 8601 week format, including the day-of-week number (1-7 for Monday-Sunday).

String inputWeekDate = ld.format( DateTimeFormatter.ISO_WEEK_DATE ) ;

2018-W22-3

Do the same for the current week.

String currentWeekDate = today.format( DateTimeFormatter.ISO_WEEK_DATE ) ;

2018-W22-3

Truncate the last two characters, the hyphen and day-of-week number.

String inputWeek = inputWeekDate.substring( 0 , 8 ) ;
String currentWeek = currentWeekDate.substring( 0 , 8 ) ;

Compare.

boolean isDateInCurrentWeek = inputWeek.equalsIgnoreCase​( currentWeek ) ;

ThreeTen-Extra library

This work of handling weeks is easier if we add the ThreeTen-Extra library to our project. Then we can make use of its YearWeek class.

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

boolean isDateInCurrentWeek = yearWeekThen.equals( yearWeekNow ) ;

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Upvotes: 4

user2575725
user2575725

Reputation:

Problem is that the date format 05/30/2018 does not matches dd/MM/yyyy.

Use instead MM/dd/yyyy.

Upvotes: 1

Related Questions