2

I am trying to get week number of given date that lies between start and end date. Below is the code i have used to get but it works only for 4 weeks.

I need it to make it to work for any number of weeks.

public static int getWeekNO( Timestamp startTime,Timestamp endTime , Timestamp dateTime) throws RuntimeException {

        String formatted = null;
        Timestamp currentTimestamp;
        int weekNumber = 0;

        logger.debug("startTime"+startTime);
        logger.debug("endTime"+endTime);
        logger.debug("dateTime"+dateTime);
        try {
            String formatDateFirst =  "";
            String formatDateSecond = "";
            String formatDateThird = "";
            String formatDateFourth = "";
            String givenDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dateTime);
            String startDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(startTime);
            String endDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(endTime);
            logger.debug("givenDateString"+givenDateString);
            logger.debug("startDateString"+startDateString);
            logger.debug("endDateString"+endDateString);


            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            Calendar c = Calendar.getInstance();
            Date givenDate = sdf.parse(givenDateString);
            Date startDate = sdf.parse(startDateString);
            Date endDate = sdf.parse(endDateString);

            logger.debug("givenDate"+givenDate);
            logger.debug("startDate"+startDate);
            logger.debug("endDate"+endDate);

            c.setTime(sdf.parse(startDateString));

            c.add(Calendar.DAY_OF_MONTH, 6); // number of days to add
            formatDateFirst = sdf.format(c.getTime());
            Date firstWeekDate = (Date) sdf.parse(formatDateFirst);
            logger.debug("endDate"+firstWeekDate);

            c.add(Calendar.DAY_OF_MONTH, 7); // number of days to add
            formatDateSecond = sdf.format(c.getTime());
            Date secondWeekDate = (Date) sdf.parse(formatDateSecond);
            logger.debug("endDate"+secondWeekDate);

            c.add(Calendar.DAY_OF_MONTH, 7); // number of days to add
            formatDateThird = sdf.format(c.getTime());
            Date thirdWeekDate = (Date) sdf.parse(formatDateThird);
            logger.debug("endDate"+thirdWeekDate);

            c.add(Calendar.DAY_OF_MONTH, 7); // number of days to add
            formatDateFourth = sdf.format(c.getTime());
            Date fourthWeekDate = (Date) sdf.parse(formatDateFourth);
            logger.debug("endDate"+fourthWeekDate);


            if (givenDate.compareTo(firstWeekDate) <= 0) {
                weekNumber = 1;
            } else if (givenDate.compareTo(secondWeekDate) <= 0
                    && givenDate.compareTo(firstWeekDate) > 0) {
                weekNumber = 2;
                } else if (givenDate.compareTo(thirdWeekDate) <= 0
                    && givenDate.compareTo(secondWeekDate) > 0) {
                    weekNumber = 3;
            }else if (givenDate.compareTo(fourthWeekDate) <= 0
                    && givenDate.compareTo(thirdWeekDate) > 0) {
                    weekNumber = 4;
            }else{
                logger.debug("Not a Valid Date");
            }

        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        return weekNumber;
    } 

Example:

  start Timestamp: 09/04/2016 00:00:00,End Timestamp: 28/06/2016 00:00:00. Given Timestamp : 15/05/2016 00:00:00

so here:week 1:09/04/2016 - 15/04/2016
        week 2:16/04/2016 - 22/04/2016
        week 3:23/04/2016 - 29/04/2016
        week 4:30/04/2016 - 06/05/2016
        week 5:07/05/2016 - 13/05/2016
        week 6:14/05/2016 - 20/05/2016 -- my given timestamp falls here
        week 7:21/05/2016 - 27/05/2016
        week 8:28/05/2016 - 03/06/2016

so now my output for week no should be week:6 

Here i am using java 1.7 so i am not able to use -- import java.time.LocalDateTime; import java.time.temporal.ChronoUnit;

How could i achieve, this please help me on this.

