@@ -357,90 +357,199 @@ export class SimpleDateModule extends SimpleModuleBase {
357357 }
358358
359359 /**
360- * Returns a random birthdate.
360+ * Returns a random birthdate. By default, the birthdate is generated for an adult between 18 and 80 years old.
361+ * But you can customize the `'age'` range or the `'year'` range to generate a more specific birthdate.
361362 *
362- * @param options The options to use to generate the birthdate. If no options are set, an age between 18 and 80 (inclusive) is generated.
363- * @param options.min The minimum age or year to generate a birthdate.
364- * @param options.max The maximum age or year to generate a birthdate.
365- * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `now`.
366- * @param options.mode The mode to generate the birthdate. Supported modes are `'age'` and `'year'` .
363+ * @param options The options to use to generate the birthdate.
364+ * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `faker.defaultRefDate()`.
365+ *
366+ * @example
367+ * faker.date.birthdate() // 1977-07-10T01:37:30.719Z
368+ *
369+ * @since 7.0.0
370+ */
371+ birthdate ( options ?: {
372+ /**
373+ * The date to use as reference point for the newly generated date.
374+ *
375+ * @default faker.defaultRefDate()
376+ */
377+ refDate ?: string | Date | number ;
378+ } ) : Date ;
379+ /**
380+ * Returns a random birthdate for a given age range.
381+ *
382+ * @param options The options to use to generate the birthdate.
383+ * @param options.mode `'age'` to generate a birthdate based on the age range. It is also possible to generate a birthdate based on a `'year'` range.
384+ * @param options.min The minimum age to generate a birthdate for.
385+ * @param options.max The maximum age to generate a birthdate for.
386+ * @param options.refDate The date to use as reference point for the newly generated date. Defaults to `faker.defaultRefDate()`.
387+ *
388+ * @example
389+ * faker.date.birthdate({ mode: 'age', min: 18, max: 65 }) // 2003-11-02T20:03:20.116Z
367390 *
368- * There are two modes available `'age'` and `'year'`:
369- * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`).
370- * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`).
391+ * @since 7.0.0
392+ */
393+ birthdate ( options : {
394+ /**
395+ * `'age'` to generate a birthdate based on the age range.
396+ * It is also possible to generate a birthdate based on a `'year'` range.
397+ */
398+ mode : 'age' ;
399+ /**
400+ * The minimum age to generate a birthdate for.
401+ */
402+ min : number ;
403+ /**
404+ * The maximum age to generate a birthdate for.
405+ */
406+ max : number ;
407+ /**
408+ * The date to use as reference point for the newly generated date.
409+ *
410+ * @default faker.defaultRefDate()
411+ */
412+ refDate ?: string | Date | number ;
413+ } ) : Date ;
414+ /**
415+ * Returns a random birthdate in the given range of years.
416+ *
417+ * @param options The options to use to generate the birthdate.
418+ * @param options.mode `'year'` to generate a birthdate based on the year range. It is also possible to generate a birthdate based on a `'age'` range.
419+ * @param options.min The minimum year to generate a birthdate in.
420+ * @param options.max The maximum year to generate a birthdate in.
421+ *
422+ * @example
423+ * faker.date.birthdate({ mode: 'year', min: 1900, max: 2000 }) // 1940-08-20T08:53:07.538Z
424+ *
425+ * @since 7.0.0
426+ */
427+ birthdate ( options : {
428+ /**
429+ * `'year'` to generate a birthdate based on the year range.
430+ * It is also possible to generate a birthdate based on an `'age'` range.
431+ */
432+ mode : 'year' ;
433+ /**
434+ * The minimum year to generate a birthdate in.
435+ */
436+ min : number ;
437+ /**
438+ * The maximum year to generate a birthdate in.
439+ */
440+ max : number ;
441+ } ) : Date ;
442+ /**
443+ * Returns a random birthdate. By default, the birthdate is generated for an adult between 18 and 80 years old.
444+ * But you can customize the `'age'` range or the `'year'` range to generate a more specific birthdate.
371445 *
372- * Defaults to `year`.
446+ * @param options The options to use to generate the birthdate.
447+ * @param options.mode Either `'age'` or `'year'` to generate a birthdate based on the age or year range.
448+ * @param options.min The minimum age or year to generate a birthdate in.
449+ * @param options.max The maximum age or year to generate a birthdate in.
450+ * @param options.refDate The date to use as reference point for the newly generated date.
451+ * Only used when `mode` is `'age'`.
452+ * Defaults to `faker.defaultRefDate()`.
373453 *
374454 * @example
375455 * faker.date.birthdate() // 1977-07-10T01:37:30.719Z
376- * faker.date.birthdate({ min: 18, max: 65, mode: 'age' }) // 2003-11-02T20:03:20.116Z
377- * faker.date.birthdate({ min: 1900, max: 2000, mode: 'year' }) // 1940-08-20T08:53:07.538Z
456+ * faker.date.birthdate({ mode: 'age', min: 18, max: 65 }) // 2003-11-02T20:03:20.116Z
457+ * faker.date.birthdate({ mode: 'year', min: 1900, max: 2000 }) // 1940-08-20T08:53:07.538Z
378458 *
379459 * @since 7.0.0
380460 */
461+ birthdate (
462+ options ?:
463+ | {
464+ /**
465+ * The date to use as reference point for the newly generated date.
466+ *
467+ * @default faker.defaultRefDate()
468+ */
469+ refDate ?: string | Date | number ;
470+ }
471+ | {
472+ /**
473+ * Either `'age'` or `'year'` to generate a birthdate based on the age or year range.
474+ */
475+ mode : 'age' | 'year' ;
476+ /**
477+ * The minimum age/year to generate a birthdate for/in.
478+ */
479+ min : number ;
480+ /**
481+ * The maximum age/year to generate a birthdate for/in.
482+ */
483+ max : number ;
484+ /**
485+ * The date to use as reference point for the newly generated date.
486+ * Only used when `mode` is `'age'`.
487+ *
488+ * @default faker.defaultRefDate()
489+ */
490+ refDate ?: string | Date | number ;
491+ }
492+ ) : Date ;
381493 birthdate (
382494 options : {
383- /**
384- * The minimum age or year to generate a birthdate.
385- *
386- * @default 18
387- */
495+ mode ?: 'age' | 'year' ;
388496 min ?: number ;
389- /**
390- * The maximum age or year to generate a birthdate.
391- *
392- * @default 80
393- */
394497 max ?: number ;
395- /**
396- * The mode to generate the birthdate. Supported modes are `'age'` and `'year'` .
397- *
398- * There are two modes available `'age'` and `'year'`:
399- * - `'age'`: The min and max options define the age of the person (e.g. `18` - `42`).
400- * - `'year'`: The min and max options define the range the birthdate may be in (e.g. `1900` - `2000`).
401- *
402- * @default 'year'
403- */
404- mode ?: 'age' | 'year' ;
405- /**
406- * The date to use as reference point for the newly generated date.
407- *
408- * @default faker.defaultRefDate()
409- */
410498 refDate ?: string | Date | number ;
411499 } = { }
412500 ) : Date {
413- const { mode = 'year' , refDate = this . faker . defaultRefDate ( ) } = options ;
414- const date = toDate ( refDate ) ;
415- const refYear = date . getUTCFullYear ( ) ;
416-
417- // If no min or max is specified, generate a random date between (now - 80) years and (now - 18) years respectively
418- // So that people can still be considered as adults in most cases
419-
420- // Convert to epoch timestamps
421- let min : number ;
422- let max : number ;
423- if ( mode === 'age' ) {
424- min = new Date ( date ) . setUTCFullYear ( refYear - ( options . max ?? 80 ) - 1 ) ;
425- max = new Date ( date ) . setUTCFullYear ( refYear - ( options . min ?? 18 ) ) ;
426- } else {
427- // Avoid generating dates the first and last date of the year
428- // to avoid running into other years depending on the timezone.
429- min = new Date ( Date . UTC ( 0 , 0 , 2 ) ) . setUTCFullYear (
430- options . min ?? refYear - 80
431- ) ;
432- max = new Date ( Date . UTC ( 0 , 11 , 30 ) ) . setUTCFullYear (
433- options . max ?? refYear - 19
434- ) ;
435- }
436-
437- if ( max < min ) {
501+ const {
502+ mode = 'age' ,
503+ min = 18 ,
504+ max = 80 ,
505+ refDate : rawRefDate = this . faker . defaultRefDate ( ) ,
506+ mode : originalMode ,
507+ min : originalMin ,
508+ max : originalMax ,
509+ } = options ;
510+
511+ // TODO @ST -DDT 2024-03-17: Remove check in v10
512+ const optionsSet = [ originalMin , originalMax , originalMode ] . filter (
513+ ( x ) => x != null
514+ ) . length ;
515+ if ( optionsSet % 3 !== 0 ) {
438516 throw new FakerError (
439- `Max ${ options . max } should be larger than or equal to min ${ options . min } .`
517+ "The 'min', ' max', and 'mode' options must be set together."
440518 ) ;
441519 }
442520
443- return new Date ( this . faker . number . int ( { min, max } ) ) ;
521+ const refDate = toDate ( rawRefDate ) ;
522+ const refYear = refDate . getUTCFullYear ( ) ;
523+
524+ switch ( mode ) {
525+ case 'age' : {
526+ const from = new Date ( refDate ) . setUTCFullYear ( refYear - max - 1 ) ;
527+ const to = new Date ( refDate ) . setUTCFullYear ( refYear - min ) ;
528+
529+ if ( from > to ) {
530+ throw new FakerError (
531+ `Max age ${ max } should be greater than or equal to min age ${ min } .`
532+ ) ;
533+ }
534+
535+ return this . between ( { from, to } ) ;
536+ }
537+
538+ case 'year' : {
539+ // Avoid generating dates on the first and last date of the year
540+ // to avoid running into other years depending on the timezone.
541+ const from = new Date ( Date . UTC ( 0 , 0 , 2 ) ) . setUTCFullYear ( min ) ;
542+ const to = new Date ( Date . UTC ( 0 , 11 , 30 ) ) . setUTCFullYear ( max ) ;
543+
544+ if ( from > to ) {
545+ throw new FakerError (
546+ `Max year ${ max } should be greater than or equal to min year ${ min } .`
547+ ) ;
548+ }
549+
550+ return this . between ( { from, to } ) ;
551+ }
552+ }
444553 }
445554}
446555
0 commit comments