MySQL日期格式化函数DATE_FORMAT详解与应用

发布时间:2026/10/31 4:21:41
MySQL日期格式化函数DATE_FORMAT详解与应用 1. MySQL日期格式化基础概念在数据库操作中日期时间处理是最常见的需求之一。MySQL提供了丰富的日期时间函数其中DATE_FORMAT()函数是最核心的日期格式化工具。这个函数允许我们将日期时间值按照指定的格式转换为字符串满足各种显示和业务需求。DATE_FORMAT()函数的基本语法是DATE_FORMAT(date, format)其中date参数是要格式化的日期或日期时间值format参数定义了输出格式。MySQL使用特定的格式说明符来表示日期时间的不同部分这些说明符以百分号(%)开头。2. 常用日期格式说明符详解2.1 年、月、日格式化MySQL提供了多种格式说明符来处理年月日的显示-- 年份格式化 SELECT DATE_FORMAT(NOW(), %Y) AS full_year; -- 2023 (4位年份) SELECT DATE_FORMAT(NOW(), %y) AS short_year; -- 23 (2位年份) -- 月份格式化 SELECT DATE_FORMAT(NOW(), %m) AS numeric_month; -- 01-12 SELECT DATE_FORMAT(NOW(), %c) AS month_no_zero; -- 1-12 (无前导零) SELECT DATE_FORMAT(NOW(), %M) AS month_name; -- January-December SELECT DATE_FORMAT(NOW(), %b) AS short_month; -- Jan-Dec -- 日期格式化 SELECT DATE_FORMAT(NOW(), %d) AS day_of_month; -- 01-31 SELECT DATE_FORMAT(NOW(), %e) AS day_no_zero; -- 1-31 (无前导零) SELECT DATE_FORMAT(NOW(), %D) AS day_ordinal; -- 1st, 2nd, 3rd...2.2 时间格式化说明符时间部分的格式化同样丰富-- 12小时制时间 SELECT DATE_FORMAT(NOW(), %h) AS hour_12; -- 01-12 SELECT DATE_FORMAT(NOW(), %I) AS hour_12_alt; -- 同上 SELECT DATE_FORMAT(NOW(), %l) AS hour_12_no_zero; -- 1-12 (无前导零) -- 24小时制时间 SELECT DATE_FORMAT(NOW(), %H) AS hour_24; -- 00-23 SELECT DATE_FORMAT(NOW(), %k) AS hour_24_no_zero; -- 0-23 (无前导零) -- 分钟和秒 SELECT DATE_FORMAT(NOW(), %i) AS minutes; -- 00-59 SELECT DATE_FORMAT(NOW(), %S) AS seconds; -- 00-59 SELECT DATE_FORMAT(NOW(), %s) AS seconds_alt; -- 同上 -- 上午/下午标识 SELECT DATE_FORMAT(NOW(), %p) AS am_pm; -- AM或PM2.3 周和季度相关格式-- 周相关格式 SELECT DATE_FORMAT(NOW(), %W) AS weekday_name; -- Sunday-Saturday SELECT DATE_FORMAT(NOW(), %a) AS short_weekday; -- Sun-Sat SELECT DATE_FORMAT(NOW(), %w) AS weekday_num; -- 0Sunday, 1Monday,...,6Saturday SELECT DATE_FORMAT(NOW(), %u) AS week_num; -- 周数(00-53), Sunday为一周第一天 SELECT DATE_FORMAT(NOW(), %v) AS week_num_iso; -- 周数(01-53), Monday为一周第一天(ISO标准) -- 季度 SELECT DATE_FORMAT(NOW(), %Q) AS quarter; -- 1-43. 实用日期格式化组合示例3.1 常见日期格式-- 标准日期格式 SELECT DATE_FORMAT(NOW(), %Y-%m-%d) AS standard_date; -- 2023-07-15 SELECT DATE_FORMAT(NOW(), %m/%d/%Y) AS us_date; -- 07/15/2023 SELECT DATE_FORMAT(NOW(), %d/%m/%Y) AS european_date; -- 15/07/2023 -- 可读性强的日期格式 SELECT DATE_FORMAT(NOW(), %M %d, %Y) AS long_date; -- July 15, 2023 SELECT DATE_FORMAT(NOW(), %b %d, %Y) AS short_date; -- Jul 15, 2023 SELECT DATE_FORMAT(NOW(), %W, %M %d, %Y) AS full_date; -- Saturday, July 15, 20233.2 时间格式组合-- 24小时制时间 SELECT DATE_FORMAT(NOW(), %H:%i:%s) AS time_24; -- 14:30:45 -- 12小时制时间 SELECT DATE_FORMAT(NOW(), %h:%i:%s %p) AS time_12; -- 02:30:45 PM SELECT DATE_FORMAT(NOW(), %l:%i %p) AS short_time_12; -- 2:30 PM -- 带日期的时间 SELECT DATE_FORMAT(NOW(), %Y-%m-%d %H:%i:%s) AS datetime; -- 2023-07-15 14:30:45 SELECT DATE_FORMAT(NOW(), %b %d, %Y %l:%i %p) AS readable_datetime; -- Jul 15, 2023 2:30 PM3.3 特殊业务场景格式-- 文件命名常用格式 SELECT DATE_FORMAT(NOW(), %Y%m%d_%H%i%s) AS file_timestamp; -- 20230715_143045 -- 日志格式 SELECT DATE_FORMAT(NOW(), %Y-%m-%d %H:%i:%s.%f) AS log_timestamp; -- 2023-07-15 14:30:45.123456 -- 季度报表格式 SELECT DATE_FORMAT(NOW(), Q%Q %Y) AS quarter_report; -- Q3 2023 -- 周报格式 SELECT CONCAT(Week , DATE_FORMAT(NOW(), %v), , , DATE_FORMAT(NOW(), %x)) AS week_report; -- Week 28, 20234. 高级应用与性能优化4.1 动态日期格式处理在实际应用中我们经常需要根据用户偏好或地区设置动态改变日期格式。可以通过应用程序逻辑或存储过程实现DELIMITER // CREATE PROCEDURE format_date_by_locale(IN dt DATETIME, IN locale VARCHAR(10), OUT formatted VARCHAR(50)) BEGIN CASE locale WHEN US THEN SET formatted DATE_FORMAT(dt, %m/%d/%Y); WHEN EU THEN SET formatted DATE_FORMAT(dt, %d/%m/%Y); WHEN ISO THEN SET formatted DATE_FORMAT(dt, %Y-%m-%d); ELSE SET formatted DATE_FORMAT(dt, %Y-%m-%d); END CASE; END // DELIMITER ; -- 调用示例 CALL format_date_by_locale(NOW(), US, us_date); SELECT us_date;4.2 索引与日期格式化需要注意的是对日期列使用函数处理会导致索引失效-- 不推荐(索引失效) SELECT * FROM orders WHERE DATE_FORMAT(order_date, %Y-%m) 2023-07; -- 推荐(可以使用索引) SELECT * FROM orders WHERE order_date 2023-07-01 AND order_date 2023-08-01;4.3 批量日期格式化技巧处理大量数据时可以考虑以下优化方法-- 使用临时表存储格式化结果 CREATE TEMPORARY TABLE temp_formatted_dates AS SELECT id, DATE_FORMAT(created_at, %Y-%m-%d) AS formatted_date FROM large_table; -- 使用视图预定义常用格式 CREATE VIEW vw_formatted_dates AS SELECT id, DATE_FORMAT(created_at, %Y-%m-%d) AS standard_date, DATE_FORMAT(created_at, %M %d, %Y) AS long_date, DATE_FORMAT(created_at, %W) AS weekday FROM orders;4.4 时区处理MySQL的日期格式化函数默认使用服务器时区设置。如果需要处理不同时区的时间可以结合CONVERT_TZ函数SET time_zone 00:00; -- 设置为UTC时间 SELECT DATE_FORMAT(NOW(), %Y-%m-%d %H:%i:%s) AS utc_time; SET time_zone 08:00; -- 设置为北京时间 SELECT DATE_FORMAT(NOW(), %Y-%m-%d %H:%i:%s) AS beijing_time; -- 动态转换时区 SELECT DATE_FORMAT( CONVERT_TZ(NOW(), session.time_zone, 09:00), %Y-%m-%d %H:%i:%s ) AS tokyo_time;5. 常见问题与解决方案5.1 日期格式化中的NULL处理当输入日期为NULL时DATE_FORMAT()会返回NULL。可以使用IFNULL或COALESCE函数处理SELECT DATE_FORMAT(IFNULL(some_date, NOW()), %Y-%m-%d) AS safe_date FROM some_table; -- 或者使用COALESCE SELECT DATE_FORMAT(COALESCE(some_date, NOW()), %Y-%m-%d) AS safe_date FROM some_table;5.2 语言环境问题MySQL的日期格式函数默认使用英语输出月份和星期名称。如果需要其他语言可以设置lc_time_names系统变量-- 查看当前语言设置 SELECT lc_time_names; -- 设置为中文 SET lc_time_names zh_CN; SELECT DATE_FORMAT(NOW(), %W %M %d %Y); -- 星期六 七月 15 2023 -- 设置为法语 SET lc_time_names fr_FR; SELECT DATE_FORMAT(NOW(), %W %M %d %Y); -- samedi juillet 15 20235.3 性能优化建议避免在WHERE子句中使用DATE_FORMAT这会导致索引失效应该使用日期范围查询替代。考虑使用计算列对于频繁使用的格式化日期可以在表中添加计算列ALTER TABLE orders ADD COLUMN formatted_date VARCHAR(20) GENERATED ALWAYS AS (DATE_FORMAT(order_date, %Y-%m-%d)) STORED;批量处理优于单条处理在应用程序中处理大量日期格式化时尽量使用一条SQL完成多个日期的格式化而不是循环调用。5.4 日期格式验证在接收用户输入的日期格式字符串时应该验证其有效性。以下是一个简单的验证存储过程DELIMITER // CREATE PROCEDURE validate_date_format(IN format_str VARCHAR(50), OUT is_valid BOOLEAN) BEGIN DECLARE test_result VARCHAR(100); DECLARE CONTINUE HANDLER FOR 1411 DO SET is_valid FALSE; SET is_valid TRUE; SET test_result DATE_FORMAT(NOW(), format_str); END // DELIMITER ; -- 调用示例 CALL validate_date_format(%Y-%m-%d, valid); SELECT valid; -- 1 (TRUE) CALL validate_date_format(%Y-%m-%x, valid); SELECT valid; -- 0 (FALSE)6. 实际应用案例6.1 报表生成生成月度销售报表时日期格式化非常重要SELECT DATE_FORMAT(order_date, %Y-%m) AS month, COUNT(*) AS order_count, SUM(amount) AS total_amount FROM orders GROUP BY DATE_FORMAT(order_date, %Y-%m) ORDER BY month;6.2 用户界面显示在用户个人中心显示友好的日期格式SELECT user_id, username, DATE_FORMAT(created_at, %M %d, %Y) AS join_date, DATE_FORMAT(last_login, %b %d, %Y at %h:%i %p) AS last_login_time FROM users WHERE user_id 123;6.3 数据导出导出数据到CSV时统一日期格式SELECT order_id, customer_name, DATE_FORMAT(order_date, %Y-%m-%d) AS order_date, DATE_FORMAT(ship_date, %m/%d/%Y) AS ship_date, amount FROM orders INTO OUTFILE /tmp/orders_export.csv FIELDS TERMINATED BY , ENCLOSED BY LINES TERMINATED BY \n;6.4 生日提醒查找即将过生日的用户SELECT user_id, name, DATE_FORMAT(birthday, %M %d) AS birthday, CONCAT( FLOOR(DATEDIFF( DATE_ADD(birthday, INTERVAL YEAR(CURDATE())-YEAR(birthday) YEAR), CURDATE() ) / 365 * 12), months ) AS age_next_birthday FROM users WHERE DATE_FORMAT(birthday, %m-%d) BETWEEN DATE_FORMAT(CURDATE(), %m-%d) AND DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 7 DAY), %m-%d) ORDER BY DATE_FORMAT(birthday, %m-%d);7. 与其他日期函数的结合使用DATE_FORMAT()函数可以与其他MySQL日期函数结合使用实现更复杂的日期处理需求。7.1 与DATE_ADD/DATE_SUB结合-- 显示下周今天的日期 SELECT DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 7 DAY), %W, %M %d, %Y) AS next_week; -- 显示上个月同一天的日期 SELECT DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), %Y-%m-%d) AS last_month;7.2 与DATEDIFF/TIMESTAMPDIFF结合-- 计算年龄并格式化显示 SELECT name, birthday, DATE_FORMAT(birthday, %Y-%m-%d) AS birth_date, TIMESTAMPDIFF(YEAR, birthday, CURDATE()) AS age, CONCAT( TIMESTAMPDIFF(YEAR, birthday, CURDATE()), years, , TIMESTAMPDIFF(MONTH, birthday, CURDATE()) % 12, months ) AS age_detail FROM users;7.3 与STR_TO_DATE结合STR_TO_DATE()是DATE_FORMAT()的反函数用于将字符串转换为日期-- 将各种格式的日期字符串转换为标准日期 SELECT STR_TO_DATE(July 15, 2023, %M %d, %Y) AS date1, STR_TO_DATE(15/07/2023, %d/%m/%Y) AS date2, STR_TO_DATE(20230715, %Y%m%d) AS date3; -- 结合DATE_FORMAT使用 SELECT DATE_FORMAT( STR_TO_DATE(15-Jul-2023, %d-%b-%Y), %Y-%m-%d ) AS formatted_date;8. 版本差异与兼容性不同MySQL版本在日期格式化方面有一些差异需要注意8.1 MySQL 5.7与8.0的差异微秒支持MySQL 8.0更好地支持微秒精度-- MySQL 5.7 SELECT DATE_FORMAT(2023-07-15 14:30:45.123456, %f); -- 只显示123456 -- MySQL 8.0 SELECT DATE_FORMAT(2023-07-15 14:30:45.123456, %f); -- 正确显示123456时区处理MySQL 8.0的时区处理更加完善性能优化MySQL 8.0对日期函数进行了更多优化8.2 跨数据库兼容性如果需要考虑与其他数据库的兼容性可以创建兼容性函数-- 创建类似Oracle的TO_CHAR函数 DELIMITER // CREATE FUNCTION to_char(dt DATETIME, format_str VARCHAR(100)) RETURNS VARCHAR(100) DETERMINISTIC BEGIN RETURN DATE_FORMAT(dt, REPLACE( REPLACE( REPLACE(format_str, YYYY, %Y), MM, %m ), DD, %d ) ); END // DELIMITER ; -- 使用示例 SELECT to_char(NOW(), YYYY-MM-DD) AS oracle_style_date;9. 最佳实践总结一致性原则在整个应用中保持日期格式的一致性性能考虑避免在WHERE、JOIN或GROUP BY子句中使用DATE_FORMAT可读性面向用户的日期显示应该更加友好存储格式在数据库中始终以标准格式存储日期时间时区意识明确处理时区问题特别是跨时区应用验证输入严格验证用户提供的日期格式字符串文档化记录团队约定的日期格式标准10. 扩展资源MySQL官方文档DATE_FORMAT函数详细说明ICU库更强大的国际化日期格式化moment.js前端日期处理的优秀库Joda-TimeJava平台的日期时间库在实际项目中合理使用DATE_FORMAT函数可以大大简化日期时间处理工作提升开发效率和用户体验。掌握这些技巧后你将能够轻松应对各种日期格式化需求。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询