2010-10-21 137 views

Respuesta

65
import java.util.GregorianCalendar; 

public class RandomDateOfBirth { 

    public static void main(String[] args) { 

     GregorianCalendar gc = new GregorianCalendar(); 

     int year = randBetween(1900, 2010); 

     gc.set(gc.YEAR, year); 

     int dayOfYear = randBetween(1, gc.getActualMaximum(gc.DAY_OF_YEAR)); 

     gc.set(gc.DAY_OF_YEAR, dayOfYear); 

     System.out.println(gc.get(gc.YEAR) + "-" + (gc.get(gc.MONTH) + 1) + "-" + gc.get(gc.DAY_OF_MONTH)); 

    } 

    public static int randBetween(int start, int end) { 
     return start + (int)Math.round(Math.random() * (end - start)); 
    } 
} 
+2

Esta no es una distribución uniforme porque, por ejemplo, en febrero debería haber menos personas. – lbalazscs

+2

@lbalazscs - De hecho. Actualicé el ejemplo, debería ser un poco mejor ahora. – Saul

+5

En aras de la exhaustividad, debe usar las constantes de acceso a través de la clase 'Calendar' (' Calendar.YEAR', 'Calendar.DAY_OF_YEAR') no a través de la instancia' gc'. – mareckmareck

27

java.util.Date tiene un constructor que acepte milisegundos desde el tiempo, y java.util.Random tiene a method que le puede dar un número aleatorio de milisegundos. Deberá establecer un rango para el valor aleatorio según el rango de DOB que desee, pero eso debería hacerlo.

Muy más o menos:

Random rnd; 
Date dt; 
long ms; 

// Get a new random instance, seeded from the clock 
rnd = new Random(); 

// Get an Epoch value roughly between 1940 and 2010 
// -946771200000L = January 1, 1940 
// Add up to 70 years to it (using modulus on the next long) 
ms = -946771200000L + (Math.abs(rnd.nextLong()) % (70L * 365 * 24 * 60 * 60 * 1000)); 

// Construct a date 
dt = new Date(ms); 
+1

Esto es exactamente lo que empecé a pensar cuando leí por primera vez la cuestión. – AJMansfield

+1

Esta respuesta es mucho más para mi preferencia también. No es necesario hacer llamadas aleatorias por separado para el mes, el día y el año cuando un solo número puede determinarlo. – ewall

+0

Es una solución agradable y simple, pero prefiero usar 'RandomUtils.nextLong (0, 70L * 365 * 24 * 60 * 60 * 1000);' de apache lang3 – Alissa

20

Es necesario definir una fecha al azar, ¿verdad?

Una forma sencilla de hacerlo es generar una nueva Date objeto, utilizando un long (time in milliseconds since 1st January, 1970) y restar un azar long:

new Date(Math.abs(System.currentTimeMillis() - RandomUtils.nextLong())); 

(RandomUtils se toma de Apache Commons Lang).

Por supuesto, esto está lejos de ser una fecha aleatoria real (por ejemplo, no obtendrás una fecha anterior a 1970), pero creo que será suficiente para tus necesidades.

De lo contrario, puede crear su propia fecha mediante el uso de Calendar clase:

int year = // generate a year between 1900 and 2010; 
int dayOfYear = // generate a number between 1 and 365 (or 366 if you need to handle leap year); 
Calendar calendar = Calendar.getInstance(); 
calendar.set(Calendar.YEAR, randomYear); 
calendar.set(Calendar.DAY_OF_YEAR, dayOfYear); 
Date randomDoB = calendar.getTime(); 
+5

¿Es realmente tan oneroso usar el estándar aleatorio ? – AJMansfield

+1

esta respuesta está un poco desactualizada. Cuando escribo 'new Date (Math.abs (System.currentTimeMillis() - RandomUtils.nextLong()));', muestra que el método está en desuso. Sin embargo, no puedo encontrar un método paralelo equivalente en ningún otro lado. – Yokhen

2

Generación aleatoria Fecha de Nacimientos:

import java.util.Calendar; 

public class Main { 
    public static void main(String[] args) { 
    for (int i = 0; i < 100; i++) { 
     System.out.println(randomDOB()); 
    } 
    } 

    public static String randomDOB() { 

    int yyyy = random(1900, 2013); 
    int mm = random(1, 12); 
    int dd = 0; // will set it later depending on year and month 

    switch(mm) { 
     case 2: 
     if (isLeapYear(yyyy)) { 
      dd = random(1, 29); 
     } else { 
      dd = random(1, 28); 
     } 
     break; 

     case 1: 
     case 3: 
     case 5: 
     case 7: 
     case 8: 
     case 10: 
     case 12: 
     dd = random(1, 31); 
     break; 

     default: 
     dd = random(1, 30); 
     break; 
    } 

    String year = Integer.toString(yyyy); 
    String month = Integer.toString(mm); 
    String day = Integer.toString(dd); 

    if (mm < 10) { 
     month = "0" + mm; 
    } 

    if (dd < 10) { 
     day = "0" + dd; 
    } 

    return day + '/' + month + '/' + year; 
    } 

