09/10/2018, 17:37

Ngày tháng trong ASP + Access

Có một vấn đề muốn trao đổi với các bạn:
Mình muốn dùng ngày tháng dạng dd/mm/yyyy trong Web
1. Giải pháp 1:
Dbase: field ngày tháng là xday được format là: dd/mm/yyyy
- Nếu ngày tháng nhập vào từ form ASP: 19/10/2002 --> đúng
- Nếu ngày tháng nhập vào từ form ASP: 11/10/2002 --> sai (hiểu là ngày 10 tháng 11...)
Cau query là: INSERT INTO xx(xday) VALUES(#11/10/2002#);
2. Giải pháp 2:
DBase: field xday: mm/dd/yyyy --> với query trên vẫn sai....

Trong ASP có hàm formatdate thì phải...

Nhưng nếu không xài hàm đó thì làm sao cho đúng???
White_Rose viết 19:46 ngày 09/10/2018
lúc in ra bạn sử dụng cách hàm Day, Month, Year để in
lúc nhập thì chỉ có cách tách ngày tháng user gửi lên thành 3 phần, rồi hợp lại theo thứ tự mm/dd/yyyy thôi vì cái formatdate có cho dd/mm/yyyy đâu.
newcinc viết 19:49 ngày 09/10/2018
Có vẻ như bạn chưa làm chuyện này bao giờ....
Thế này nhé:
tớ có một form:
--------
<form action="" method=post>
<input type=text name=d>
<input type=submit>
</form>
-----
Khi tớ muốn nhập ngày 11 tháng 10 năm 2002, tớ sẽ nhập: 11/10/2002 vào và nhấn Submit.
Ở file ASP xử lý:
----
d=Request.Form("d")
dd=Day(d)
md=Month(d)
yd=Year(d)
--------
Bạn biết tớ được cái gì không?
dd=10
md=11
yd=2002

---> Thế là sai mất tiêu rồi...

Vấn đề ở chỗ: xử lý trong code cũng sai, ép trong database cũng sai.... chỉ có cách config trong Control Panel của Web Server thôi. Mà cách này thì đâu có hiệu quả vì mình đâu có làm được????

Thế nên tớ mới tìm người để hỏi các giải quyết đó mà...
White_Rose viết 19:40 ngày 09/10/2018
thì mình cũng nói cách làm rồi đấy thôi. Ví dụ nhé.
d = Request.Form("day")
arr = Split(d,"/")
day = arr(0)
month = arr(1)
year = arr(2)
Erase arr
-----> để xử lý như ngày tháng
CDate(month & "/" & day & "/" & year)
hay đơn giản chỉ là chèn vào CSDL thì chỉ cần
month & "/" & day & "/" & year
DTB viết 19:40 ngày 09/10/2018
Tôi không nghĩ là NewCinC không biết cách xử lý. Phải không NewCinC?
Dẫu sao tôi cũng biết NewCinC từ thời ở diễn đàn của Net-center.

Có lẽ NewCinC muốn bàn về nguyên nhân chứ không phải về cách tính tóan.

Nhân tiện cũng xin nói lại vấn đề đã cũ: thể hiện dữ liệu font Unicode lấy từ cơ sở dữ liệu ra.

Khi có người không thể hiện được font chữ Unicode trên trang web thì người khác chỉ cho cách áp dụng đồng thời 3 biện pháp:
- đặt Codepage=65001 trên trang ASP.
- đặt Charset=UTF-8 trên trang web (có hoặc không chứa Form).
- chỉ cập nhật database thông qua web.

Thế nhưng lại không giải thích rõ tại sao lại thế, không giải thích tác dụng của từng cái. Cuối cùng nhiều người vẫn làm được nhưng không biết tại sao lại phải thế.

Việc hiểu rõ server và cilent hoạt động như thế nào, liên lạc giữa chúng ra sao... lẽ ra phải là điều cần biết trước tiên.

Khi dữ liệu là font unicode được chuyển đến cho cilent thì khi đó trang web cần đặt charset=utf-8 thì browser mới hiển thị đúng font chữ được. Nếu không sẽ thấy những dấu "?" hoặc hình vuông. Nhưng lúc đó trong bộ nhớ của máy vẫn là dữ liệu font Unicode. Người xem vẫn có thể đặt lại charset được bằng cách chọn trên menu View/Encoding.
Như vậy quyết định là do bản thân database trên máy server có phải là chứa dữ liệu bằng font Unicode hay không.

Khi 1 trang web có 1 cái form để ta cập nhật dữ liệu thì trang đó phải đặt Charset=utf-8 thì lúc gõ vào ta mới đọc được chữ. Nếu không ta không đọc được chữ. Tuy nhiên nó vẫn là mã của font Unicode vì do bộ gõ đã xử lý các ký tự ta gõ vào và chuyển đổi chúng thành unicode rồi. (hê! không đọc được thì làm sao gõ được nhỉ? Tôi muốn nói là việc copy từ trang khác rồi paste vào vùng textaray đó ).

Tương ứng với Charset ở máy cilent là Codepage trong trang ASP trên máy server.

Bởi vì dữ liệu chuyển từ cilent lên server sẽ nằm ở dạng chuỗi ký tự (tất nhiên là số hóa bằng chuỗi các con số nhị phân). Và vì ta đặt các thông tin đó vào các biến cho nên khi INSERT vào database thì nó cứ bê nguyên xi mà ịn vào.
Ngoài ra ta thấy dữ liệu truyền lên server không hề được khai báo kiểu Num, Date hay Logic gì ráo.
Chính vì vậy khi máy nhận được chuỗi "11/10/2002" mà ta lại bảo đó là kiểu ngày tháng thì đương nhiên là nó hiểu ngày 10 tháng 11 năm 2002. Bởi vì ASP là người Mỹ mà. :-) để nó hiểu đúng ta cần đặt cho trang ASP này là Việt, Pháp hay Nga gì đó. Vì các nước này hiểu ngày tháng theo dạng dd/mm/yyyy. điều này tương tự như Charset ở máy cilent.

