Chào các bạn,
Dạo qua một số chủ đề mình thấy các bạn bàn luận sôi nổi quá, rất nhiều chủ đề thật hay và cũng rất thú vị.
Những ngày qua, chắc cũng có rất nhiều người giống mình, tất cả đều rất buồn.
Quay lại chủ đề về vấn đề ngày tháng trong CSDL, tôi xin mạn phép bàn mấy điều như sau:
- Cơ cấu lưu trữ dữ liệu kiểu ngày tháng.
- Nguyên tắc xử lý dữ liệu kiểu ngày tháng trước khi đưa và CSDL của Access.
- Một số thủ thuật xử lý.
Trong máy tính nguyên tắc lưu trữ dữ liệu kiểu thời gian (Datetime) dựa trên nhu cầu xử lý dữ liệu tối thiểu của người dùng (tức là xem xét mức quản lý thời gian đến của anh ta). Đơn vị tối thiểu để thông dụng nhất là giây và đơn vị tối đa thông dụng nhất là năm, vì thế người ta dùng cách thức mà tôi hình tượng hoá theo dạng sau đây để lưu trữ kiểu dữ liệu ngày tháng. Mm/dd/yyyy HH:MM:SS
Trong đó mm là tháng (từ 1 đến 2 chữ số), dd là ngày (từ 1 đến 2 chữ số) và yyyy là năm có 4 chữ số. HH là giờ, mm là phút và ss là giây.
Bất kể bạn định dạng ngày giờ theo vùng quốc gia thế nào dd/mm/yyyy hay yyyy/mm/dd … thì máy tính luôn chọn chuẩn nói trên để lưu trữ ngày tháng.
Vậy vấn đề nảy sinh là tập quán người dùng trong lưu trữ ngày tháng cũng có thể gây ra một số điều không như ý khi lưu trữ đơn vị dữ liệu kiểu thời gian. Nếu bạn dùng định dạng thời gian hệ thống là dd/mm/yyyy (kiểu Locale Setting của các nước theo chuẩn của Pháp) thì sẽ có nhiều vấn đề khi chuyển đổi dữ liệu nhập vào sang kiểu ngày tháng.
Do đặc tính VB có khả năng tự chuyển đổi định dạng dữ liệu khi có một số đặc tả nhất định để tiến hành các phép toán nên chúng ta cần đặc biệt lưu ý.
Xét ví dụ #15/10/2005#, trong bất kỳ tình huống sử dụng nào, thì VB sẽ luôn cho ta kết quả là tháng 10, ngày 15.
Nhưng xét ví dụ #1/10/2005# thì VB sẽ luôn hiểu đây là ngày 10 tháng 1.
Vậy tức là khi tiến hành chuyển đổi, VB xét chuỗi số đầu tiên nếu thoả mãn nhỏ hơn hoặc bằng 12 thì nó sẽ tự gán đó là tháng còn nếu lớn hơn thì nó sẽ coi đó là ngày và xét tiếp chuối tiếp theo nếu nó thoả mãn là ngày hay tháng để xây dựng kiểu dữ liệu thời gian, còn nếu các điều kiện đó không thoả mãn thì thông báo lỗi.
Debug.Print Format("10/1/2005", "mmm-dd-yyyy")
Debug.Print Format("1/10/2005", "mmm-dd-yyyy")
Kết quả buồn cười chưa
Oct-01-2005
Jan-10-2005
Nếu định dạng hệ thống bạn để là mm/dd/yyyy
còn để định dạng hệ thống là dd/mm/yyyy thì kết quả đúng là cái ta cần
Chúng ta có thể thấy rõ, vậy nếu chúng ta sử dụng cấu hình thời gian hệ thống là mm/dd/yyyy rồi yêu cầu người dùng nhập vào chuỗi như vậy thì sẽ không có vấn đề gì cả. Tuy nhiên, điều naỳ sẽ gây trở ngại cho người dùng Việt nam. Vì vậy tôi xin tạm giới thiệu một cách khá củ chuối để làm sao sử dụng dữ liệu thời gian một cách nhuần nhuyễn - tất nhiên ở cấp độ cò con của chúng ta thôi. Các nhà sản xuất phần mềm họ sẽ làm khác nhiều - hiện đại và ngon hơn nhiều.
Yêu cầu của đầu vào là: Nhập dữ liệu dạng dd/mm/yyyy qua textbox
Yêu cầu đầu ra là: cung cấp dữ liệu đúng để xử lý – ví dụ trong query chẳng hạn.
Để làm được điều này bạn cần 2 công đoạn
- tách ra các chuỗi ngày tháng và năm riêng
- Chuyển đổi các chuỗi đã xắp xếp hợp lý sang kiểu ngày tháng.
Các bạn nên thiết kế phần tách chuỗi thành dạng hàm để thực hiện cho tiện. Xét thủ tục ví dụ dưới đây của tôi nhé
Function GetDateString(RawString As String, Optional DateSeparator As String = "/") As Date ' Gia dinh kieu dau vao cua du lieu luon la dd/mm/yyyy ' o day toi dung DateSeparator de co the thay / thanh - hoac bat ky kieu phan cach nao khac Dim StrDate As String Dim StrMonth As String Dim StrYear As String Dim i As Integer, x As Integer ' tach doan chuoi dau tien chua ngay x = InStr(RawString, DateSeparator) StrDate = Mid(RawString, 1, x - 1) ' rut ngan doan chuoi dang xu ly RawString = Mid(RawString, x + 1) x = InStr(RawString, DateSeparator) StrMonth = Mid(RawString, 1, x - 1) ' tach doan chuoi chua ngay StrYear = Mid(RawString, x + 1) ' dua ra chuoi chuan va chuyen sang kieu du lieu ngay thang GetDateString = CDate(StrMonth & DateSeparator & StrDate & DateSeparator & StrYear) End Function
Khi gọi hàm chúng ta chỉ cần gọi như sau:
GetDateString([chuỗi đưa vào],|Kiểu phân cách|)
Các bạn có thể dùng cách này, tôi tin là sẽ có thể giải quyết được vài việc với kiểu dữ liệu thời gian…
Vậy tóm lại ta có thể yêu cầu người dùng nhập vào định dạng dữ liệu chuẩn và rồi sử dụng cách trên thì - chúng ta có thể bước qua được khó khăn này bất kể định dạng hệ thống về thời gian là gì. Cách tương tự cũng có thể áp dụng với kiểu định dạng số (chấm . và phẩy , - hihi) Củ chuối nhỉ...
Thế đã nhé - giờ tớ đi làm - nếu ai cần trao đổi thêm cứ YIM tớ paulsteigel