2010-10-21 4 views

ответ

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

Это не равномерное распределение, потому что, например, в феврале должно быть меньше людей. – lbalazscs

+2

@lbalazscs - Действительно. Я обновил пример, теперь он должен быть немного лучше. – Saul

+5

Для полноты - вы должны использовать константы доступа с помощью класса 'Calendar' (' Calendar.YEAR', 'Calendar.DAY_OF_YEAR') не через экземпляр' gc'. – mareckmareck

27

java.util.Date имеет constructor, который принимает миллисекунды с начала эпохи, и java.util.Random имеет a method, что может дать вам случайное число миллисекунд. Вы хотите установить диапазон для случайного значения в зависимости от диапазона DOB, который вы хотите, но это должно сделать это.

Очень примерно:

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

Это именно то, что я начал думать, когда я впервые прочитал вопрос. – AJMansfield

+1

Этот ответ гораздо больше подходит для моих предпочтений. Не нужно делать отдельные случайные вызовы для месяца, дня и года, когда один номер может определить его. – ewall

+0

Это приятное и простое решение, но я бы предпочел использовать «RandomUtils.nextLong» (0, 70L * 365 * 24 * 60 * 60 * 1000); 'от apache lang3 – Alissa

20

Вы должны определить случайную дату, не так ли?

Простой способ сделать это, чтобы создать новый объект Date, используя long (time in milliseconds since 1st January, 1970) и вычитаем случайное long:

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

(RandomUtils берется из Apache Commons Lang).

Конечно, это далеко не реальная случайная дата (например, вы не получите дату до 1970 года), но я думаю, этого будет достаточно для ваших нужд.

В противном случае, вы можете создать свою собственную дату, используя Calendar класс:

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

Действительно ли так обременительно просто использовать стандартную случайную ? – AJMansfield

+1

Этот ответ немного устарел. Когда я набираю 'new Date (Math.abs (System.currentTimeMillis() - RandomUtils.nextLong());), он показывает, что метод устарел. Однако я не могу найти параллельный эквивалентный метод в другом месте. – Yokhen

2

Генерация случайных Дата Роды:

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

Я изучаю Scala и в конечном итоге решения Googling Java для выбора случайной даты между диапазоном. Я нашел this сообщение супер полезно, и это мое окончательное решение. Надеюсь, это поможет будущим программистам Scala и 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

Сниппет для решения, основанного на 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); 

Примечание: Это генерирует случайную дату между 1Jan1900 (включительно) и 1Jan2015 (Exclusive).

Примечание: Он основан на epoch days, т.е. дней по сравнению с 1Jan1970 (EPOCH) - положительное значение после ЭПОХИ, отрицательное значение, прежде чем ЭПОХИ


Вы также можете создать небольшой вспомогательный класс:

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 + 
       '}'; 
    } 
} 

и использовать его как это:

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

Это прекрасный ответ, но класс полезности может быть сделан немного более эффективным, делая преобразования toEpochDay() для min и max в конструкторе и сохраняя результаты int, а не LocalDates. Затем это нужно сделать только один раз, а не один раз для каждого вызова nextDate(). –

-1

вы получите дату в дд/мм/гггг
Вы можете использовать математику.случайная функция(), как я сделал ниже

здесь мы генерируем 3 случайных чисел от 1 до 31,1 до 12,1990 до 2016 года и конкатенации «/» между ними

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; 
    } 

, чтобы узнать больше о ссылка Math.random() ниже, может помочь
Math.random() explained

+1

объясните что-нибудь .. !! –

2

Вы можете оформить randomizer для случайных данных, generation.This библиотеки позволяет создавать случайные данные из данной модели class.Checkout ниже примере кода.

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);       

Поскольку существует множество встроенного в генераторе данных доступен с помощью аннотаций, Вы также можете создать пользовательские данные generator.I рекомендую вам пройти через документацию, представленную на странице библиотеки.

2

Посмотрите этот метод:

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

Если вы не возражаете, добавив новую библиотеку в свой код, который вы можете использовать MockNeat (отказ от ответственности: Я один из авторов).

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

Для Java8 -> Assumming данные о рождении должно быть перед текущим днем:

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

Рассмотрите возможность использования ['ThreadLocalRandom'] (https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/ThreadLocalRandom.html) вместо создания экземпляра нового [' Random'] (https : //docs.oracle.com/javase/9/docs/api/java/util/Random.html) каждый раз. –

+0

Правда. Лучшая практика. –

1

Я думаю, что это будет делать трюк:

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

Если вы не возражаете библиотека сторонних разработчиков, библиотека Utils имеет RandomDateUtils, которая генерирует случайные java.util.Dates и все даты, время, моменты и длительности из 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)); 

Он находится в Maven центрального хранилища на:

<dependency> 
    <groupId>com.github.rkumsher</groupId> 
    <artifactId>utils</artifactId> 
    <version>1.0</version> 
</dependency> 
Смежные вопросы