Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Расчет возраста (https://javascript.ru/forum/misc/12805-raschet-vozrasta.html)

Tryman 03.11.2010 20:04

Расчет возраста
 
Добрый вечер, такая проблема, произвожу расчет возраста посетителя следующим скриптом:

<SCRIPT Language="JavaScript">
<!-- hide from old browsers
var today = new Date()
if ([xfvalue_data] && [xfvalue_mec] && [xfvalue_god] != "") {
var targetDate = new Date("[xfvalue_data]/[xfvalue_mec]/[xfvalue_god]")
var timeAfterTarget = Math.floor(( today.getTime() - targetDate.getTime() ) / 86400000)
var msg = parseInt(timeAfterTarget/365);
document.write(msg);
} else {
var msg="";
document.write(msg);
}
//-->
</SCRIPT>


[xfvalue_data] && [xfvalue_mec] && [xfvalue_god] это переменные, из выпадающего списка юзер выбирает необходимые значения....вбиваю свои данные 24/8/1990 на сайте скрипт выводит результат расчета 18 лет.....на могу найти причину почему на 2 года ошибается....
Прошу помощи, заранее спасибо!

ksa 03.11.2010 21:58

Tryman, как вариант:
- переводи даты в числа формата ГГГГММДД
- просто вычисляй их разность
- дели на 10000
- отбрасывай дробную часть

Aetae 03.11.2010 22:16

xfvalue_god=1990;
alert(new Date().getFullYear()-xfvalue_god)

Надмозги, лол.) :lol:

ksa 03.11.2010 22:58

Aetae, пример:

сегодня 03.11.2010
родился 10.09.2009

по-твоему человеку 1 год. Что не верно...:nono:

Aetae 04.11.2010 01:10

Цитата:

Сообщение от ksa (Сообщение 77319)
Aetae, пример:

сегодня 03.11.2010
родился 10.09.2009

по-твоему человеку 1 год. Что не верно...:nono:

Не, тут как раз таки верно)
Но да, признаю, ступил.)

рони 04.11.2010 01:12

Tryman,
Поменяйте месяц и дату местами тут
var targetDate = new Date("[xfvalue_data]/[xfvalue_mec]/[xfvalue_god]")

Aetae 04.11.2010 02:18

Не, всё равно не точно будет ибо не в каждом году 365 дней.

В голову теперь только всякие надмозги и лезут.=\
d=24;m=7;y=1990; // и надо помнить, что месяца считаются 0-11, а не 1-12)
var t=new Date();t=[t.getMonth(),t.getDate(),t.getFullYear()];
alert(t[2]-y-(t[0]==m?t[1]<d:t[0]<m))

Или ещё более извращённый:
d=24;m=7;y=1990; // и надо помнить, что месяца считаются 0-11, а не 1-12)
var t=new Date();
alert( t.getFullYear()-y-((t.getMonth()-m||t.getDate()-d)<0) )

ksa 04.11.2010 08:29

Цитата:

Сообщение от Aetae
всё равно не точно будет

Мой вариант проверен годами. :) Используя его людям начисляют пособие... Оформляют пенсии...
Т.ч. отбрось сомнения и просто используй.

Aetae 04.11.2010 11:29

Цитата:

Сообщение от ksa (Сообщение 77345)
Мой вариант проверен годами. :) Используя его людям начисляют пособие... Оформляют пенсии...
Т.ч. отбрось сомнения и просто используй.

Цитата:

Сообщение от ksa (Сообщение 77309)
Tryman, как вариант:
- переводи даты в числа формата ГГГГММДД
- просто вычисляй их разность
- дели на 10000
- отбрасывай дробную часть

Это логично и это первое о чём я подумал, но "просто изпользовать" не получится ибо кода нет)) И в js реализация будет громоздкой, ибо Date такой Date.

DooMer 05.11.2010 19:05

