Date Sorting in Java

Viewed 384

The Instruction was to create a Random dates for each object withn the range specified in the instructions below for the interview slot objects to be stored in . I am not exactly sure how to do this

Create a random number of InterviewSlot objects and store them in the slots container.
Use the Math.random() method to create variation in the objects created:

  • Make the range of variation of the dates in hours.
  • The range should be 30 days, meaning that the dates could vary between say, today and 30 days from now. The max of the range would be equal to 30*24.
  • You can set the minimum of the range to 1.
  • Make the duration vary between 1 and 60.

Examples of objects:

Thu Apr 02 05:28:59 EDT 2020 duration:18
Fri Mar 27 00:22:32 EDT 2020 duration:48
Wed Apr 01 20:22:32 EDT 2020 duration:8
Sat Mar 28 19:22:32 EDT 2020 duration:31

 

import java.util.Calendar;
import java.util.Date;







public class InterviewSlot implements Comparable<InterviewSlot> {

    Calendar cal = Calendar.getInstance();
    private Date startTime = cal.getTime();
    private Integer duration;

    public InterviewSlot(Date start, Integer d) {
        setDuration(d);
        setStartTime(start);

    }

    public void setDuration(Integer duration) {
        this.duration = duration;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Integer getDuration() {
        return duration;
    }

    public Date getStartTime() {
        return startTime;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Interview Start " + getStartTime() + "Duration :  " + getDuration();
    }

    @Override

    public int compareTo(InterviewSlot s) {
        return this.getStartTime().compareTo(s.getStartTime());
        // TODO Auto-generated method stub

    }

}


import java.awt.List;
import java.util.ArrayList;

public class DataCreator {

    public static <E extends Comparable<E>> void outputData(ArrayList<E> l) {
        for (E L : l) {
            System.out.println(L);
        }

    }

    public static void createIntegers(ArrayList<Integer> a, int num) {
        // double random = (int)(Math.random()*((100-1)+1))+1;
        for (int i = 0; i < num; i++) {
            Integer random = (int) (Math.random() * ((100 - 1) + 1)) + 1;
            a.add(random);

        }

        ;
    }

    public static void createData(ArrayList<InterviewSlot> slots, int num) {

    }

}
3 Answers

I will answer as if this is for real work, as you did not indicate explicitly schoolwork.

ThreadLocalRandom

Use ThreadLocalRandom to avoid any possible concurrency issues. There is no downside to using this class over Math.random. And this class has convenient methods for generating various types of numbers rather than just double.

java.time

Never use Calendar or Date. Those terrible date-time classes were supplanted years ago by the modern java.time classes defined in JSR 310.

Get today's date.

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

Add random number of days within next 30 days.

int days = ThreadLocalRandom.current().nextInt( 1 , 31 ) ;
LocalDate localDate = today.plusDays( days ) ;

Days vary in length, such as 23, 24, 25, or other number of hours. So for your date in your zone, calculate maximum number of seconds.

ZonedDateTime start = localDate.atStartOfDay( z ) ;
ZonedDateTime stop = localDate.plusDays( 1 ).atStartOfDay( z ) ;
Duration d = Duration.between( start.toInstant() , stop.toInstant() ) ;
long seconds = d.toSeconds() ;  // In Java 9 and later. For Java 8, call `Duration::getSeconds`.

That count of seconds becomes the maximum for our length of day. From this we pick a random number of seconds.

long secondsIntoDay = ThreadLocalRandom.current().nextInt( 0 , seconds ) ;
ZonedDateTime zdt = start.plusSeconds( secondsIntoDay ) ;

Determine a random duration from 1 to 60 minutes for the elapsed time of each event.

int minutes = ThreadLocalRandom.current().nextInt( 1 , 61 ) ; // At least one minute, and less than 61 minutes.
Duration duration = Duration.ofMinutes( minutes ) ;

Define your public class InterviewSlot with two member fields: a ZonedDateTime and a Duration.

Simple solution with date for your spezific case, including an example:

import java.util.Date; import java.util.Random;

import org.apache.commons.lang3.time.DateUtils;

public class SimpleDateGenerator {
    private static Random random = new Random();

    public static Date getRandomDate(Date start, long timerangeSeconds) {
        int randomTime = (int) Math.ceil(random.nextDouble() * timerangeSeconds);
        return DateUtils.addSeconds((Date) start.clone(), randomTime);
    }