    public static int random(int lowerBound, int upperBound) { 
    return (lowerBound + (int) Math.round(Math.random() 
      * (upperBound - lowerBound))); 
    } 

    public static boolean isLeapYear(int year) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.YEAR, year); 
    int noOfDays = calendar.getActualMaximum(Calendar.DAY_OF_YEAR); 

    if (noOfDays > 365) { 
     return true; 
    } 

    return false; 
    } 
} 
0

estoy estudiando Scala y terminó soluciones googlear Java para elegir una fecha aleatoria entre rango. Encontré this post super útil y esta es mi solución final. Espero que pueda ayudar a los futuros programadores de Scala y Java.

import java.sql.Timestamp 

def date_rand(ts_start_str:String = "2012-01-01 00:00:00", ts_end_str:String = "2015-01-01 00:00:00"): String = { 
    val ts_start = Timestamp.valueOf(ts_start_str).getTime() 
    val ts_end = Timestamp.valueOf(ts_end_str).getTime() 
    val diff = ts_end - ts_start 
    println(diff) 
    val ts_rand = new Timestamp(ts_start + (Random.nextFloat() * diff).toLong) 
    return ts_rand.toString 
}           //> date_rand: (ts_start_str: String, ts_end_str: String)String 

println(date_rand())      //> 94694400000 
               //| 2012-10-28 18:21:13.216 

println(date_rand("2001-01-01 00:00:00", "2001-01-01 00:00:00")) 
               //> 0 
               //| 2001-01-01 00:00:00.0 
println(date_rand("2001-01-01 00:00:00", "2010-01-01 00:00:00")) 
               //> 283996800000 
               //| 2008-02-16 23:15:48.864     //> 2013-12-21 08:32:16.384 
23

Fragmento para una solución basada en Java 8:

Random random = new Random(); 
int minDay = (int) LocalDate.of(1900, 1, 1).toEpochDay(); 
int maxDay = (int) LocalDate.of(2015, 1, 1).toEpochDay(); 
long randomDay = minDay + random.nextInt(maxDay - minDay); 

LocalDate randomBirthDate = LocalDate.ofEpochDay(randomDay); 

System.out.println(randomBirthDate); 

Nota: Esto genera una fecha aleatoria entre 1Jan1900 (ambos inclusive) y 1Jan2015 (exclusivo).

Nota: Se basa en epoch days, es decir, días en relación con 1Jan1970 (EPOCH) - significado positivo después de EPOCH, sentido negativo antes de EPOCH


También puede crear una pequeña clase de utilidad:

public class RandomDate { 
    private final LocalDate minDate; 
    private final LocalDate maxDate; 
    private final Random random; 

    public RandomDate(LocalDate minDate, LocalDate maxDate) { 
     this.minDate = minDate; 
     this.maxDate = maxDate; 
     this.random = new Random(); 
    } 

    public LocalDate nextDate() { 
     int minDay = (int) minDate.toEpochDay(); 
     int maxDay = (int) maxDate.toEpochDay(); 
     long randomDay = minDay + random.nextInt(maxDay - minDay); 
     return LocalDate.ofEpochDay(randomDay); 
    } 

    @Override 
    public String toString() { 
     return "RandomDate{" + 
       "maxDate=" + maxDate + 
       ", minDate=" + minDate + 
       '}'; 
    } 
} 

y utilizar de esta manera:

RandomDate rd = new RandomDate(LocalDate.of(1900, 1, 1), LocalDate.of(2010, 1, 1)); 
System.out.println(rd.nextDate()); 
System.out.println(rd.nextDate()); // birthdays ad infinitum 
+2

Esta es una buena respuesta, pero la clase de utilidad puede hacerse un poco más eficiente al hacer las conversiones toEpochDay() para min y max en el constructor y guardar los resultados int en lugar de LocalDates. Entonces solo necesita hacerse una vez, en lugar de una vez por cada llamada a nextDate(). –

-1

obtendrá la fecha en dd/mm/aaaa
Puede usar las Matemáticas.función aleatoria(), como lo he hecho a continuación

aquí estamos generando números aleatorios de 3 a 1 a 31,1 12,1990 a 2016 y la concatenación de "/" entre ellos

public static String getRandomJoinDate() 
    { 
     String date=""; 
     int yearBegin=1990; 
     int yearEnd=2016-yearBegin; 

     date=""+(1 + (int)(Math.random() * 31)+"/"+(1 + (int)(Math.random() * 12)+"/"+(yearBegin + (int)(Math.random() * yearEnd)))); 
     return date; 
    } 

