在处理订单时间、用户注册日期或报表统计时,日期函数几乎是SQL查询里绕不开的部分。SQL Server和MySQL虽然都支持日期类型和丰富的日期函数,但命名、参数顺序、返回类型以及底层存储方式差异很大。比如获取当前日期时间,SQL Server使用GETDATE(),MySQL则可以选择NOW()或CURDATE()。如果只是简单替换函数名,往往会出现字段类型不匹配、索引失效甚至时区偏移等问题。下面从日期类型开始,把两类数据库常用的Date函数按使用场景拆开说明。

一、日期类型与当前时间获取方式
先看底层类型差异。SQL Server常用日期类型有DATE、DATETIME、DATETIME2、SMALLDATETIME和DATETIMEOFFSET。其中DATETIME精度为约3.33毫秒,范围从1753年1月1日到9999年12月31日;DATETIME2精度可到100纳秒,范围从0001年1月1日到9999年12月31日,更推荐使用。MySQL常用日期类型包括DATE、DATETIME、TIMESTAMP和YEAR。DATETIME支持1000-01-01 00:00:00到9999-12-31 23:59:59,而TIMESTAMP本质是UTC时间戳,范围为1970-01-01 00:00:01 UTC到2038-01-19 03:14:07 UTC,并且受会话时区影响。理解这些差异后,才知道为什么同一个日期在不同类型或不同库中表现不一样。
获取当前日期和时间是最基础的需求。SQL Server中GETDATE()返回当前系统的DATETIME,SYSDATETIME()返回DATETIME2,CURRENT_TIMESTAMP是标准SQL写法,等价于GETDATE()。如果只想要日期部分,可以使用CAST(GETDATE() AS DATE)。MySQL中NOW()返回当前DATETIME,CURDATE()只返回日期,CURTIME()只返回时间,SYSDATE()与NOW()类似,但在函数执行时取值,可能受语句执行时间影响。具体可看下面的查询示例。
-- SQL Server:获取当前日期时间
SELECT GETDATE() AS current_datetime,
SYSDATETIME() AS current_datetime2,
CAST(GETDATE() AS DATE) AS current_date;
-- MySQL:获取当前日期时间
SELECT NOW() AS current_datetime,
CURDATE() AS current_date,
CURTIME() AS current_time;
这里要特别注意,CURRENT_TIMESTAMP在两个数据库中都能使用,但MySQL里它默认等价于NOW(),而SQL Server里它等价于GETDATE()。如果项目要求数据库无关性,可以优先考虑标准函数,但也要验证返回精度和时区行为。
二、日期格式化、加减与差值计算
日期格式化在日常开发中非常高频。SQL Server从2012版开始提供了FORMAT()函数,可以按.NET格式字符串输出,例如FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm:ss')。不过FORMAT()在数据量大时性能一般,更推荐使用CONVERT()配合样式代码,比如CONVERT(VARCHAR(19), GETDATE(), 120)输出yyyy-mm-dd hh:mi:ss。MySQL则使用DATE_FORMAT(),例如DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s')。两者的格式化占位符完全不同,MySQL用%Y表示四位年份、%m表示月份、%d表示日,而SQL Server的FORMAT()用yyyy、MM、dd。
日期加减同样存在命名差异。SQL Server用DATEADD(datepart, number, date),第一个参数是日期部分,例如DAY、MONTH、YEAR、HOUR;MySQL用DATE_ADD(date, INTERVAL expr unit)和DATE_SUB(date, INTERVAL expr unit),单位是DAY、MONTH、YEAR、HOUR等。SQL Server语法更偏函数参数,MySQL的INTERVAL则更直观。下面给出对比代码。
-- SQL Server:日期加减
SELECT DATEADD(DAY, 7, GETDATE()) AS add_7_days,
DATEADD(MONTH, -1, GETDATE()) AS subtract_1_month,
DATEADD(HOUR, 2, GETDATE()) AS add_2_hours;
-- MySQL:日期加减
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY) AS add_7_days,
DATE_SUB(NOW(), INTERVAL 1 MONTH) AS subtract_1_month,
DATE_ADD(NOW(), INTERVAL 2 HOUR) AS add_2_hours;
计算两个日期之间的差值时,SQL Server用DATEDIFF(datepart, startdate, enddate),它返回跨过的边界数,而不是完整的时间差。例如DATEDIFF(DAY, '2025-01-01 23:59:59', '2025-01-02 00:00:01')结果是1,虽然实际只差2秒。MySQL的DATEDIFF(date1, date2)只计算日期部分差值,返回天数;如果要计算时间差,用TIMESTAMPDIFF(unit, start, end),其中unit可以是SECOND、MINUTE、HOUR、DAY等。如果需要精确到秒,SQL Server要使用DATEDIFF_BIG或转换后计算,MySQL则直接TIMESTAMPDIFF(SECOND, start, end)。
-- SQL Server:日期差值
SELECT DATEDIFF(DAY, '2025-01-01', '2025-01-10') AS day_diff,
DATEDIFF(MINUTE, '2025-01-01 10:00:00', '2025-01-01 12:30:00') AS minute_diff;
-- MySQL:日期差值
SELECT DATEDIFF('2025-01-10', '2025-01-01') AS day_diff,
TIMESTAMPDIFF(MINUTE, '2025-01-01 10:00:00', '2025-01-01 12:30:00') AS minute_diff;
三、日期函数常见问题与避坑指南
第一个高频问题是在WHERE条件里对日期列使用函数,导致索引失效。比如想查询某天注册的用户,不少开发者会写WHERE CONVERT(VARCHAR(10), create_time, 120) = '2025-01-01'或WHERE DATE(create_time) = '2025-01-01'。这两种写法在数据量较小时看不出问题,但列上的函数会阻止优化器使用索引,造成全表扫描。SQL Server推荐写成范围查询:WHERE create_time >= '2025-01-01' AND create_time < '2025-01-02';MySQL同样可以用范围条件:WHERE create_time >= '2025-01-01 00:00:00' AND create_time < '2025-01-02 00:00:00'。如果确实需要按日期分组,可以在表设计时增加持久化计算列或生成列。
第二个常见问题是时区。MySQL的TIMESTAMP列会自动从当前会话时区转换到UTC存储,读取时再转换回会话时区,所以同一行数据在不同时区连接下会显示不同时间。SQL Server的DATETIMEOFFSET可以保存时区偏移,但普通的DATETIME和DATETIME2不携带时区信息。如果系统涉及跨时区业务,建议尽量用DATETIMEOFFSET或统一使用UTC时间存储,在应用层做展示转换。MySQL可以在连接串中设置serverTimezone=UTC,并检查数据库的time_zone变量。
第三个问题是在SQL Server和MySQL之间迁移时,日期函数不能一一照搬。例如NOW()在MySQL里常用,但SQL Server没有NOW();SQL Server的GETDATE()在MySQL里也无效。可以通过封装公共函数或ORM层统一处理。下表列出常用对应关系。
| 功能 | SQL Server | MySQL |
|---|---|---|
| 当前日期时间 | GETDATE() | NOW() |
| 当前日期 | CAST(GETDATE() AS DATE) | CURDATE() |
| 日期格式化 | FORMAT() 或 CONVERT() | DATE_FORMAT() |
| 日期加减 | DATEADD() | DATE_ADD() / DATE_SUB() |
| 日期差值 | DATEDIFF() | DATEDIFF() / TIMESTAMPDIFF() |
| 提取年/月/日 | YEAR() / MONTH() / DAY() | YEAR() / MONTH() / DAY() |
最后还要注意DATETIME与DATE比较时的隐式转换问题。SQL Server中字符串转日期依赖语言和日期格式设置,推荐始终使用YYYY-MM-DD或YYYYMMDD格式,避免MM/DD/YYYY与DD/MM/YYYY混淆。MySQL在严格模式下,插入非法日期会报错,非严格模式可能写入0000-00-00,因此生产环境建议开启严格模式。掌握这些函数和边界行为,基本能覆盖日常开发中大多数日期处理场景。
SQL Server Date函数MySQL Date函数日期函数对比修改时间:2026-10-06 23:57:56