SSRS中DateTime字段截断秒数时避免时间四舍五入的方案咨询
这个问题我之前帮不少同行解决过——SSRS默认的日期格式化逻辑确实会对秒数做四舍五入,想要截断而非进位保留到分钟的话,有几个靠谱的方案,你可以根据自己的习惯选:
方案1:在SQL查询中提前截断时间(推荐)
把处理逻辑放在数据源层面是最稳妥的,既能减少报表端的计算压力,也能避免格式层面的意外。你可以用SQL Server的DATEADD和DATEDIFF组合来截断时间到分钟:
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, 0, YourDateTimeColumn), 0) AS TruncatedDateTime FROM YourTable
原理很简单:DATEDIFF(MINUTE, 0, YourDateTimeColumn)会计算从SQL Server的基准时间(1900-01-01 00:00:00)到目标时间的总分钟数,再用DATEADD把这个分钟数加回基准时间,就得到了截断到当前分钟起始时刻的时间(比如你的例子会变成2018-05-18 13:14:00.000)。之后在SSRS里直接对这个TruncatedDateTime字段用dd.MM.yyyy HH:mm格式化,就会显示18.05.2018 13:14,完全符合需求。
方案2:在SSRS报表表达式中处理值再格式化
如果不想修改SQL查询,也可以直接在报表的表达式里先截断时间,再套用格式:
=Format(DateAdd("n", DateDiff("n", #1/1/1900#, Fields!YourDateTimeColumn.Value), #1/1/1900#), "dd.MM.yyyy HH:mm")
逻辑和SQL方案一致:先计算目标时间距离1900年1月1日的总分钟数,再把这个分钟数还原成DateTime,这样就去掉了秒和毫秒。之后用Format函数指定格式即可。
另外还有个更直观的写法,直接减去秒数和毫秒:
=Format(DateAdd("s", -DatePart("s", Fields!YourDateTimeColumn.Value) - (DatePart("ms", Fields!YourDateTimeColumn.Value)/1000), Fields!YourDateTimeColumn.Value), "dd.MM.yyyy HH:mm")
这个是直接把当前时间的秒数和毫秒都减掉,强制截断到上一分钟的末尾,效果和前两个方案一样。
为什么直接用格式字符串不行?
SSRS的日期格式化基于.NET的ToString规则,当使用HH:mm格式时,.NET会自动把秒数四舍五入到最近的分钟——你的例子里秒数是59.927,接近60秒,就被进位到下一分钟了。所以必须先修改DateTime值本身,再做格式化。
内容的提问来源于stack exchange,提问作者user2171512

