1

I am trying to write a method which takes two java.util.Date's as parameters and returns a random java.util.Date between these two in Scala. However, I get the same dummy result each time. What is wrong with my code?

Note:

randomDateBetween(new Date(2017, 1, 1), new Date(2018, 1, 1)) returns Tue Jun 12 09:36:00 EET 3917 like all the time

Code:

 def randomDateBetween( firstDate : Date, secondDate : Date) : Date =
  {
    val ratio = new Random().nextInt(100);

    val difference = (secondDate.getTime - firstDate.getTime)

    val surplusMillis = (difference * (ratio / 100.0)).asInstanceOf[Long]
    
    val cal = Calendar.getInstance()

    cal.setTimeInMillis(surplusMillis + firstDate.getTime)

    return cal.getTime()
  } 

I fixed it guys, thank you anyway. Cause of the error was java.util.Date being deprecated. I changed my method call like this and it worked perfectly fine:

val date1 = Calendar.getInstance
val date2 = Calendar.getInstance

date1.set(2017, 1, 1)
date2.set(2018, 1, 1)

randomDateBetween(date1.getTime, date2.getTime)
Community
  • 1
  • 1
Enes Keles
  • 141
  • 1
  • 15
  • It's not that it is deprecated, it's that you don't read the doc: " year the year minus 1900." – Dima Jul 13 '17 at 22:44

3 Answers3

3

You need to seed the Random object like so:

Random.setSeed(System.currentTimeMillis())
val ratio = new Random().nextInt(100)
sheunis
  • 1,494
  • 11
  • 10
2

(Java syntax here, rather than Scala)

ThreadLocalRandom

The Answer by sheunis is correct but outdated.

Another outdated option is Math.random.

randomNum = minimum + ( int )( Math.random() * maximum ); 

The modern approach since Java 7 is ThreadLocalRandom. See this Answer.

long random = ThreadLocalRandom.current().nextLong( minimum , maximum + 1 );

Both of these alternatives to Random are initialized with an internally generated seed that may not otherwise be modified.

Avoid legacy date-time classes.

Also you are using troublesome old date-time classes Date and Calendar that are now legacy, supplanted by java.time classes.

Using java.time

For date-only values without time-of-day and without time zone, use LocalDate class.

LocalDate start = LocalDate.of( 2017 , Month.JANUARY , 1 ) ;
LocalDate stop = LocalDate.of( 2018 , Month.JANUARY , 1 ) ;

Count days between, to determine random number of days.

long maxDays = ChronoUnit.DAYS.between( start , stop ) ;

So we want to add a random number of days, as little as zero and as much as maxDays.

long days = ThreadLocalRandom.current().nextLong( 0 , maxDays + 1 );

LocalDate ld = start.plusDays( days ) ;
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0
 Date randomDate= new Date(ThreadLocalRandom.current().nextLong(fromDate.getTime(), toDate.getTime()+1));

I don't know much about scala. I have tested it in java, I think this solution is applicable for scala as well. Please modify the code if needed.

Ashish Lohia
  • 269
  • 1
  • 12