dafodil
  • 531
  • 15
  • 30
  • 2
    Use [Joda Time](http://www.joda.org/joda-time/). – Elliott Frisch Jun 04 '16 at 02:33
  • @Elliott Frisch Joda time is present in Java SE 8,i am working on java SE 7 built project – dafodil Jun 04 '16 at 02:56
  • @dafodil No, [Joda-Time](http://www.joda.org/joda-time/) is a 3rd-party library, not part of Java. I suspect you are thinking of [java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) which is built into Java 8 and later, supplants the old date-time classes, and inspired by Joda-Time. The Joda-Time team has advised users to migrate to java.time. Much of java.time functionality is back-ported in [ThreeTen-Backport](http://www.threeten.org/threetenbp/), and further adapted to Android in [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP). – Basil Bourque Jun 04 '16 at 05:27
  • @Basil Bourque your comment was informative,thanks for that.But i should not use any third party library also as i am working on already bulit project ,it should be maintained by existing libraries and api's . – dafodil Jun 04 '16 at 05:30
  • @dafodil Are you asking: For a given interval (a pair of date-time values), how many weeks past that interval’s start is a particular date-time value (a third and separate date-time value)? – Basil Bourque Jun 04 '16 at 05:31
  • @Basil Bourque Please look my updated question i have explained with example. – dafodil Jun 04 '16 at 05:59
  • @dafodil So that would be a “Yes” to my question? If so I suggest you edit your Question to have a similar short summary of your issue. Also, how *exactly* do you define a week? Is it seven days from whatever start date is submitted? And, what is the point of the second argument, the `End Timestamp`? Seems irrelevant to me, unless you want to check that the "Given Timestamp" is before the "End". Tip: Your example data would be easier to read by the international audience here on Stack Overflow if you stuck with ISO 8601 formats (as does your input data apparently). – Basil Bourque Jun 04 '16 at 06:03
  • @Basil Bourque .Yes it would be 7 days for a week.End Timestamp is to just check whether given date falls in given date range. – dafodil Jun 04 '16 at 06:11

2 Answers2

0
    public static int getWeekNO(Timestamp startTime, Timestamp endTime, Timestamp dateTime) {
      if (dateTime.compareTo(startTime) < 0 || dateTime.compareTo(endTime) > 0) {
        System.out.println("Not a Valid Date");
        return -1;
      }
      return (int) ((dateTime.getTime() - startTime.getTime() - 1) / (1000L * 3600 * 24 * 7)) + 1;
    }

edit:

As request, updated the answer,

public static int getWeekNO(Timestamp startTime, Timestamp endTime, Timestamp dateTime) {
  if (dateTime.compareTo(startTime) < 0 || dateTime.compareTo(endTime) > 0) {
    System.out.println("Not a Valid Date");
    return -1;
  }
  int dayDiff = (int) ((dateTime.getTime() - startTime.getTime()) / (1000L * 3600 * 24)) + 1;
  int week = dayDiff / 7;
  return dayDiff % 7 == 0 ? week : week + 1;
}

Notice: Be careful about the constructor of Date/Timestamp,

  Timestamp startTime = new Timestamp(2016, 5, 30, 0, 0, 0, 0);
  Timestamp dateTime = new Timestamp(2016, 6, 6, 0, 0, 0, 0);

This constructor the month starts with 0. So the above code is comparing 2016-4-30 to 2016-5-6. It's only one week.

waltersu
  • 1,191
  • 8
  • 20
  • If you want to ignore "HH:mm:ss", just reset three values of three inputs to zero. It's not included in the answer. – waltersu Jun 04 '16 at 05:47
  • How to reset "HH:mm:ss" values,Can you show in code ,i searched in google it shows only calender reset. – dafodil Jun 04 '16 at 07:48
  • if i give startdate as 2016, 05, 17 and dateTime as 2016, 06, 01 it gives 2 week instead of 3 week.How could i correct it – dafodil Jun 13 '16 at 06:39
  • @dafodil It's edge situation. My calculation is from 2016-05-17 00:00 to 2016-06-01 00:00. The duration is exactly 2 weeks. You can say it's the end of 2 week, or you can say it's the start of 3 week, it's totally ok. It's your decision. Just remove the *-1* from the last line. – waltersu Jun 13 '16 at 08:17
  • it should not only limit for particular interval,whatever date interval i give it has to work for that.Could you please help me on this – dafodil Jun 13 '16 at 08:43
  • if startTime = 2016, 04, 25 and dateTime = 2016,05,1,its returning week as 2,But according to calender its week 1 as i am starting from 25th to of april to may 1st,7 days totally. How is this getting changed? – dafodil Jun 13 '16 at 09:40
  • Oops. I forgot to adjust weeks calculation. I've updated my answer. Sorry for wasting your time. – waltersu Jun 13 '16 at 09:45
  • starttime - 2016, 05,30 datetime - 2016,06,6 returns week as 1,instead of week 2.Why i am getting like this? – dafodil Jun 13 '16 at 10:03
  • @dafodil same result returning week as 1 instead of 2 – dafodil Jun 13 '16 at 10:23
  • same result returning week as 1 instead of 2.for starttime - 2016, 05,30 datetime - 2016,06,6 – dafodil Jun 13 '16 at 10:52
  • @dafodil It returns 2. Please check the *notice* part of the answer. Thanks. – waltersu Jun 13 '16 at 11:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/114520/discussion-between-waltersu-and-dafodil). – waltersu Jun 13 '16 at 11:20
0

Using java.time

Do not use java.sql.Timestamp for business logic. That class is only for exchanging data with your database. And even that purpose is now supplanted by the java.time classes. For Java 7, use the back-port of java.time listed in bullets below.

The troublesome old date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleTextFormat are now legacy, supplanted by the java.time classes.

DayOfWeek

Specify the day-of-week you consider to be the beginning of a week. Use aDayOfWeek enum object. By the ways, standard ISO 8601 week definition begins with Monday.

DayOfWeek dowStart = DayOfWeek.MONDAY ;

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone.

Specify your start/stop dates.

LocalDate start = LocalDate.parse( 2016 , 4 , 9 ) ; 
LocalDate stop = LocalDate.parse( 2016 , 6 , 28 ) ;
LocalDate first = start.with( TemporalAdjusters.previousOrSame( dowStart ) ) ;

List<LocalDate> dates = new ArrayList<>() ;
LocalDate ld = first ; // Initialize for loop.
while( ld.isBefore( stop ) ) {  // While the local date is before the stopping point.
    dates.add( ld ) ;
    // Prepare for next loop.
    ld = ld.plusWeeks( 1 ) ;
}

Now report on your week-starting dates in any manner you choose.

int i = 0 ;  // Initialize for loop.
for( LocalDate ld : dates ) {
    i ++ ;
    String output = "Week # " + i + ":" + ld + " - " + ld.plusDays( 6 ) ;
    …
}

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.

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154