Trong hầu hết các dự án lập trình, việc phải thao tác với Date/time diễn ra như cơm bữa. Ví dụ, bạn phải đọc và định dạng ngày tháng nhận được từ server trước khi hiển thị ra giao diện, hoặc trong các trang tìm kiếm với các điều kiện lọc theo thời gian… Nhiều lắm!
Trong Javascript, bạn có rất nhiều cách để lấy ngày tháng năm, cũng như xử lý chúng. Ví dụ như sử dụng đối tượng Date có sẵn, hoặc sử dụng các thư viện chuyên về xử lý date/time như momentJS, date-fns…
Cá nhân mình thấy làm việc với date/time chưa bao giờ là dễ cả. Nào là múi giờ, năm nhuận, định dạng ngày tháng theo các chuẩn khác nhau… và còn nhiều điều kì dị nữa.
Bài viết hôm nay, mình sẽ chia sẻ một số kinh nghiệm xương máu khi làm việc với Date/Time trong JavaScript.
Nội dung chính của bài viết
JavaScript Date là gì
Trong Javascript, Date là một object chuyên phụ trách xử lý thời gian. Bản chất đối tượng Date chỉ có một giá trị là số milliseconds trước hoặc sau ngày 01 tháng 01 năm 1970 theo giờ UTC.
Nói tới thời gian thì mọi người cần phải biết tới mấy cái khái niệm về múi giờ như UTC, GMT. Hiểu nôm na thì nó là quy ước để đồng bộ các múi giờ trên toàn cầu với nhau.
Khi xử lý các tác vụ liên quan tới ngày tháng, chúng ta quy về xử lý số nguyên milliseconds, ví dụ: 819131040000
Tuy nhiên, việc xử lý các số như vậy khá là bất tiện, và khó hình dung với lập trình viên. Do đó, Javascript đã tích hợp sẵn các công cụ hỗ trợ tạo và truy vấn ngày tháng.
Mình sẽ hướng dẫn ngay phía dưới đây thôi.
Khởi tạo đối tượng Date
Rất đơn giản, để khởi tạo đối tượng Date, chúng ta dùng từ khóa new:
var today = new Date();
Mặc định không truyền tham số gì cả, đối tượng date sẽ đặt giá trị của ngày hôm nay.
Bạn có thể xem giá trị của nó bằng các hàm có sẵn trong đối tượng Date, ví dụ: toDateString()
var today = new Date(); console.log(today.toDateString()); // In ra màn hình: "Fri Feb 24 2023" console.log(today.toTimeString()); // In ra màn hình: "10:30:49 GMT+0700 (Indochina Time)"
Mặc định các hàm toDateString
and toTimeString
không có định dạng ngày tháng. Do đó, các trình duyệt khác nhau có thể trả về các định dạng khác nhau. Ngoài ra, nó còn phụ thuộc vào cả thiết lập của máy tính nữa.
Khởi tạo Date với giá trị cụ thể
Phần trên là mình khởi tạo đối tượng Date không tham số, mặc định nó sẽ gán giá trị là ngày giờ hiện tại.
Nếu bạn muốn gán một ngày giờ cụ thể nào đó thì cú pháp truyền vào như sau:
new Date(year, month, date, hours, minutes, seconds, ms)
Trong đó: Hai tham số đầu là bắt buộc
year
phải có 4 chữ số- Số
month
bắt đầu bằng 0 (tháng 1), tối đa 11 (tháng 12). - Các tham số
date
: Ngày trong tháng. Nếu không nhập thì mặc định là 1 - Nếu
hours/minutes/seconds/ms
nếu không nhập thì mặc định là 0
Ví dụ:
var date = new Date(2023, 02, 25, 10, 20, 00); console.log(date.toDateString()) // In ra màn hình: "Sat Mar 25 2023" console.log(date.toTimeString()) // In ra màn hình: "10:20:00 GMT+0700 (Indochina Time)"
Ngoài ra, bạn có thể truyền vào một chuỗi ngày tháng, đối tượng Date cũng hỗ trợ parse tự động giúp bạn.
Ví dụ:
var date = new Date("2023-01-26"); console.log(date.toDateString()) // In ra màn hình: "Thu Jan 26 2023"
Vấn đề timezone trong Date
Bạn có để ý trong đoạn code trên, dòng in ra có thể hiện múi giờ trong đó không? “GMT+0700”.
Đấy là múi giờ được cài đặt trong máy tính của mình. Nếu vẫn đoạn code đó mà chạy ở một máy tính khác (ở cùng thời điểm lúc này), có thể giá trị hiển thị ra cũng sẽ khác. Ví dụ: “08:30:49 GMT+0500 (Indochina Time)”
Điều đó chứng tỏ, các hàm toDateString
và toTimeString
tự động convert ngày giờ sang múi giờ được thiết lập trong máy tính.
Đây thực sự là vấn đề nếu bạn không xử lý đúng. Vì các ứng dụng web của bạn được chạy trên trình duyệt của khách hàng. Mà khách hàng thì có thể ở bất kỳ đâu trên thế giới, ở bất kỳ múi giờ nào.
Do đó, để cho cẩn thận và chắc chắn. Thông thường, nếu cần lấy giá trị thời gian, bạn nên chỉ định cụ thể timezone cho nó.
Ví dụ:
var today = new Date().toLocaleString("en-US", {timeZone: "Asia/Jakarta"}) console.log(today); // In ra màn hình: "2/24/2023, 11:08:57 AM"
Các hàm lấy giá trị của Date
Đối tượng Date cung cấp đầy đủ công cụ để bạn có thể lấy giá trị theo yêu cầu.
Ngày tháng
getFullYear()
– lấy ra năm (có 4 chữ số).getMonth()
– Trả về tháng, bắt đầu từ 0 là tháng 1, tới 11 là tháng 12.getDate()
– Trả về ngày trong thánggetDay()
– Ngày trong tuần, 0 là Thứ hai, 1 là thứ ba…
Thời gian
getHours()
– Trả về giờgetMinutes()
– Trả về phútgetSeconds()
– Trả về giâygetMilliseconds()
– mili giây.
Ví dụ:
var date = new Date(2023, 1, 23, 6, 8, 5); // Nhớ rằng: đối tượng Date thiết lập ngày tháng với timezone UTC của trình duyệt đang chạy. console.log(date.getFullYear()); // 2023 console.log(date.getMonth()); // 1, là Tháng hai console.log(date.getSeconds()); // 5
Định dạng ngày tháng trong Javascript
Khi bạn làm dự án backend (NodeJS), hoặc ứng dụng web cần phải giao tiếp dữ liệu với server qua API, bạn sẽ phải thực hiện định dạng lại ngày tháng rất nhiều.
Thông thường, để tiện cho việc tính và xử lý dữ liệu liên quan tới ngày tháng, người ta sẽ chuyển ngày tháng thành milliseconds. Do đó, bạn cần phải định dạng lại trước khi hiển thị ra giao diện cho người dùng.
Ở phần này, mình hay sử dụng thư viện ngoài như momentJS để hỗ trợ định dạng đơn giản hơn.
Ví dụ:
const currentTime = moment().format('DD/MM/YYYY hh:mm a'); console.log(currentTime); //in ra: 24/02/2023 01:19 pm
Bạn có thể tham khảo các quy tắc format của thư viện tại đây: MomentJS format
Nếu bạn không thích sử dụng thư viện, có thể viết chay bằng JS cũng được. Dưới đây là một ví dụ tham khảo:
function formatDate(date) { var hours = date.getHours(); var minutes = date.getMinutes(); var ampm = hours >= 12 ? 'pm' : 'am'; hours = hours % 12; hours = hours ? hours : 12; // the hour '0' should be '12' minutes = minutes < 10 ? '0'+minutes : minutes; var strTime = hours + ':' + minutes + ' ' + ampm; return (date.getDate() + "/" + (date.getMonth()+1) + "/"+ date.getFullYear() + " " + strTime); } // gọi hàm var currentTime = formatDate(new Date()); console.log(currentTime) // in ra: 24/2/2023 1:23 pm
Sử dụng định dạng ngày tháng chuẩn ISO 8601
Khi làm việc với thời gian và ngày trong JavaScript, rất quan trọng để sử dụng định dạng ngày tháng chuẩn ISO 8601.
Định dạng này sẽ giúp đảm bảo tính độc lập với múi giờ và giúp cho các đối tượng Date có thể được chuyển đổi và so sánh một cách chính xác.
// Định dạng ngày tháng theo chuẩn ISO 8601 const isoDate = new Date().toISOString();
Kết luận
Trong bài viết này, chúng ta đã tìm hiểu về cách sử dụng date/time trong JavaScript.
Ngoài ra, khi làm việc với thời gian và ngày, chúng ta nên sử dụng định dạng chuẩn ISO 8601 để đảm bảo tính độc lập với múi giờ và giúp cho các đối tượng Date có thể được chuyển đổi và so sánh một cách chính xác.
Trước khi kết thúc bài viết, mình tổng kết lại một số điểm cần lưu ý về Date/Time trong Javascript:
- Tính chính xác của đối tượng Date trong JavaScript phụ thuộc vào độ chính xác của hệ thống đồng hồ của máy tính.
- Việc sử dụng các thư viện như Moment.js có thể ảnh hưởng đến tốc độ tải trang và hiệu suất của ứng dụng. Vì vậy, bạn nên cân nhắc việc sử dụng các thư viện này trong trường hợp cần thiết.
- Các đối tượng Date trong JavaScript là không thể thay đổi (immutable). Do đó, khi bạn thay đổi giá trị của một đối tượng Date, bạn cần tạo ra một đối tượng Date mới.
Trên đây là một số điểm cần lưu ý khi làm việc với date/time trong JavaScript. Hy vọng bài viết này đã giúp bạn hiểu rõ hơn về chủ đề này và có thể áp dụng vào công việc của mình một cách hiệu quả.
Bình luận. Cùng nhau thảo luận nhé!