Это несущественно, который верен. Что делает Вы подразумеваете под станд.:: интерфейс строки, являющийся большим? Что делает большой средний в этом контексте - много вызовов метода? Я не остроумен, мне на самом деле интересно.
Это имеет больше методов, чем этому действительно нужно, и его поведение использования интегральных смещений, а не итераторов немного сомнительно (поскольку это противоречит пути остальная часть работ библиотеки).
реальная проблема, я думаю, - то, что библиотека C++ имеет три части; это имеет старую библиотеку C, это имеет STL, и это имеет strings-iostreams. Хотя некоторые усилия были приложены для образования моста различных частей (например, добавление перегрузок к библиотеке C, потому что перегрузка поддержек C++; добавление итераторов к basic_string; добавление iostream адаптеров итератора), существует много несоответствий при рассмотрении детали.
, Например, basic_string включает методы, которые являются ненужными дубликатами стандартных алгоритмов; различные методы находки, мог, вероятно, быть безопасно удален. Другой пример: локали используют необработанные указатели вместо итераторов.
Есть проблемы с високосным годом / днями и следующим методом, см. Обновление ниже:
попробуйте следующее:
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
Надо выбросить это. Если вы конвертируете дату с использованием стиля 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
SELECT ID,
Name,
DATEDIFF(yy,CONVERT(DATETIME, DOB),GETDATE()) AS AGE,
DOB
FROM MyTable
Я использовал этот запрос в нашем производственном коде почти 10 лет:
SELECT FLOOR((CAST (GetDate() AS INTEGER) - CAST(Date_of_birth AS INTEGER)) / 365.25) AS Age
Вам необходимо учитывать способ обхода команды 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>
Который я адаптировал из здесь