рони,
Без обид, но выкинь свой говнокод
за 10 мин наваял

var day = 24;
var month = 8;
var year = 1990;
var now = new Date().getTime();
var birsday = Date.UTC(year,month-1,day);
var result = new Date();	
result.setTime(now-birsday);
alert(result.getFullYear() - 1970)
alert(result.getMonth())
alert(result.getDay())

Aetae 05.11.2010 21:11

Цитата:

Сообщение от DooMer (Сообщение 77627)
рони,
Без обид, но выкинь свой говнокод
за 10 мин наваял

Таки не точно получается)
var day = 5;
var month = 11;
var year = 2010;
var now = new Date().getTime();
var birsday = Date.UTC(year,month-1,day);
var result = new Date();  
result.setTime(now-birsday);
alert([result.getFullYear()-1970,result.getMonth(),result.getDay()])

рони 05.11.2010 21:20

DooMer,
Стёр свой код но решил вернуть -- проверяй что мой выдаёт и твой )))
function passed(e, b, a) {
    function g(f, j, k, l) {
        return f + (f % 10 == 1 && f % 100 != 11 ? j : f % 10 >= 2 && f % 10 <= 4 && (f % 100 < 10 || f % 100 >= 20) ? k : l)
    }
    var c = e;
    a = "" + b + "/" + e + "/" + a + "";
    a = new Date(a);
    a.setHours(0, 0, 0, 0);
    b = new Date;
    b.setHours(0, 0, 0, 0);
    var d = a;
    if (b.getTime() < a.getTime()) {
        a = b;
        b = d;
        d = a;
        c = a.getDate()
    }
    for (e = -1; b.getTime() >= d.getTime();) {
        a = new Date(d);
        e++;
        var h = (new Date(d.getFullYear(), d.getMonth() + 2, 0)).getDate(),
            i = c;
        if (h < c) i = h;
        d.setMonth(d.getMonth() + 1, i)
    }
    c = b.getTime() - a.getTime();
    c = (c - c % 864E5) / 864E5;
    c = c > 0 ? g(c, " \u0434\u0435\u043d\u044c ", " \u0434\u043d\u044f ", " \u0434\u043d\u0435\u0439 ") : "";
    a = (e - e % 12) / 12;
    a = a > 0 ? g(a, " \u0433\u043e\u0434 ", " \u0433\u043e\u0434\u0430 ", " \u043b\u0435\u0442 ") : "";
    b = e % 12;
    b = b > 0 ? g(b, " \u043c\u0435\u0441\u044f\u0446 ", " \u043c\u0435\u0441\u044f\u0446\u0430 ", " \u043c\u0435\u0441\u044f\u0446\u0435\u0432 ") : "";
    return a + b + c || "0 \u0434\u043d\u0435\u0439"
};
alert(passed('5','11','2010')+' :) ');
alert("до нового года "+passed('31','12',(new Date()).getFullYear())+' :) ');

Aetae 05.11.2010 22:08

Рано радуешься рони, дело в опечатке))
result.getDay() >> result.getDate()
getDay это таки день недели.)
var day = 5;
var month = 11;
var year = 2010;
var now = new Date().getTime();
var birsday = Date.UTC(year,month-1,day);
var result = new Date();  
result.setTime(now-birsday);
alert([result.getFullYear()-1970,result.getMonth(),result.getDate()])


Подведя итоги:
function passed(y,m,d){
  var r=new Date(new Date().getTime()-Date.UTC(y,m-1,d));
  return [r.getFullYear()-1970,r.getMonth(),r.getDate()-1]
}
alert(passed(2010,11,5))
alert(passed(1990,8,24))

рони 05.11.2010 22:51

Aetae,
отмотаем два месяца назад ровно ))) и сравним
function passed(y,m,d){
  var r=new Date(new Date().getTime()-Date.UTC(y,m-1,d));
  return [r.getFullYear()-1970,r.getMonth(),r.getDate()-1]
}
alert(passed(2010,9,5))