    public static void main(String[] args) {
        Date now = new Date();
        System.out.println(now);
        for (int i = 0; i < 10; i++) {
            System.out.println(getRandomDate(now, 30 * 24 * 60 * 60));
        }

    }

}

main gives following (example) output:

Tue Mar 31 08:26:14 CEST 2020
Sun Apr 19 16:06:48 CEST 2020
Fri Apr 03 20:49:58 CEST 2020
Wed Apr 22 22:27:00 CEST 2020
Mon Apr 06 03:39:48 CEST 2020
Wed Apr 22 19:13:28 CEST 2020
Fri Apr 03 12:36:16 CEST 2020
Wed Apr 22 20:27:35 CEST 2020
Mon Apr 06 13:58:37 CEST 2020
Fri Apr 03 03:57:17 CEST 2020
Wed Apr 15 09:05:47 CEST 2020

As per @Basil Bourque suggestion the following code should do the trick :

import java.time.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

public static void main(String[] args) {
    int numberOfRandomDates = 10;
    ArrayList<InterviewSlot>  interviewSlotArrayList= new ArrayList<>();
    for (int i = 0; i< numberOfRandomDates ; i++) {
        InterviewSlot interviewSlot = calculateInterviewSlot();
        interviewSlotArrayList.add(interviewSlot);
        System.out.println(interviewSlot);
    }

    Collections.sort(interviewSlotArrayList);
    System.out.println("After sorting: \n");

    //Using lamda
    interviewSlotArrayList.forEach(element -> {
        System.out.println(element);
    });

    //or Using method reference
    interviewSlotArrayList.forEach(System.out::println);
  }

    public static InterviewSlot calculateInterviewSlot() {
        //Getting time zone id and setting local time according to the time zone
        ZoneId z = ZoneId.of("America/Montreal");
        LocalDate today = LocalDate.now(z);

        //Getting a random day between 1 and 31 and adding it to the current date
        int days = ThreadLocalRandom.current().nextInt(1, 31);
        LocalDate localDate = today.plusDays(days);

        //Getting start and end time of the day as per time zone.End time is taken as next day start time(24 hr)
        ZonedDateTime start = localDate.atStartOfDay(z);
        ZonedDateTime stop = localDate.plusDays(1).atStartOfDay(z);

        //Duration is taken which is the max duration for that time zone.
        Duration duration = Duration.between(start.toInstant(), stop.toInstant());
        long seconds = TimeUnit.SECONDS.convert(duration.toNanos(), TimeUnit.NANOSECONDS);

        //Calculating random no of seconds keeping the computed seconds as max seconds in the day
        long secondsIntoDay = ThreadLocalRandom.current().nextInt(0, Math.toIntExact(seconds));
        ZonedDateTime zonedDateTime = start.plusSeconds(secondsIntoDay);

        //Calculating random no of minutes for duration
        int minutes = ThreadLocalRandom.current().nextInt(1, 61);
        Duration durationMinutes = Duration.ofMinutes(minutes);

        return new InterviewSlot(zonedDateTime, durationMinutes);
    }
}

InterviewSlot.java :

public class InterviewSlot implements Comparable<InterviewSlot> {

    private ZonedDateTime startTime;
    private Duration duration;

    public InterviewSlot() {
    }

    public InterviewSlot(ZonedDateTime startTime, Duration duration) {
        this.startTime = startTime;
        this.duration = duration;
    }

    public ZonedDateTime getStartTime() {
        return startTime;
    }

    public void setStartTime(ZonedDateTime startTime) {
        this.startTime = startTime;
    }

    public Duration getDuration() {
        return duration;
    }

    public void setDuration(Duration duration) {
        this.duration = duration;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Interview Start " + getStartTime() + " Duration :  " + getDuration();
    }

    @Override

    public int compareTo(InterviewSlot s) {
        return this.getStartTime().compareTo(s.getStartTime());
        // TODO Auto-generated method stub

    }

}

Generated sample output :

Interview Start 2020-04-24T02:16:09-04:00[America/Montreal] Duration :  PT12M
Interview Start 2020-04-04T20:58:43-04:00[America/Montreal] Duration :  PT38M
Interview Start 2020-04-25T00:09:12-04:00[America/Montreal] Duration :  PT31M
Interview Start 2020-04-03T20:26:01-04:00[America/Montreal] Duration :  PT22M
Interview Start 2020-04-06T03:48:29-04:00[America/Montreal] Duration :  PT45M
Interview Start 2020-04-15T07:56:32-04:00[America/Montreal] Duration :  PT34M
Interview Start 2020-04-21T09:25:15-04:00[America/Montreal] Duration :  PT44M
Interview Start 2020-04-30T18:33:40-04:00[America/Montreal] Duration :  PT52M
Interview Start 2020-04-16T07:12:54-04:00[America/Montreal] Duration :  PT14M
Interview Start 2020-04-24T17:02:48-04:00[America/Montreal] Duration :  PT50M
Related