Thay vì dùng session.codepage ở đầu trang ASP, ta có thể dùng session.LCID để có thể thay đổi ở giữa trang khi cần.
Ví dụ:
<%
' Set LCID for US-English
session.LCID = 1033
Response.Wirte ("Now is: " & now() & "<BR>" )
' Set LCID for Russian
session.LCID = 1049
Response.Wirte ("Now is: " & now() & "<BR>" )
%>

Kết quả:
Now is: 10/26/2002 4:11:12 PM
Now is: 26.10.2002 16:11:12

ghi chú: LCID Vietnam: 1066 ; Pháp: 1036 ; Malaysia: 1086 ; Nhật: 1041 ...
newcinc viết 19:49 ngày 09/10/2018
Bài viết được gửi bởi White_Rose
thì mình cũng nói cách làm rồi đấy thôi. Ví dụ nhé.
d = Request.Form("day")
arr = Split(d,"/")
day = arr(0)
month = arr(1)
year = arr(2)
Erase arr
-----> để xử lý như ngày tháng
CDate(month & "/" & day & "/" & year)
hay đơn giản chỉ là chèn vào CSDL thì chỉ cần
month & "/" & day & "/" & year
Vấn đề như thế này:
Web Server default ngày tháng dạng mm/dd/yyyy
---> khi user nhập từ form: ngày 11 tháng 10/2002 (11/10/2002) sẽ được hiểu là ngày 10 tháng 11 năm 2002 --> sai
do đó, up lên database vẫn sai

Mình bàn cách xử lý, giải quyết vấn đề, nguyên nhân do ai? (Web Server, Client? Database???)
Nếu dùng hàm CDate nhu cua ban, mình nhập 11/10/2002 sẽ trả kết quà là: 10/11/2002 thôi

Dường như bạn chưa hiểu ý của mình lắm: Nếu để ý kỹ, bạn sẽ thấy các ngày tháng viết theo 2 kiểu (dd/mm/yyyy, mm/dd/yyyy) đều được (ie: 11/10/2002, 1/2/2002, 5-9-2002), đều bị lỗi này.
Còn các ngày khác (23/5/2002, 31/1/2002) thì dĩ nhiên không bị

