MySQL cung cấp một bộ sưu tập phong phú các hàm tích hợp sẵn để thao tác và định dạng dữ liệu ngày tháng, thời gian. Việc nắm vững các hàm này giúp người dùng dễ dàng truy vấn, phân tích và hiển thị thông tin thời gian theo nhiều cách khác nhau. Dưới đây là danh sách các hàm xử lý ngày tháng phổ biến trong MySQL cùng với ví dụ minh họa.
1. DAYOFWEEK(ngay)
Hàm này trả về chỉ số ngày trong tuần của một ngày cụ thể. Chủ Nhật được tính là 1, Thứ Hai là 2, ..., và Thứ Bảy là 7.
SELECT DAYOFWEEK('2023-08-15');
-- Kết quả: 3 (Thứ Ba)
SELECT DAYOFWEEK('2023-08-13 10:30:00');
-- Kết quả: 1 (Chủ Nhật)
2. WEEKDAY(ngay)
Hàm này trả về chỉ số ngày trong tuần theo quy ước phương Tây, với Thứ Hai là 0. Cụ thể: Thứ Hai = 0, Thứ Ba = 1, ..., và Chủ Nhật = 6.
SELECT WEEKDAY('2023-08-15');
-- Kết quả: 1 (Thứ Ba)
SELECT WEEKDAY('2023-08-13 10:30:00');
-- Kết quả: 6 (Chủ Nhật)
3. DAYOFMONTH(ngay)
Trả về ngày trong tháng của một ngày cụ thể, từ 1 đến 31.
SELECT DAYOFMONTH('2023-08-15');
-- Kết quả: 15
SELECT DAYOFMONTH('2023-01-01');
-- Kết quả: 1
4. DAYOFYEAR(ngay)
Trả về số thứ tự ngày trong năm của một ngày cụ thể, từ 1 đến 366.
SELECT DAYOFYEAR('2023-03-01');
-- Kết quả: 60 (Ngày 1 tháng 3 năm 2023 là ngày thứ 60 trong năm)
SELECT DAYOFYEAR('2024-03-01');
-- Kết quả: 61 (Vì 2024 là năm nhuận)
5. MONTH(ngay)
Trả về tháng của một ngày cụ thể, từ 1 đến 12.
SELECT MONTH('2023-08-15');
-- Kết quả: 8
SELECT MONTH('2023-01-05 14:00:00');
-- Kết quả: 1
6. DAYNAME(ngay)
Trả về tên ngày trong tuần bằng tiếng Anh (ví dụ: 'Monday', 'Tuesday').
SELECT DAYNAME('2023-08-15');
-- Kết quả: 'Tuesday'
SELECT DAYNAME('2023-08-13 10:30:00');
-- Kết quả: 'Sunday'
7. MONTHNAME(ngay)
Trả về tên tháng bằng tiếng Anh (ví dụ: 'January', 'February').
SELECT MONTHNAME('2023-08-15');
-- Kết quả: 'August'
SELECT MONTHNAME('2023-01-20');
-- Kết quả: 'January'
8. QUARTER(ngay)
Trả về quý trong năm của một ngày cụ thể, từ 1 đến 4.
SELECT QUARTER('2023-01-15');
-- Kết quả: 1
SELECT QUARTER('2023-07-20 12:00:00');
-- Kết quả: 3
9. WEEK(ngay, chế_độ)
Hàm này trả về số tuần trong năm của ngày đã cho. Tham số chế_độ (mode) ảnh hưởng đến việc xác định ngày bắt đầu tuần và cách đánh số tuần. Giá trị mặc định của chế_độ là 0.
0(mặc định): Chủ Nhật là ngày đầu tuần, tuần đầu tiên của năm chứa ngày 1 tháng 1. Số tuần từ 0-53.1: Thứ Hai là ngày đầu tuần, tuần đầu tiên của năm có ít nhất 4 ngày trong năm mới. Số tuần từ 0-53.- Các giá trị
chế_độkhác có thể tham khảo thêm trong tài liệu MySQL chính thức.
SELECT WEEK('2023-01-01', 0);
-- Kết quả: 0 (Với mode 0, ngày 1 tháng 1 năm 2023 là Chủ Nhật, nằm trong tuần đầu tiên nhưng có thể được đánh số 0)
SELECT WEEK('2023-01-01', 1);
-- Kết quả: 0 (Với mode 1, ngày 1 tháng 1 năm 2023 là Chủ Nhật, tuần bắt đầu từ Thứ Hai, nên ngày 1 tháng 1 nằm trong tuần cuối của năm trước hoặc tuần 0 của năm nay)
SELECT WEEK('2023-01-02', 1);
-- Kết quả: 1 (Với mode 1, ngày 2 tháng 1 năm 2023 là Thứ Hai, là ngày đầu tiên của tuần 1)
Lưu ý: Kết quả của hàm WEEK có thể thay đổi tùy theo phiên bản MySQL và cấu hình hệ thống.
10. YEAR(ngay)
Trả về năm của một ngày cụ thể, dưới dạng số có 4 chữ số.
SELECT YEAR('1999-12-31');
-- Kết quả: 1999
SELECT YEAR('2025-01-01 00:00:00');
-- Kết quả: 2025
SELECT YEAR('75-06-10');
-- Kết quả: 1975 (Năm có 2 chữ số >= 70 được bổ sung tiền tố '19')
SELECT YEAR('25-06-10');
-- Kết quả: 2025 (Năm có 2 chữ số < 70 được bổ sung tiền tố '20')
Quy tắc bổ sung năm 2 chữ số: Nếu năm có hai chữ số và giá trị >= 70, MySQL giả định tiền tố '19'. Nếu giá trị < 70, MySQL giả định tiền tố '20'.
11. HOUR(thoi_gian)
Trả về giá trị giờ của một thời gian hoặc datetime, từ 0 đến 23.
SELECT HOUR('15:45:30');
-- Kết quả: 15
SELECT HOUR('2023-08-15 09:10:05');
-- Kết quả: 9
12. MINUTE(thoi_gian)
Trả về giá trị phút của một thời gian hoặc datetime, từ 0 đến 59.
SELECT MINUTE('15:45:30');
-- Kết quả: 45
SELECT MINUTE('2023-08-15 09:10:05');
-- Kết quả: 10
13. SECOND(thoi_gian)
Trả về giá trị giây của một thời gian hoặc datetime, từ 0 đến 59.
SELECT SECOND('15:45:30');
-- Kết quả: 30
SELECT SECOND('2023-08-15 09:10:05');
-- Kết quả: 5
14. PERIOD_ADD(chu_ky_thang, so_thang)
Cộng thêm số tháng vào một chu kỳ tháng (ở định dạng YYMM hoặc YYYYMM) và trả về kết quả dưới dạng YYYYMM.
SELECT PERIOD_ADD(202301, 3);
-- Kết quả: 202304
SELECT PERIOD_ADD(2306, -2);
-- Kết quả: 202304
15. PERIOD_DIFF(chu_ky_thang_ket_thuc, chu_ky_thang_bat_dau)
Tính toán số tháng chênh lệch giữa hai chu kỳ tháng (ở định dạng YYMM hoặc YYYYMM). Hàm này trả về chu_ky_thang_ket_thuc - chu_ky_thang_bat_dau.
SELECT PERIOD_DIFF(202308, 202301);
-- Kết quả: 7
SELECT PERIOD_DIFF(202401, 202310);
-- Kết quả: 3
SELECT PERIOD_DIFF(202301, 202308);
-- Kết quả: -7
16. DATE_ADD(ngay, INTERVAL giá_trị đơn_vị) và ADDDATE(ngay, INTERVAL giá_trị đơn_vị)
Thêm một khoảng thời gian cụ thể vào một giá trị ngày hoặc datetime. Cả hai hàm DATE_ADD() và ADDDATE() đều có chức năng tương tự.
Tham số ngay có thể là chuỗi, DATE, hoặc DATETIME. Nếu ngay là DATE, kết quả là DATE. Nếu ngay là DATETIME, kết quả là DATETIME.
Các đơn_vị (unit) phổ biến bao gồm:
SECOND(giây)MINUTE(phút)HOUR(giờ)DAY(ngày)MONTH(tháng)YEAR(năm)- Các kết hợp như
MINUTE_SECOND('phút:giây'),DAY_HOUR('ngày giờ'), v.v.
SELECT DATE_ADD('2023-12-31 10:00:00', INTERVAL 1 HOUR);
-- Kết quả: 2023-12-31 11:00:00
SELECT ADDDATE('2023-01-15', INTERVAL 5 DAY);
-- Kết quả: 2023-01-20
SELECT DATE_ADD('2023-12-01', INTERVAL '1-2' YEAR_MONTH);
-- Kết quả: 2024-02-01
SELECT DATE_ADD('2023-08-15', INTERVAL -3 DAY);
-- Kết quả: 2023-08-12
Ngoài ra, có thể sử dụng các toán tử + và - trực tiếp với INTERVAL:
SELECT '2023-08-15' + INTERVAL 1 DAY;
-- Kết quả: 2023-08-16
SELECT '2023-08-15 10:00:00' - INTERVAL '01:30' HOUR_MINUTE;
-- Kết quả: 2023-08-15 08:30:00
17. DATE_SUB(ngay, INTERVAL giá_trị đơn_vị) và SUBDATE(ngay, INTERVAL giá_trị đơn_vị)
Trừ một khoảng thời gian cụ thể khỏi một giá trị ngày hoặc datetime. Chức năng tương tự như DATE_ADD() và ADDDATE() nhưng thực hiện phép trừ. Tham khảo các loại đơn_vị từ mục 16.
SELECT DATE_SUB('2023-08-15', INTERVAL 1 MONTH);
-- Kết quả: 2023-07-15
SELECT SUBDATE('2023-01-01 00:00:00', INTERVAL 1 SECOND);
-- Kết quả: 2022-12-31 23:59:59
18. TO_DAYS(ngay)
Trả về tổng số ngày kể từ năm 0 (theo lịch Gregorian) đến ngày đã cho. Hàm này không dành cho các ngày trước năm 1582.
SELECT TO_DAYS('2023-08-15');
-- Kết quả: 739130
SELECT TO_DAYS('20230815');
-- Kết quả: 739130
19. FROM_DAYS(so_ngay)
Chuyển đổi một số nguyên (tổng số ngày kể từ năm 0) thành giá trị DATE.
SELECT FROM_DAYS(739130);
-- Kết quả: 2023-08-15
SELECT FROM_DAYS(366);
-- Kết quả: 0001-01-01
20. DATE_FORMAT(ngay, định_dạng)
Định dạng giá trị ngày hoặc datetime theo chuỗi định dạng đã cho.
SELECT DATE_FORMAT('2023-08-15 14:30:00', '%W, %D %M %Y');
-- Kết quả: 'Tuesday, 15th August 2023'
SELECT DATE_FORMAT('2023-08-15 14:30:00', '%Y/%m/%d %H:%i:%s');
-- Kết quả: '2023/08/15 14:30:00'
SELECT DATE_FORMAT(NOW(), '%H:%i:%s %p');
-- Ví dụ: '14:30:05 PM'
Các ký tự định dạng (format specifiers) phổ biến:
%Y: Năm (4 chữ số)%y: Năm (2 chữ số)%m: Tháng (01-12)%c: Tháng (1-12)%M: Tên tháng đầy đủ (January...December)%b: Tên tháng viết tắt (Jan...Dec)%d: Ngày trong tháng (00-31)%e: Ngày trong tháng (0-31)%D: Ngày với hậu tố tiếng Anh (1st, 2nd, 3rd, ...)%W: Tên ngày trong tuần đầy đủ (Sunday...Saturday)%a: Tên ngày trong tuần viết tắt (Sun...Sat)%w: Chỉ số ngày trong tuần (0=Chủ Nhật, 6=Thứ Bảy)%j: Ngày trong năm (001-366)%H: Giờ (00-23)%k: Giờ (0-23)%h: Giờ (01-12)%I: Giờ (01-12)%l: Giờ (1-12)%i: Phút (00-59)%S,%s: Giây (00-59)%p: AM hoặc PM%r: Thời gian 12 giờ (hh:mm:ss AM/PM)%T: Thời gian 24 giờ (hh:mm:ss)%U: Tuần trong năm (0-52), Chủ Nhật là ngày đầu tuần%u: Tuần trong năm (0-52), Thứ Hai là ngày đầu tuần%%: Ký tự '%'
21. TIME_FORMAT(thoi_gian, định_dạng)
Tương tự như DATE_FORMAT(), nhưng chỉ xử lý các phần giờ, phút và giây. Các ký tự định dạng liên quan đến ngày sẽ trả về NULL hoặc 0.
SELECT TIME_FORMAT('14:30:05', '%H giờ %i phút %s giây');
-- Kết quả: '14 giờ 30 phút 05 giây'
SELECT TIME_FORMAT('14:30:05', '%r');
-- Kết quả: '02:30:05 PM'
22. CURDATE() và CURRENT_DATE()
Trả về ngày hiện tại dưới định dạng 'YYYY-MM-DD'.
SELECT CURDATE();
-- Ví dụ: '2023-08-15'
SELECT CURRENT_DATE();
-- Ví dụ: '2023-08-15'
23. CURTIME() và CURRENT_TIME()
Trả về thời gian hiện tại dưới định dạng 'HH:MM:SS'.
SELECT CURTIME();
-- Ví dụ: '14:30:05'
SELECT CURRENT_TIME();
-- Ví dụ: '14:30:05'
24. NOW(), SYSDATE(), CURRENT_TIMESTAMP(), LOCALTIME()
Tất cả các hàm này đều trả về ngày và giờ hiện tại của hệ thống dưới định dạng 'YYYY-MM-DD HH:MM:SS'.
SELECT NOW();
-- Ví dụ: '2023-08-15 14:30:05'
SELECT SYSDATE();
-- Ví dụ: '2023-08-15 14:30:05'
SELECT CURRENT_TIMESTAMP();
-- Ví dụ: '2023-08-15 14:30:05'
Lưu ý: NOW() trả về thời gian khi giao dịch bắt đầu, trong khi SYSDATE() trả về thời gian thực khi hàm được thực thi. Có thể có sự khác biệt nhỏ trong một số trường hợp.
25. UNIX_TIMESTAMP(ngay_gio)
Chuyển đổi một giá trị ngày hoặc datetime thành dấu thời gian Unix (số giây kể từ '1970-01-01 00:00:00' UTC).
Nếu không có đối số, nó trả về dấu thời gian Unix hiện tại.
SELECT UNIX_TIMESTAMP();
-- Ví dụ: 1692113405 (dấu thời gian hiện tại)
SELECT UNIX_TIMESTAMP('2023-08-15 14:30:00');
-- Kết quả: 1692100200
SELECT UNIX_TIMESTAMP('2023-01-01');
-- Kết quả: 1672534800
26. FROM_UNIXTIME(dấu_thời_gian_unix, định_dạng)
Chuyển đổi một dấu thời gian Unix (số nguyên) thành giá trị DATETIME hoặc chuỗi có định dạng.
Nếu tham số định_dạng được cung cấp, kết quả sẽ được định dạng theo đó (xem các ký tự định dạng trong mục 20).
SELECT FROM_UNIXTIME(1692100200);
-- Kết quả: '2023-08-15 14:30:00'
SELECT FROM_UNIXTIME(1692100200, '%Y-%m-%d %H:%i:%s');
-- Kết quả: '2023-08-15 14:30:00'
SELECT FROM_UNIXTIME(1692100200, '%D %M %Y');
-- Kết quả: '15th August 2023'
27. SEC_TO_TIME(tong_giay)
Chuyển đổi tổng số giây thành một giá trị TIME (HH:MM:SS).
SELECT SEC_TO_TIME(3600);
-- Kết quả: '01:00:00'
SELECT SEC_TO_TIME(90060);
-- Kết quả: '25:01:00'
28. TIME_TO_SEC(thoi_gian)
Chuyển đổi một giá trị TIME hoặc DATETIME thành tổng số giây.
SELECT TIME_TO_SEC('01:00:00');
-- Kết quả: 3600
SELECT TIME_TO_SEC('25:01:00');
-- Kết quả: 90060
SELECT TIME_TO_SEC('2023-08-15 01:00:00');
-- Kết quả: 3600
29. ADDTIME(bieu_thuc1, bieu_thuc2)
Cộng hai giá trị thời gian (hoặc datetime và thời gian). bieu_thuc1 là giá trị ban đầu, bieu_thuc2 là giá trị để cộng thêm.
SELECT ADDTIME('10:00:00', '02:30:15');
-- Kết quả: '12:30:15'
SELECT ADDTIME('2023-08-15 10:00:00', '05:00:00');
-- Kết quả: '2023-08-15 15:00:00'
30. CONVERT_TZ(dt, from_tz, to_tz)
Chuyển đổi một giá trị datetime dt từ múi giờ from_tz sang múi giờ to_tz.
Để hàm này hoạt động, các bảng múi giờ của MySQL cần được nạp dữ liệu. Các múi giờ có thể là chuỗi như '+00:00' hoặc tên múi giờ như 'Asia/Ho_Chi_Minh'.
SELECT CONVERT_TZ('2023-08-15 10:00:00', '+00:00', '+07:00');
-- Chuyển từ UTC sang múi giờ +7
-- Kết quả: '2023-08-15 17:00:00'
31. STR_TO_DATE(chuoi, định_dạng)
Chuyển đổi một chuỗi chuoi thành giá trị DATE hoặc DATETIME dựa trên chuỗi định dạng đã cho. Đây là hàm ngược của DATE_FORMAT().
SELECT STR_TO_DATE('15-08-2023', '%d-%m-%Y');
-- Kết quả: '2023-08-15'
SELECT STR_TO_DATE('Aug 15 2023 2:30 PM', '%b %d %Y %h:%i %p');
-- Kết quả: '2023-08-15 14:30:00'
32. LAST_DAY(ngay)
Trả về ngày cuối cùng của tháng chứa ngày đã cho.
SELECT LAST_DAY('2023-08-15');
-- Kết quả: '2023-08-31'
SELECT LAST_DAY('2023-02-01');
-- Kết quả: '2023-02-28'
SELECT LAST_DAY('2024-02-10');
-- Kết quả: '2024-02-29' (2024 là năm nhuận)
33. MAKEDATE(nam, so_ngay_trong_nam)
Tạo một giá trị DATE từ năm và số thứ tự ngày trong năm.
SELECT MAKEDATE(2023, 1);
-- Kết quả: '2023-01-01'
SELECT MAKEDATE(2023, 32);
-- Kết quả: '2023-02-01'
SELECT MAKEDATE(2024, 60);
-- Kết quả: '2024-02-29' (Ngày thứ 60 của năm nhuận 2024)
34. MAKETIME(gio, phut, giay)
Tạo một giá trị TIME từ giờ, phút và giây đã cho.
SELECT MAKETIME(10, 20, 30);
-- Kết quả: '10:20:30'
SELECT MAKETIME(23, 59, 59);
-- Kết quả: '23:59:59'
35. YEARWEEK(ngay, chế_độ)
Trả về năm và tuần trong năm dưới dạng số nguyên YYYYWW. Tham số chế_độ (mode) tương tự như trong hàm WEEK().
SELECT YEARWEEK('2023-01-01', 0);
-- Kết quả: 202300 (mode mặc định 0, Chủ Nhật là ngày đầu tuần, tuần đầu chứa ngày 1 tháng 1)
SELECT YEARWEEK('2023-01-01', 1);
-- Kết quả: 202252 (mode 1, Thứ Hai là ngày đầu tuần. Ngày 1 tháng 1 năm 2023 là Chủ Nhật, nên nó thuộc tuần cuối của năm 2022)
SELECT YEARWEEK('2023-01-02', 1);
-- Kết quả: 202301 (mode 1, ngày 2 tháng 1 năm 2023 là Thứ Hai, là ngày đầu tiên của tuần 1)
36. WEEKOFYEAR(ngay)
Trả về số tuần trong năm của ngày đã cho, với tuần đầu tiên chứa ngày 1 tháng 1. Hàm này tương đương với WEEK(ngay, 3), nghĩa là Thứ Hai là ngày đầu tuần và tuần 1 là tuần đầu tiên có hơn 3 ngày của năm mới.
SELECT WEEKOFYEAR('2023-01-01');
-- Kết quả: 1
SELECT WEEKOFYEAR('2023-01-07');
-- Kết quả: 1
SELECT WEEKOFYEAR('2023-01-09');
-- Kết quả: 2