It could be written as a UDF but I'm not sure performance would be up to production use.
If you ever find yourself in that situation again, write the UDF as a in-line table-valued function. You get multiple return values and avoid the scalar UDF hit, since the engine will execute it in-line (appropriately enough).
eg:
select t.date, d.date_as_string
from table1 t
cross apply dbo.format_date(t.date,'yyyy-mm-dd') d
If you ever find yourself in that situation again, write the UDF as a in-line table-valued function. You get multiple return values and avoid the scalar UDF hit, since the engine will execute it in-line (appropriately enough).
eg:
select t.date, d.date_as_string from table1 t cross apply dbo.format_date(t.date,'yyyy-mm-dd') d