Mình đã giải quyết vấn đề này rồi, nhưng khà phức tạp:
Đối với các ngày kiểu 1: mình chuyển ngược lại
Đối với ngày kiểu 2: để bình thường
--> OKey

Nhưng có thể có bạn sẽ có cách làm cực ngắn...

---------
Bàn thêm với Dương Thái Bình:
Bạn nói ASP Counter mình viết không chạy là sao? bạn qua bài kia đọc lại thử nhé... mình hơi bất bình
newcinc viết 19:48 ngày 09/10/2018
Trở lại vấn đề tiếng việt (Unicode)
Tớ hay dùng Window-1252
Khi Insert từ web--> dbase: insert thành mã Unicode nên viết ra thì ra đúng tiếng việt
--
Giả sử trong Access bạn gõ Unicode trực tiếp: trong Access bạn sẽ thấy được tiếng Việt --> khi show ra Web sẽ sai.
--> cách giải quyết: trước khi Response.Write X, với X lấy từ dbase ra thì viết thành: Response.Write Server.HTMLEncode(X)
thế là xong
White_Rose viết 19:46 ngày 09/10/2018
Mình nghĩ Access sử dụng dạng UTF8 để lưu các kí tự khi mình gõ trực tiếp ở trong đó, vì vậy nếu muốn đồng bộ bảng mã (gõ trực tiếp vào Access hay là insert tù trang Web thì việc xử lý các string của script cũng nên theo dạng UTF8 bằng cách thiết lập lại codepage (không phải session.codepage).
Như vậy kích thước trang web cũng nhỏ hơn là sử dụng dạng windows-1252 vì mỗi kí tự chỉ chiếm độ 2 byte thôi.

quả thực mình chưa hiểu rõ ý bạn nói. Bạn có thể giải thích kĩ hơn không? Ý bạn có phải là:
- Nếu mình insert một ngày kiểu như 10/11/2002 thì database sẽ lưu giữ nó như là ngày 11 tháng 10 năm 2002. Nếu mình insert một ngày kiểu như 23/10/2002 thì database tự động chuyển nó thành ngày 23 tháng 10 năm 2002. Nó cũng tương tự như phản ứng của Access khi mình nhập trực tiếp ngày tháng vào.

Và bạn muốn rằng ứng dụng tự biết nếu người sử dụng nhập vào 10/11/2002 thì là họ muốn nhập ngày 11 tháng 10 năm 2002 còn nếu họ nhập 23/10/2002 thì là họ muốn nhập ngày 23 tháng 10 năm 2002???

Nếu đúng như vậy thì trước khi chuyển đổi thì kiểm tra xem đó có phải là một ngày đúng không (IsDate). Nếu không đúng thì giả sự họ đã nhập theo dạng dd/mm/yyyy và mình đổi lại thành mm/dd/yyyy để insert vào CSDL.
newcinc viết 19:53 ngày 09/10/2018
Và bạn muốn rằng ứng dụng tự biết nếu người sử dụng nhập vào 10/11/2002 thì là họ muốn nhập ngày 11 tháng 10 năm 2002 còn nếu họ nhập 23/10/2002 thì là họ muốn nhập ngày 23 tháng 10 năm 2002???
-->chỗ này đây: người dùng nhập 10/11/2002 có nghĩa là họ nhập ngày 10 tháng 11 năm 2002. Nhưng ứng dụng luôn đưa vào database là ngày 11 tháng 10 năm 2002....
--> sai ý đồ người dùng rồi
White_Rose viết 19:38 ngày 09/10/2018
Vậy cái này ổn chứ
Function CDateVN(userdate)
Dim arr
arr = Split(userdate,"/") 'bài cũ mình viết nhầm là arr=Split(userdate)
CDateVN=CDate(arr(1)&"/"&arr(0)&"/"arr(2))
Erase arr
End Function
Bài liên quan
0