I think this a serious limitation for a great function but why not do something like this:
--where zero is the current value of the unit
CREATE FUNCTION [dbo].[DateTrunc]
(
@Unit varchar(10),
@DateTime datetime,
@Num int
)
RETURNS DateTime
AS
BEGIN
RETURN
case left(@Unit, 1)
when 'y' then dateadd(yy, datediff(yy, 0, @DateTime) -@num, 0)
when 'q' then dateadd(qq, datediff(qq, 0, @DateTime) -@num, 0)
when 'w' then dateadd(wk, datediff(wk, 0, @DateTime) -@num, 0)
when 'd' then dateadd(dd, datediff(dd, 0, @DateTime) -@num, 0)
when 'h' then dateadd(hh, datediff(hh, 0, @DateTime) -@num, 0)
when 'n' then dateadd(mi, datediff(mi, 0, @DateTime) -@num, 0)
when 's' then dateadd(ss, datediff(ss, dateadd(dd, datediff(dd, 0, @DateTime), 0), @DateTime) -@num, dateadd(dd, datediff(dd, 0, @DateTime), 0))
when 'm' then
Case when @Unit in ('month', 'mm', 'm') then dateadd(mm, datediff(mm, 0, @DateTime) -@num, 0)
when @Unit in ('minute', 'mi') then dateadd(mi, datediff(mi, 0, @DateTime) -@num, 0)
else null
end
else null
end;
END
GO