Aetae 05.11.2010 23:05

Лол, интересно почему?))

рони 05.11.2010 23:42

Aetae,
Попытка прояснить )))
сентябрь 30 дней -5 = 25 дней
октябрь 31 день
из ноября 5 дней
итого 61 день
сравнение по скрипту с январём 31день и февралём 28 дней итого 59 дней
61 - 59 = 2 дня
итого скрипт выдал 2 месяца 2 дня

Aetae 06.11.2010 00:28

Тоды примерно так, должно быть дубово)):
function passed(d,m,y){
var t=new Date();
return [t.setDate(t.getDate()-d+1)&&(t.getDate()-1),t.setMonth(t.getMonth()-m+1)&&t.getMonth(),t.getFullYear()-y]
}
alert(passed(5,11,2010));
alert(passed(5,9,2010));
alert(passed(24,8,1990));


Хотя не факт, терзают меня некие сомнения)

рони 06.11.2010 03:33

Aetae,
Пара житейских примеров два человека взяли кредит на месяц один 30 октября другой 31 для обоих месяц закончиться 30 ноября, человек родился в високосный год 29 февраля следующие 3 года он будет праздновать день рождения 28 февраля )))

рони 06.11.2010 04:36

Aetae,
В догонку )))
Предположим сегодня 28 февраля 2010 года и мы хотим узнать сколько прошло с 28 декабря и 31 декабря по эту дату...посмотрим что получиться )))
function passed(d,m,y){
var t=new Date(2010,1,28);
return [(new Date(y,m-1,d)).toLocaleDateString(),t.toLocaleDateString(),t.setDate(t.getDate()-d+1)&&(t.getDate()-1),t.setMonth(t.getMonth()-m+1)&&t.getMonth(),t.getFullYear()-y]
}
alert(passed(28,12,2009)+'\n'+passed(31,12,2009));

c 28 прошло 2 месяца а через три дня позднее вроде и срок должен меньше быть а насчитало 2 месяца с хвостиком

ksa 06.11.2010 09:33

Цитата:

Сообщение от рони
два человека взяли кредит

У банков месяц - 30 дней, на сколько я вкурсе...

DooMer 08.11.2010 10:38

ого, ну вы даете. Лана, ппж посмотрю как решается

рони 09.11.2010 00:39

Немного упростил код и описал алгоритм подсчёта (для дат в прошлом)
function passed(d, m, g) {
    //устанавливаем начальное время  и сегодняшнее
    var a = new Date(g, m - 1, d, 0, 0, 0, 0),b = new Date;
    b.setHours(0, 0, 0, 0);
    //увеличивая начальное время на 1 месяц вперёд
    //подсчитываем количество полных месяцев до сегодня
    //если дата превышает число дней следующего месяца
    //то месяцем считаем весь следующий  месяц
    //5 января + 1 месяц = 5 февраля, но 31 января + 1 месяц = 28/29 февраля
    for (m = 0;; m++) {
        g = new Date(a.getFullYear(), a.getMonth() + 2, 0);
        g.getDate() > d && g.setDate(d);
        if (g > b) break;
        a = g
    }
    d = b - a;//оставшееся время за последний неполный месяц, если будет
    d = Math.round(d/864E5);//количество полных дней в этом времени
    g = Math.floor(m/12);//сколько полных лет в подсчитанных месяцах
    m = m % 12;//оставшиеся месяцы от полных лет
    return [g, m, d]
};
alert(passed('24','8','1990'));

Johny 31.03.2011 17:26

Если только нужен возраст, то также можно воспользоваться следующим скриптом:
var d = 31;
var m = 03;
var y = 1987;
var t = new Date();
var a = ( t.getFullYear() - y - ((t.getMonth() - --m||t.getDate() - d)<0) );


Часовой пояс GMT +3, время: 19:58.