Je veux vérifier si une personne a exactement ou plus de 18 ans. J'ai donc utilisé les fonctions diff()
et duration()
pour calculer l'âge de la personne. J'ai écrit des tests avec des valeurs limites pour tester ma logique. Je voulais tester si j'ai exactement un jour de moins que 18 ans et exactement 18 ans. J'ai donc choisi deux anniversaires pour le test (aujourd'hui nous sommes le 27.02.2017) :
// today date is: 27.02.2017
// exactly age 18
var birthday = moment("27.02.1999", "DD.MM.YYYY"),
age = moment.duration(moment().diff(birthday)).asYears();
console.log(age); // output: 18.00325100985672; expected: == 18
// one day under age 18
var birthday = moment("28.02.1999", "DD.MM.YYYY"),
age = moment.duration(moment().diff(birthday)).asYears();
console.log(age); // output: 18.00053005036735; expected: < 18
Je pense que le calcul est correct, à cause des années bissextiles. Mais en termes d'anniversaire, la personne ne devrait pas avoir 18 ans. Peut-être qu'il y a une autre façon de le faire avec momentjs et je le fais mal. Si c'est le cas, ce serait bien d'être mentionné dans la documentation de momentjs.
<form id="newsletter-form" data-parsley-validate="">
<input id="birthday" type="text" class="form-control" required="" data-parsley-minage="18">
<input type="submit" class="btn btn-default" value="subscribe">
</form>
<script type="text/javascript">
$(function () {
window.Parsley.addValidator('minage', {
validateString: function(value, minAge) {
var birthday = moment(value, "DD.MM.YYYY"),
age = moment.duration(moment().diff(birthday)).asYears();
return (age >= minAge);
},
requirementType: 'integer',
messages: {
en: 'You must be mature.'
}
});
});
</script>
<script type="text/javascript">
$(function () {
$('#newsletter-form').parsley()
// field validation
.on('form:submit', function() {
return false; // do not submit
});
});
</script>
Chrome version 56.0.2924.87 (64 bits) sur Windows 7
console.log( (new Date()).toString()) // Mon Feb 27 2017 13:38:04 GMT+0100 (Mitteleuropäische Zeit)
console.log((new Date()).toLocaleString()) // 27.2.2017, 13:38:04
console.log( (new Date()).getTimezoneOffset()) // -60
console.log( navigator.userAgent) // Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
console.log(moment.version) // 2.17.1
Je pense que le calcul est faux, mais c'est super proche. Peut-être à cause d'erreurs d'arrondi ?
Par exemple:
a = moment("27.02.1999", "DD.MM.YYYY");
b = moment("28.02.1999", "DD.MM.YYYY");
c = moment("27.02.2017", "DD.MM.YYYY");
moment.duration(c.diff(a)).asYears(); // 18.00173857094944
moment.duration(c.diff(b)).asYears(); // 17.99900066394245
Ainsi, dans ce cas, moment.duration(end.diff(start)).asYears()
renverra 18
environ 16 heures avant qu'il ne le devrait.
Si vous essayez de vérifier si un âge est supérieur ou égal à 18 ans, vous pouvez comparer les années, puis (si 18 ans séparent) les mois, puis les jours.
// pseudocode, correctness not guaranteed
function is18(start, end) {
if (end.year() - start.year() == 18) {
if (end.month() == start.month()) {
return end.date() >= start.date();
}
return end.month() > start.month();
}
return end.year() - 18 > start.year();
}
Est-ce que cela fonctionne mieux si vous utilisez simplement
age = moment().diff(birthday, 'years');
@mj1856
Ouais, ça marche très bien.
// today date is: 03.03.2017
// exactly age 18
var birthday = moment("03.03.1999", "DD.MM.YYYY"),
age = moment().diff(birthday, 'years');
console.log(age); // output: 18; expected: == 18
// one day under age 18
var birthday = moment("04.03.1999", "DD.MM.YYYY"),
age = moment().diff(birthday, 'years');
console.log(age); // output: 17; expected: < 18
Commentaire le plus utile
Est-ce que cela fonctionne mieux si vous utilisez simplement