saber más acerca de a continuación math.random() enlace puede ayudar a
Math.random() explained

+1

explicar algo ... !! –

2

usted puede comprobación randomizer para la biblioteca de datos aleatorios generation.This ayuda a crear datos aleatorios a partir de determinado modelo class.Checkout ejemplo de código a continuación.

public class Person { 

    @DateValue(from = "01 Jan 1990",to = "31 Dec 2002" , customFormat = "dd MMM yyyy") 
    String dateOfBirth; 

} 

//Generate random 100 Person(Model Class) object 
Generator<Person> generator = new Generator<>(Person.class); 
List<Person> persons = generator.generate(100);       

Como hay muchos construidos en el generador de datos es accesible mediante anotación, También se puede construir de datos personalizados generator.I que sugieren que pasar por la documentación proporcionada en la página de la biblioteca.

2

Look este método:

public static Date dateRandom(int initialYear, int lastYear) { 
    if (initialYear > lastYear) { 
     int year = lastYear; 
     lastYear = initialYear; 
     initialYear = year; 
    } 

    Calendar cInitialYear = Calendar.getInstance(); 
    cInitialYear.set(Calendar.YEAR, 2015); 
    long offset = cInitialYear.getTimeInMillis(); 

    Calendar cLastYear = Calendar.getInstance(); 
    cLastYear.set(Calendar.YEAR, 2016); 
    long end = cLastYear.getTimeInMillis(); 

    long diff = end - offset + 1; 
    Timestamp timestamp = new Timestamp(offset + (long) (Math.random() * diff)); 
    return new Date(timestamp.getTime()); 
} 
2

Si no te importa la adición de una nueva biblioteca para el código que puede utilizar MockNeat (exención de responsabilidad: yo soy uno de los autores).

MockNeat mock = MockNeat.threadLocal(); 

// Generates a random date between [1970-1-1, NOW) 
LocalDate localDate = mock.localDates().val(); 
System.out.println(localDate); 

// Generates a random date in the past 
// but beore 1987-1-30 
LocalDate min = LocalDate.of(1987, 1, 30); 
LocalDate past = mock.localDates().past(min).val(); 
System.out.println(past); 

LocalDate max = LocalDate.of(2020, 1, 1); 
LocalDate future = mock.localDates().future(max).val(); 
System.out.println(future); 

// Generates a random date between 1989-1-1 and 1993-1-1 
LocalDate start = LocalDate.of(1989, 1, 1); 
LocalDate stop = LocalDate.of(1993, 1, 1); 
LocalDate between = mock.localDates().between(start, stop).val(); 
System.out.println(between); 
2

Para Java8 -> Assumming los datos de nacimiento debe ser antes del día actual:

import java.time.LocalDate; 
import java.time.LocalTime; 
import java.time.Period; 
import java.time.temporal.ChronoUnit; 
import java.util.Random; 

public class RandomDate { 

    public static LocalDate randomBirthday() { 
     return LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70)))); 
    } 

    public static void main(String[] args) { 
     System.out.println("randomDate: " + randomBirthday()); 
    } 
} 
+1

Considera usar un ['ThreadLocalRandom'] (https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/ThreadLocalRandom.html) en lugar de crear una instancia nueva [' Random'] (https : //docs.oracle.com/javase/9/docs/api/java/util/Random.html) cada vez. –

+0

cierto. Mejor práctica. –

1

creo que esto va a hacer el truco:

public static void main(String[] args) { 
    Date now = new Date(); 
    long sixMonthsAgo = (now.getTime() - 15552000000l); 
    long today = now.getTime(); 

    for(int i=0; i<10; i++) { 
     long ms = ThreadLocalRandom.current().nextLong(sixMonthsAgo, today); 

     Date date = new Date(ms); 

     System.out.println(date.toString()); 
    } 

} 
1

Si no le importa una biblioteca de terceros, la biblioteca Utils tiene un RandomDateUtils que genera aleatoriamente java.util.Dates y todas las fechas, horas, instantes y duraciones de Java 8's date and time API

LocalDate birthDate = RandomDateUtils.randomPastLocalDate(); 
LocalDate today = LocalDate.now(); 
LocalDate under18YearsOld = RandomDateUtils.randomLocalDate(today.minus(18, YEARS), today); 
LocalDate over18YearsOld = RandomDateUtils.randomLocalDateBefore(today.minus(18, YEARS)); 

Es en el Repositorio Central de Maven en:

<dependency> 
    <groupId>com.github.rkumsher</groupId> 
    <artifactId>utils</artifactId> 
    <version>1.0</version> 
</dependency> 
Cuestiones relacionadas