Java - 生成随机DOB

时间:2017-03-08 09:35:55

标签: java

我想为给定的年份范围生成随机DOB。所以我尝试了下面的代码

private static String randomDataOfBirth(int yearStart, int yearEnd)
    {
        GregorianCalendar gc = new GregorianCalendar();
        int year = randBetween(yearStart, yearEnd);
        gc.set(Calendar.YEAR, year);
         int dayOfYear = randBetween(1, gc.getActualMaximum(Calendar.DAY_OF_YEAR));

            gc.set(Calendar.DAY_OF_YEAR, dayOfYear);
            String date = null;
            if(gc.get(Calendar.MONTH) == 0)
            {
                 date = gc.get(Calendar.YEAR) + "-" + 1 + "-" + gc.get(Calendar.DAY_OF_MONTH);
            }else
            {
                 date = gc.get(Calendar.YEAR) + "-" + gc.get(Calendar.MONTH) + "-" + gc.get(Calendar.DAY_OF_MONTH);
            }
            return date;    
    }

private static int randBetween(int start, int end) {
        // TODO Auto-generated method stub
         return start + (int)Math.round(Math.random() * (end - start));
    }

主: -

public static void main(String[] args) {
String dob = randomDataOfBirth(1899, 1937);
System.out.println(dob);
}

我可以生成随机DOB。但仅限于月和日,我想为1到9的范围添加前缀'0'

Month - 01, 02, 03 and ... up to 09
Day - 01, 02, 03 and ... up to 09


2 个答案:

答案 0 :(得分:1)

除了您希望格式化日期之外,我还会看到您认为您希望解决的代码存在的其他一些问题:

  • 假设你想要一个通常的月号,从1月到12月12月,你对月份号的处理是不正确的。 get(Calendar.MONTH)为您提供一个基于0的月份:1月份为0月份,11月份为11月份。因此,您的代码不仅永远不会给您12个月和1个。它还会为您提供不存在的日期。我见过1905-2-31和1929-4-31(因为3月份得到2,我们将其解释为2月等)。
  • 可能不重要,你的发行版每天在闰年中的概率比其他日子略小。

如果可以,我建议您使用LocalDate。这个类是在Java 8中引入的:

private static String randomDataOfBirth(int yearStartInclusive, int yearEndExclusive) {
    LocalDate start = LocalDate.ofYearDay(yearStartInclusive, 1);
    LocalDate end = LocalDate.ofYearDay(yearEndExclusive, 1);

    long longDays = ChronoUnit.DAYS.between(start, end);
    int days = (int) longDays;
    if (days != longDays) {
        throw new IllegalStateException("int overflow; too many years");
    }
    int day = randBetween(0, days);
    LocalDate dateOfBirth = start.plusDays(day);

    return dateOfBirth.toString();
}

这为您提供了均匀分布的正确日期,格式为月份和日期的2位数字,例如1926-07-05

如果您想避免溢出检查,您当然可以重写randBetween()来处理long

如果您无法使用Java 8,则可以使用GregorianCalendarSimpleDateFormat执行类似操作。但是,计算从下限到上限的确切天数是很复杂的,因此您可能希望坚持选择日期的方式。 SimpleDateFormat仍然可以为您提供正确的日期,格式为两位数的月份和日期。编辑:在您的课程中,声明:

static DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

现在只需将if - else语句替换为:

    String date = formatter.format(gc.getTime());

如果您的randomDataOfBirth()可以从多个线程访问,那么这将无效,因为SimpleDateFormat不是线程安全的。如果是这样,每个线程都应该有自己的SimpleDateFormat实例。

答案 1 :(得分:0)

使用Java7,您可以尝试使用以下内容:

public class DobMaker
{

    public String getDOB(int min, int max)
    {
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        int year = min + new Random().nextInt(max - min + 1);
        calendar.set(Calendar.YEAR, year);
        int day = 1+new Random().nextInt(calendar.getActualMaximum(Calendar.DAY_OF_YEAR));
        calendar.set(Calendar.DAY_OF_YEAR, day);
        return new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
    }

    public static void main(String[] args)
    {
        DobMaker d = new DobMaker();

        System.out.println(d.getDOB(1970, 1980));
        System.out.println(d.getDOB(1970, 1971));
        System.out.println(d.getDOB(2007, 2016));

    }
}