-1

e.g. 70,105 - calculate any date of birth that meets the age range of the parameters

    CalculateDob(int youngestAge, int oldestAge)
     {

        Random r = new Random();
        int age = 0;
        age = r.Next(70, 105);

        var year = DateTime.Now.Year - age;
        var month = r.Next(1, 12);
        var day = r.Next(1, 28);
        return new DateTime(year, month, day); 
    }

My current soluton almost works, but fails in some edge cases i.e. returns 69 in some circumstances due what i presume a month issue.

Any suggestions?

J.Doe
  • 11
  • Why day is `r.Next(1, 28)`? – Rahul Jan 31 '19 at 13:22
  • why do you send `youngestAge` and `oldestAge` as parameters and doesn't use them. what is the point the function, calculate a birthday of some that will have his 70th birthday this year? – styx Jan 31 '19 at 13:23
  • `returns 69 in some circumstances ` - what does this mean? You're returning a date time, so how can you return 69? – Matt Hogan-Jones Jan 31 '19 at 13:27
  • @Rahul February has 28 days - if I set it as 31 then it may potentially compute 31st Feb, this was a very rough implementation :) – J.Doe Jan 31 '19 at 13:29
  • @MattJones i.e. if you convert the DateTime produced to an age.. – J.Doe Jan 31 '19 at 13:30
  • _"returns 69 in some circumstances "_ what circumstances? – Tim Schmelter Jan 31 '19 at 13:30
  • @Rango i.e. 18/07/1949 - I've ran this method 3000 times and it produces an age of 69 in 77 instances. – J.Doe Jan 31 '19 at 13:36
  • @J.Doe: not the cause of this issue, but you should not initialize the random in this method. Because it will use the same seed if you call it very fast(for example in a loop) because the default constructor uses the current time. That will produce always the same "random" age. Instead you could pass it to the method or use a field. – Tim Schmelter Jan 31 '19 at 13:39
  • Wait.. `Random` what ? "calculate any date of birth"? Please use [ask] and [mcve] guidline. We need to have the requirement clear. Read https://stackoverflow.com/questions/9/how-do-i-calculate-someones-age-in-c?rq=1 to understand the complexity and reduce the scope. Explain the input and the required output of test case. A test case is not about creating random value. test your function against the real date range + date max and date min – xdtTransform Jan 31 '19 at 13:58
  • It's unclear if you wan't to check if someone is in age range based on its Birth date? Or you wan't the list of all date that will span be in this date range? – xdtTransform Jan 31 '19 at 15:07
  • You are rounding to Year (DateTime.Now.Year - age). To fix change age to a DateTime using todays Month and Day : DateTime now = DateTime.Now; new DateTime(now.Year - age, now.Month, now.Day); – jdweng Jan 31 '19 at 15:11
  • Or try to get one random date in the range, in this case does it have to be different, random doesnt mean different value. If it can be the same why is it random? When range min +1 day give you a valid result without using any random and wasting computation. – xdtTransform Jan 31 '19 at 15:17

1 Answers1

0

Reason you are getting 69 years of age sometimes is because if CalculateDob returns month which is after current month (DateTime.Now); then Dob still wouldn't reach 70 years. Also, you should bring random constructor out from the method, and make it static so that you don't keep seeding rand generator during every call.

public static void Main(string[] args)
{
    for (int i = 0; i < 100; i++)
    {
        var birthDate = CalculateDob(70, 105);
        var now = DateTime.Now;
        int age = now.Year - birthDate.Year;
        if (now.Month < birthDate.Month || (now.Month == birthDate.Month && now.Day < birthDate.Day))
        {
            age--;
        }
        Console.WriteLine(age);                
    }
}

//Construct this as static so that we don't keep seeding the rand    
private static readonly Random _random = new Random();

static DateTime CalculateDob(int youngestAge, int oldestAge)
{


    int age = 0;
    age = _random.Next(70, 105);
    var today = DateTime.Now;
    var year = today.Year - age;
    var month = _random.Next(1, 12);

    //Age might less than youngest age,
    //if born at/after current month, edge condition
    if (month >= today.Month)
    {

        month = today.Month - 1;
        if (month < 1)
        {
            year--;
            month = 12;
        }
    }

    var day = _random.Next(1, DateTime.DaysInMonth(year, month));
    return new DateTime(year, month, day);
}
loopedcode
  • 4,863
  • 1
  • 21
  • 21