1

I have two times opening and close. I want to generate as much slot which can be accommodate within defined range with fixed number of minutes. For e.g opening time: 12:30 pm and close timing: 3:30 pm respectively. So in this particular range i have to add minutes let's say 15 min increment every time until the time reaches to close time. Like 12:45, 12:30, ........ , 3:15, 3:30 pm exactly here i want to finish the loop but in my case it goes up to 12:06 am from 12:30 pm

        String newTime = "";
        SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a");
        Date date = dateFormat.parse(_model.getClinic_time_from());
        SimpleDateFormat dateFormat1 = new SimpleDateFormat("hh:mm a");
        Date date1 = dateFormat1.parse(_model.getClinic_time_to());

        Date temp = date;
        while (date1.compareTo(temp) < 0)
            {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(temp);
                calendar.add(Calendar.MINUTE, Integer.parseInt(_model.getSlot()));
                newTime = dateFormat.format(calendar.getTime());
                Apt_time_model ap = new Apt_time_model(dateFormat.format(temp.getTime()),newTime,"no status");

                    Apt_time_model ap1 = new Apt_time_model(ap.getApt_time_from(), ap.getApt_time_to(),ap.getStatus());
                    list.add(ap1);
                temp = dateFormat.parse(newTime);
            }
Kasım Özdemir
  • 5,414
  • 3
  • 18
  • 35
Azhar Bhatti
  • 91
  • 1
  • 3
  • 14
  • 1) Why are you creating two formatters for the same format? Get rid of `dateFormat1`. --- 2) Bad naming: `date`, `date1`, and `temp`. The names don't help identify what they are, so it's too easy to misuse them, as it seems you have. Give them better names, e.g. `fromTime`, `toTime`, and `currTime`. --- 3) `while (date1.compareTo(temp) < 0)` aka `while (toTime.compareTo(currTime) < 0)` makes no sense, since `toTime` by nature will be `> currTime`, so the loop is never executed. --- 4) Don't set `temp` (aka `currTime`) by parsing `newTime`. Use `calendar.getTime()`, which you already called. – Andreas Apr 11 '20 at 17:22
  • Thank You. Acknowledged! – Azhar Bhatti Apr 11 '20 at 17:27
  • 1
    Don’t put times as strings in your model. `model.getClinic_time_from()` should return a `LocalTime` and `model.getSlot()` an `int` (also variable names in Java begin with a lower case letter and don’t contain any underscores). Also put `LocalTime` objects into your newly created `AptTimeModel`. – Ole V.V. Apr 11 '20 at 18:17

1 Answers1

3

tl;dr

List < LocalTime > slots = new ArrayList <>();
for ( LocalTime lt = open ; lt.isBefore( close ) ; lt = lt.plusMinutes( 15 ) ) { slots.add( lt ); }

slots.toString(): [12:30, 12:45, 13:00, 13:15, 13:30, 13:45, 14:00, 14:15, 14:30, 14:45, 15:00, 15:15]

Details

You are using terrible date-date classes that were years ago supplanted by the modern java.time classes defined in JSR 310. For older Java, see the ThreeTen-Backport project. For older Android, see the ThreeTenABP project.

For time-of-day without a date and without a time zone, use LocalTime class.

12:30 pm and close timing: 3:30 pm

final LocalTime open = LocalTime.of( 12 , 30 );
final LocalTime close = LocalTime.of( 15 , 30 );

while loop

Loop in 15 minute increments until you reach the close time. Compare by calling equals, isBefore, or isAfter.

List < LocalTime > slots = new ArrayList <>();
LocalTime lt = open;
while ( lt.isBefore( close ) )
{
    slots.add( lt );
    lt = lt.plusMinutes( 15 );
}

System.out.println( "slots = " + slots );

See this code run live at IdeOne.com.

slots = [12:30, 12:45, 13:00, 13:15, 13:30, 13:45, 14:00, 14:15, 14:30, 14:45, 15:00, 15:15]

for loop

Some folks might prefer a one-liner for loop, for the same effect.

List < LocalTime > slots = new ArrayList <>();
for ( LocalTime lt = open ; lt.isBefore( close ) ; lt = lt.plusMinutes( 15 ) ) { slots.add( lt ); }

Or:

List < LocalTime > slots = new ArrayList <>();
for ( LocalTime lt = open ;
      lt.isBefore( close ) ;
      lt = lt.plusMinutes( 15 ) )
{
    slots.add( lt );
}

Stream

Perhaps there might be some clever way to accomplish this with Java streams. But I cannot think of any.

Presentation

Generate text representing the meaning within each LocalTime object you collected.

Be clear that a LocalTime is not a String, and a String is not a LocalTime, but a String object can hold text that happens to represent the content of a LocalTime object.

Locale locale = Locale.US;  // Or Locale.CANADA_FRENCH etc. 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( locale );
for ( LocalTime slot : slots )
{
    String output = slot.format( f );
    System.out.println( "output = " + output );
}

output = 12:30 PM

output = 12:45 PM

output = 1:00 PM


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.

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

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

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?

Table of which java.time library to use with which version of Java or Android

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Can you tell me how this logic works? (lt.isBefore( close )) – Azhar Bhatti Apr 11 '20 at 17:29
  • I'd recommend using a for-each loop, to keep the loop logic together: `for (LocalTime time = open; time.isBefore(close); time = time.plusMinutes(15)) { slots.add(time); }` – Andreas Apr 11 '20 at 17:29
  • 2
    @AzharBhatti Look at the documentation of [`LocalTime`](https://docs.oracle.com/javase/8/docs/api/java/time/LocalTime.html) to see what the various methods do. The method name seems pretty straightforward though: It returns true if the `lt` time *is before* the `close` time. – Andreas Apr 11 '20 at 17:30
  • After implementing this technique still get the same result – Azhar Bhatti Apr 11 '20 at 19:05
  • 2
    @AzharBhatti I added a [link to IdeOne.com](https://ideone.com/IFgUYx) to prove this code works. – Basil Bourque Apr 11 '20 at 19:46
  • @Andreas I added the `for` loop per your suggestion. – Basil Bourque Apr 11 '20 at 19:53
  • @BasilBourque I got it now the problem is your time has 24 - format on the other hand i am working with am/pm. What do you say? – Azhar Bhatti Apr 11 '20 at 20:00
  • 1
    @AzharBhatti Separate your [data model](https://en.wikipedia.org/wiki/Data_model) from your presentation strings. Generate objects as shown here. When presenting to the user, use [`DateTimeFormatter.ofLocalizedTime`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html#ofLocalizedTime(java.time.format.FormatStyle)) to generate text representing the value within the `LocalTime` objects. The `DateTimeFormatter` class has been covered many many times already on Stack Overflow. So search to learn more. – Basil Bourque Apr 11 '20 at 20:03