Как вычислить возраст (в течение многих лет) на основе Даты рождения и getDate ()

Это несущественно, который верен. Что делает Вы подразумеваете под станд.:: интерфейс строки, являющийся большим? Что делает большой средний в этом контексте - много вызовов метода? Я не остроумен, мне на самом деле интересно.

Это имеет больше методов, чем этому действительно нужно, и его поведение использования интегральных смещений, а не итераторов немного сомнительно (поскольку это противоречит пути остальная часть работ библиотеки).

реальная проблема, я думаю, - то, что библиотека C++ имеет три части; это имеет старую библиотеку C, это имеет STL, и это имеет strings-iostreams. Хотя некоторые усилия были приложены для образования моста различных частей (например, добавление перегрузок к библиотеке C, потому что перегрузка поддержек C++; добавление итераторов к basic_string; добавление iostream адаптеров итератора), существует много несоответствий при рассмотрении детали.

, Например, basic_string включает методы, которые являются ненужными дубликатами стандартных алгоритмов; различные методы находки, мог, вероятно, быть безопасно удален. Другой пример: локали используют необработанные указатели вместо итераторов.

157
задан user990423 2 December 2015 в 23:28
поделиться

5 ответов

Есть проблемы с високосным годом / днями и следующим методом, см. Обновление ниже:

попробуйте следующее:

 DECLARE @dob datetime
SET @ dob = '1992-01-09 00:00:00'

ВЫБЕРИТЕ DATEDIFF (час, @ dob, GETDATE ()) / 8766.0 AS AgeYearsDecimal
 , CONVERT (int, ROUND (DATEDIFF (час, @ dob, GETDATE ()) / 8766.0,0)) КАК AgeYearsIntRound
 , DATEDIFF (час, @ dob, GETDATE ()) / 8766 AS AgeYearsIntTrunc

ВЫХОД:

 ВозрастYearsDecimal AgeYearsIntRound AgeYearsIntTrunc
--------------------------------------- ----------- ----- ----------------
17.767054 18 17

(Затронута 1 строка (и))

UPDATE вот несколько более точных методов:

НАИЛУЧШИЙ МЕТОД ЗА ГОДЫ IN INT

DECLARE @Now  datetime, @Dob datetime
SELECT   @Now='1990-05-05', @Dob='1980-05-05'  --results in 10
--SELECT @Now='1990-05-04', @Dob='1980-05-05'  --results in  9
--SELECT @Now='1989-05-06', @Dob='1980-05-05'  --results in  9
--SELECT @Now='1990-05-06', @Dob='1980-05-05'  --results in 10
--SELECT @Now='1990-12-06', @Dob='1980-05-05'  --results in 10
--SELECT @Now='1991-05-04', @Dob='1980-05-05'  --results in 10

SELECT
    (CONVERT(int,CONVERT(char(8),@Now,112))-CONVERT(char(8),@Dob,112))/10000 AS AgeIntYears

вы можете изменить вышеуказанное 10000 на 10000.0 и получить десятичные дроби, но он не будет таким точным, как метод ниже.

НАИЛУЧШИЙ МЕТОД ЗА ГОДЫ В ДЕСЯТИЧНЫХ ЧИСЛАХ

DECLARE @Now  datetime, @Dob datetime
SELECT   @Now='1990-05-05', @Dob='1980-05-05' --results in 10.000000000000
--SELECT @Now='1990-05-04', @Dob='1980-05-05' --results in  9.997260273973
--SELECT @Now='1989-05-06', @Dob='1980-05-05' --results in  9.002739726027
--SELECT @Now='1990-05-06', @Dob='1980-05-05' --results in 10.002739726027
--SELECT @Now='1990-12-06', @Dob='1980-05-05' --results in 10.589041095890
--SELECT @Now='1991-05-04', @Dob='1980-05-05' --results in 10.997260273973

SELECT 1.0* DateDiff(yy,@Dob,@Now) 
    +CASE 
         WHEN @Now >= DATEFROMPARTS(DATEPART(yyyy,@Now),DATEPART(m,@Dob),DATEPART(d,@Dob)) THEN  --birthday has happened for the @now year, so add some portion onto the year difference
           (  1.0   --force automatic conversions from int to decimal
              * DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),DATEPART(m,@Dob),DATEPART(d,@Dob)),@Now) --number of days difference between the @Now year birthday and the @Now day
              / DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),1,1),DATEFROMPARTS(DATEPART(yyyy,@Now)+1,1,1)) --number of days in the @Now year
           )
         ELSE  --birthday has not been reached for the last year, so remove some portion of the year difference
           -1 --remove this fractional difference onto the age
           * (  -1.0   --force automatic conversions from int to decimal
                * DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),DATEPART(m,@Dob),DATEPART(d,@Dob)),@Now) --number of days difference between the @Now year birthday and the @Now day
                / DATEDIFF(day,DATEFROMPARTS(DATEPART(yyyy,@Now),1,1),DATEFROMPARTS(DATEPART(yyyy,@Now)+1,1,1)) --number of days in the @Now year
             )
     END AS AgeYearsDecimal
238
ответ дан 23 November 2019 в 21:42
поделиться

Надо выбросить это. Если вы конвертируете дату с использованием стиля 112 (ггггммдд) в число, вы можете использовать следующий расчет ...

(ггггММдд - ггггММдд) / 10000 = разница в полных годах

declare @as_of datetime, @bday datetime;
select @as_of = '2009/10/15', @bday = '1980/4/20'

select 
    Convert(Char(8),@as_of,112),
    Convert(Char(8),@bday,112),
    0 + Convert(Char(8),@as_of,112) - Convert(Char(8),@bday,112), 
    (0 + Convert(Char(8),@as_of,112) - Convert(Char(8),@bday,112)) / 10000

вывод

20091015    19800420    290595  29
116
ответ дан 23 November 2019 в 21:42
поделиться
SELECT ID,
Name,
DATEDIFF(yy,CONVERT(DATETIME, DOB),GETDATE()) AS AGE,
DOB
FROM MyTable
3
ответ дан 23 November 2019 в 21:42
поделиться

Я использовал этот запрос в нашем производственном коде почти 10 лет:

SELECT FLOOR((CAST (GetDate() AS INTEGER) - CAST(Date_of_birth AS INTEGER)) / 365.25) AS Age
40
ответ дан 23 November 2019 в 21:42
поделиться

Вам необходимо учитывать способ обхода команды dateiff.

SELECT CASE WHEN dateadd(year, datediff (year, DOB, getdate()), DOB) > getdate()
            THEN datediff(year, DOB, getdate()) - 1
            ELSE datediff(year, DOB, getdate())
       END as Age
FROM <table>

Который я адаптировал из здесь

15
ответ дан 23 November 2019 в 21:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: