[Chia sẻ] Hàm lấy thời gian từ Internet.

Liên hệ QC

Hoàng Trọng Nghĩa

Chuyên gia GPE
Thành viên BQT
Moderator
Tham gia
17/8/08
Bài viết
8,570
Được thích
16,627
Giới tính
Nam
Cái hàm này tôi cũng sưu tầm trên Internet cũng lâu lắm rồi, giờ rảnh rổi lục các file cũ và thấy nó hay hay nên chia sẻ lên đây, ai dùng được thì dùng.
Tôi có chỉnh sửa bẩy lỗi một chút và cộng thêm 7 tiếng so với giờ GMT cho phù hợp với giờ Việt Nam. Nếu ai có hàm nào tốt hơn, nhanh hơn thì chia sẻ cho mọi người nhé.

PHP:
Function GetGMTNetTime() As Date
    Const sURL As String = "https://www.timeanddate.com"
    Dim oHTTP As Object
    Dim sResp As String
    Set oHTTP = CreateObject("Microsoft.XMLHTTP")
    On Error GoTo ErrorHandler
    oHTTP.Open "GET", sURL, False, "", ""
    oHTTP.Send
    sResp = oHTTP.getResponseHeader("Date")
    GetGMTNetTime = CDate(Mid$(sResp, 6, 20)) + TimeSerial(7, 0, 0)
    Set oHTTP = Nothing
    Exit Function
ErrorHandler:
    Set oHTTP = Nothing
    MsgBox "Internet disconnected!"
End Function
 
Cái hàm này tôi cũng sưu tầm trên Internet cũng lâu lắm rồi, giờ rảnh rổi lục các file cũ và thấy nó hay hay nên chia sẻ lên đây, ai dùng được thì dùng.

Tôi cũng có dùng hàm lấy giờ trên Internet và chia sẻ với các bạn cách mà tôi ứng dụng nó là:
- Kiểm tra thời gian hết hạn của chương trình. Môt số ứng dụng có thời gian dùng thử thì dùng phải lấy giờ chuẩn trên internet để đối chiếu với giờ hệ thống của máy tính, nếu thấy sai là phải đồng bộ lại ngay. Có nhiều người muốn kéo dài thời gian sử dụng nên chỉnh ngày giờ máy tính, nhưng một khi máy tính họ có kết nối internet thì ứng dụng sẽ chạy kiểm tra ngay.
- Góp phần ngăn ngừa việc chỉnh ngày hệ thống để nhập dữ liệu không đúng thời gian thực.
Có một cách khác để đồng bộ giờ hệ thống ngoài việc lấy giờ trên internet là lấy giờ từ máy chủ trong hệ thống. Khi ứng dụng có lưu CSDL lên máy chủ thì có thể dùng nó để kiểm tra giờ hệ thống của các máy con. Code lấy thời gian trên máy chủ cũng có nhiều trên mạng nhé. :)
 
Upvote 0
Đúng rồi, tôi cũng đang viết chương trình và ràng buộc nhân viên nhập liệu phải nhập cho đúng số liệu, nếu như sai sót chỉ chỉnh sửa hoặc xóa trong vòng 24h, quá 24h không cho chỉnh sửa, nếu muốn được chỉnh sửa phải làm báo cáo lên, sếp duyệt mới được chỉnh sửa.
 
Upvote 0
Cái hàm này tôi cũng sưu tầm trên Internet cũng lâu lắm rồi, giờ rảnh rổi lục các file cũ và thấy nó hay hay nên chia sẻ lên đây, ai dùng được thì dùng.
Tôi có chỉnh sửa bẩy lỗi một chút và cộng thêm 7 tiếng so với giờ GMT cho phù hợp với giờ Việt Nam. Nếu ai có hàm nào tốt hơn, nhanh hơn thì chia sẻ cho mọi người nhé.
Tôi chạy code có lỗi ở dòng
Mã:
GetGMTNetTime = CDate(Mid$(sResp, 6, 20)) + TimeSerial(7, 0, 0)
với sResp = "Sun, 22 Aug 2021 14:56:04 GMT"

Chạy code sau cũng sẽ có lỗi ngay
Mã:
Sub test()
Dim sResp As String, a As Date
    sResp = "Sun, 22 Aug 2021 14:56:04 GMT"
    a = CDate(Mid$(sResp, 6, 20))
    Debug.Print a
End Sub
-------------
Code tương tự nhưng lấy ngày tháng thời gian từ server http://time.windows.com
Mã:
Function GetDateTime(DateTime As Byte, TimeZone As Integer) As Date
'    DateTime:
'    1 - gio
'    2 - ngay thang
'    3 - ngay thang va gio
'    TimeZone - so nguyen (chenh lech voi gio Greenwich Mean Time)
'    TimeZone map - https://www.timeanddate.com/time/map/
'*******************************************************************
Dim Arr, XHTTP As Object
    On Error GoTo err

    Set XHTTP = CreateObject("MSXML2.XMLHTTP")
    With XHTTP
        .Open "Head", "http://time.windows.com/", False
        .Send
        Arr = Split(.getResponseHeader("Date"), " ")
    End With

    Select Case Arr(2)
        Case "Jan": Arr(2) = 1
        Case "Feb": Arr(2) = 2
        Case "Mar": Arr(2) = 3
        Case "Apr": Arr(2) = 4
        Case "May": Arr(2) = 5
        Case "Jun": Arr(2) = 6
        Case "Jul": Arr(2) = 7
        Case "Aug": Arr(2) = 8
        Case "Sep": Arr(2) = 9
        Case "Oct": Arr(2) = 10
        Case "Nov": Arr(2) = 11
        Case "Dec": Arr(2) = 12
    End Select

    Select Case DateTime
        Case 1: GetDateTime = TimeValue(Arr(4)) + 1 / 24 * TimeZone
        Case 2: GetDateTime = Format(DateSerial(Arr(3), Arr(2), Arr(1)) + TimeValue(Arr(4)) + 1 / 24 * TimeZone, "yyyy-mm-dd")
        Case 3: GetDateTime = DateSerial(Arr(3), Arr(2), Arr(1)) + TimeValue(Arr(4)) + 1 / 24 * TimeZone
    End Select

    Set XHTTP = Nothing

    On Error GoTo 0
    Exit Function
err:
    MsgBox "Loi " & err.Number & " (" & err.Description & ") trong ham GetDateTime "
End Function

Sub test()
'    TimeZona = 7 cho Viet Nam
    MsgBox GetDateTime(1, 7)
    MsgBox GetDateTime(2, 7)
    MsgBox GetDateTime(3, 7)
End Sub

Code dùng http://time.windows.com vì bản thân Windows cũng dùng :D

czas.jpg
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi chạy code có lỗi ở dòng
Mã:
GetGMTNetTime = CDate(Mid$(sResp, 6, 20)) + TimeSerial(7, 0, 0)
với sResp = "Sun, 22 Aug 2021 14:56:04 GMT"

Chạy code sau cũng sẽ có lỗi ngay
Mã:
Sub test()
Dim sResp As String, a As Date
    sResp = "Sun, 22 Aug 2021 14:56:04 GMT"
    a = CDate(Mid$(sResp, 6, 20))
    Debug.Print a
End Sub
-------------
Code tương tự nhưng lấy ngày tháng thời gian từ server http://time.windows.com
Mã:
Function GetDateTime(DateTime As Byte, TimeZone As Integer) As Date
'    DateTime:
'    1 - gio
'    2 - ngay thang
'    3 - ngay thang va gio
'    TimeZone - so nguyen (chenh lech voi gio Greenwich Mean Time)
'    TimeZone map - https://www.timeanddate.com/time/map/
'*******************************************************************
Dim Arr, XHTTP As Object
    On Error GoTo err

    Set XHTTP = CreateObject("MSXML2.XMLHTTP")
    With XHTTP
        .Open "Head", "http://time.windows.com/", False
        .Send
        Arr = Split(.getResponseHeader("Date"), " ")
    End With

    Select Case Arr(2)
        Case "Jan": Arr(2) = 1
        Case "Feb": Arr(2) = 2
        Case "Mar": Arr(2) = 3
        Case "Apr": Arr(2) = 4
        Case "May": Arr(2) = 5
        Case "Jun": Arr(2) = 6
        Case "Jul": Arr(2) = 7
        Case "Aug": Arr(2) = 8
        Case "Sep": Arr(2) = 9
        Case "Oct": Arr(2) = 10
        Case "Nov": Arr(2) = 11
        Case "Dec": Arr(2) = 12
    End Select

    Select Case DateTime
        Case 1: GetDateTime = TimeValue(Arr(4)) + 1 / 24 * TimeZone
        Case 2: GetDateTime = Format(DateSerial(Arr(3), Arr(2), Arr(1)) + TimeValue(Arr(4)) + 1 / 24 * TimeZone, "yyyy-mm-dd")
        Case 3: GetDateTime = DateSerial(Arr(3), Arr(2), Arr(1)) + TimeValue(Arr(4)) + 1 / 24 * TimeZone
    End Select

    Set XHTTP = Nothing

    On Error GoTo 0
    Exit Function
err:
    MsgBox "Loi " & err.Number & " (" & err.Description & ") trong ham GetDateTime "
End Function

Sub test()
'    TimeZona = 7 cho Viet Nam
    MsgBox GetDateTime(1, 7)
    MsgBox GetDateTime(2, 7)
    MsgBox GetDateTime(3, 7)
End Sub

Code dùng http://time.windows.com vì bản thân Windows cũng dùng :D

View attachment 264554
Dạ có thể mỗi máy mỗi khác, nhưng chạy trên máy của em nó chẳng lỗi gì cả. Chỉ có một điều thắc mắc là mình cho nó chạy trên trang nào nó cũng ra giờ.

Const sURL As String = "https://www.timeanddate.com"

Có đổi thành:

Const sURL As String = "https://www.giaiphapexcel.com"

Nó cũng chạy ra đúng giờ. Chưa hiểu tại sao.
 
Upvote 0
Dạ có thể mỗi máy mỗi khác, nhưng chạy trên máy của em nó chẳng lỗi gì cả.
Bạn chạy từng bước xem dạng của sReps là thế nào. Trên máy tôi thì dạng như trong bài #4.

biloi.jpg

Bạn chạy code test trong bài #4 có thấy lỗi không?

À mà tôi đoán ra rồi. Bạn có dạng trong CP y như dạng của sReps. Máy tôi trong CP có dạng hoàn toàn khác. Windows phiên bản Ba Lan, thiết lập là Ba Lan mà. Không có chuyện chuỗi có chứa Aug mà CDate lại chấp nhận. Nhưng code của tôi thì ai chạy cũng không bị lỗi.
 
Upvote 0
Bạn chạy từng bước xem dạng của sReps là thế nào. Trên máy tôi thì dạng như trong bài #4.

View attachment 264556

Bạn chạy code test trong bài #4 có thấy lỗi không?

À mà tôi đoán ra rồi. Bạn có dạng trong CP y như dạng của sReps. Máy tôi trong CP có dạng hoàn toàn khác. Windows phiên bản Ba Lan, thiết lập là Ba Lan mà. Không có chuyện chuỗi có chứa Aug mà CDate lại chấp nhận. Nhưng code của tôi thì ai chạy cũng không bị lỗi.
1629647094810.png

Máy em test không bị gì nhé thầy. Nhưng test thì thấy hàm của thầy có tốc độ nhanh hơn.
 
Upvote 0
Tôi chạy code có lỗi ở dòng
Mã:
GetGMTNetTime = CDate(Mid$(sResp, 6, 20)) + TimeSerial(7, 0, 0)
với sResp = "Sun, 22 Aug 2021 14:56:04 GMT"

Chạy code sau cũng sẽ có lỗi ngay
Mã:
Sub test()
Dim sResp As String, a As Date
    sResp = "Sun, 22 Aug 2021 14:56:04 GMT"
    a = CDate(Mid$(sResp, 6, 20))
    Debug.Print a
End Sub
-------------
Code tương tự nhưng lấy ngày tháng thời gian từ server http://time.windows.com
Mã:
Function GetDateTime(DateTime As Byte, TimeZone As Integer) As Date
'    DateTime:
'    1 - gio
'    2 - ngay thang
'    3 - ngay thang va gio
'    TimeZone - so nguyen (chenh lech voi gio Greenwich Mean Time)
'    TimeZone map - https://www.timeanddate.com/time/map/
'*******************************************************************
Dim Arr, XHTTP As Object
    On Error GoTo err

    Set XHTTP = CreateObject("MSXML2.XMLHTTP")
    With XHTTP
        .Open "Head", "http://time.windows.com/", False
        .Send
        Arr = Split(.getResponseHeader("Date"), " ")
    End With

    Select Case Arr(2)
        Case "Jan": Arr(2) = 1
        Case "Feb": Arr(2) = 2
        Case "Mar": Arr(2) = 3
        Case "Apr": Arr(2) = 4
        Case "May": Arr(2) = 5
        Case "Jun": Arr(2) = 6
        Case "Jul": Arr(2) = 7
        Case "Aug": Arr(2) = 8
        Case "Sep": Arr(2) = 9
        Case "Oct": Arr(2) = 10
        Case "Nov": Arr(2) = 11
        Case "Dec": Arr(2) = 12
    End Select

    Select Case DateTime
        Case 1: GetDateTime = TimeValue(Arr(4)) + 1 / 24 * TimeZone
        Case 2: GetDateTime = Format(DateSerial(Arr(3), Arr(2), Arr(1)) + TimeValue(Arr(4)) + 1 / 24 * TimeZone, "yyyy-mm-dd")
        Case 3: GetDateTime = DateSerial(Arr(3), Arr(2), Arr(1)) + TimeValue(Arr(4)) + 1 / 24 * TimeZone
    End Select

    Set XHTTP = Nothing

    On Error GoTo 0
    Exit Function
err:
    MsgBox "Loi " & err.Number & " (" & err.Description & ") trong ham GetDateTime "
End Function

Sub test()
'    TimeZona = 7 cho Viet Nam
    MsgBox GetDateTime(1, 7)
    MsgBox GetDateTime(2, 7)
    MsgBox GetDateTime(3, 7)
End Sub

Code dùng http://time.windows.com vì bản thân Windows cũng dùng :D

View attachment 264554
Chuẩn không cần chỉnh chú ạ, sau khi lấy được thời gian từ inter về có thể chỉnh luôn cái đồng hồ theo giờ và định dạng ngày giờ đã lấy về được không chú? chú viết cho cháu thêm một cái hàm để kiểm tra xem máy tính có kết nối với internet hay không với.
 
Upvote 0
Máy em test không bị gì nhé thầy. Nhưng test thì thấy hàm của thầy có tốc độ nhanh hơn.
Thì tôi viết rồi mà. Thiết lập trong CP của bạn y như dạng trong sReps. Còn trên máy tôi sReps vẫn là dạng Sun, 22 Aug 2021 18:14:05 GMT nhưng trong CP tôi có niedziela, 22 sierpnia 2021 (niedziela = Sun, sierpnia = Aug). Có lẽ vì thế mà CDate trả về lỗi.
Bài đã được tự động gộp:

Có đổi thành:
Const sURL As String = "https://www.giaiphapexcel.com"
Nó cũng chạy ra đúng giờ. Chưa hiểu tại sao.
Đoán ra rồi. Với những server khác nhau thì toàn bộ Header trả về là khác nhau (xem phần ở dưới), nhưng cấu trúc của phần Date luôn là như nhau, dường như có dạng chuẩn được qui định theo mẫu:

Date: <thứ bằng tiếng Anh>, <ngày> <tên tháng tiếng Anh> <năm> hh:mm:ss GMT

Header:

1. https://www.timeanddate.com

Connection: keep-alive
X-Frame-Options: SAMEORIGIN
Pragma: no-cache
Cache-Control: max-age=0, no-cache, no-store
Content-Type: text/html; charset=UTF-8
Accept-Ranges: bytes
Date: Sun, 22 Aug 2021 16:03:16 GMT
Via: 1.1 varnish
X-Served-By: cache-hhn4047-HHN
X-Cache: MISS
X-Cache-Hits: 0
X-Timer: S1629648197.501072,VS0,VE17
transfer-encoding: chunked

2. http://time.windows.com

Content-Type: text/html; charset=us-ascii
Date: Sun, 22 Aug 2021 16:01:41 GMT
Connection: close
Content-Length: 315

3. https://www.giaiphapexcel.com"

Server: nginx
Date: Sun, 22 Aug 2021 16:00:05 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Last-Modified: Sun, 22 Aug 2021 16:00:05 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: private, no-cache, max-age=0
Vary: User-Agent
Set-Cookie: xf_csrf=DvxhevkU21B0jkI-; path=/; secure
 
Upvote 0
chú viết cho cháu thêm một cái hàm để kiểm tra xem máy tính có kết nối với internet hay không với.
Cái này bạn tìm dễ mà. Tìm bằng google hoặc dùng "Tìm kiếm" của GPE. Từ khóa có thể là InternetGetConnectedState
Bài đã được tự động gộp:

KHi chạy thì ra như này là bị như nào vậy bác.
Là khi code chạy bị lỗi. Dòng cuối cùng trong hàm GetDateTime là thế này (MsgBox)
Mã:
On Error GoTo err
...
err:
MsgBox "Loi " & err.Number & " (" & err.Description & ") trong ham GetDateTime "
 
Upvote 0
sau khi lấy được thời gian từ inter về có thể chỉnh luôn cái đồng hồ theo giờ và định dạng ngày giờ đã lấy về được không chú?
Bạn đọc bài sau, và các bài khác trong chủ đề.

Để đọc ra thiết lập thì dùng hàm GetLocaleInfo. Để thiết lập thì dùng SetLocaleInfo

 
Upvote 0
Không biết tại sao lại cần hàm này, dùng cmd refresh lại là thời gian tự động cập nhật cho window, rồi ta dùng Vba.Now thôi
 
Upvote 0
Không biết tại sao lại cần hàm này, dùng cmd refresh lại là thời gian tự động cập nhật cho window, rồi ta dùng Vba.Now thôi
Ý bạn nói là hàm gì? Còn tôi dùng hàm GetGMTNetTime này để cài vào chương trình của tôi nhằm mục đích ngăn không cho nhân viên sửa chữa sau khi nhập liệu 24h. Một số nhân viên chơi "tiểu xảo" chỉnh lại thời gian hệ thống để chỉnh sửa lại khi nhập liệu cẩu thả, sau khi chỉnh sửa xong họ tự chỉnh lại ngày giờ. Cho nên hàm này sẽ như là cột mốc thời gian ngăn lại việc họ có thay đổi giờ hệ thống hay không.
 
Upvote 0
Nhân viên chỉnh bằng tay, mình chỉnh bằng code cmd, ai chắc hơn.
2 nữa, thời gian request được thì dùng javascript để convert thời gian, ai lại đi dùng hàm VBA.
Lỡ may nhân viên "tiểu xảo" ngắt internet, hàm trả giá trị 0. Bước tiếp theo mình phải xử lý ra sao
 
Upvote 0
Nhân viên chỉnh bằng tay, mình chỉnh bằng code cmd, ai chắc hơn.
2 nữa, thời gian request được thì dùng javascript để convert thời gian, ai lại đi dùng hàm VBA.
Lỡ may nhân viên "tiểu xảo" ngắt internet, hàm trả giá trị 0. Bước tiếp theo mình phải xử lý ra sao

Cái vụ đồng bộ giờ để kiểm tra cũng còn nhiều bất cập nên nếu có các bước xử lý nào hay để hạn chế, ngăn ngừa được thì chia sẽ nhé HeSanbi.
- Nếu ứng dụng có dùng máy chủ để lưu CSDL backend thì tôi dùng lênh DOS để lấy giờ của máy chủ trong mạng LAN. Nếu nhân viên tắt mạng LAN luôn thì lấy gì nhập liệu.
- Còn nếu đồng bộ giờ từ internet thì bạn có cách gì xử lý khi nhân viên tắt net?
- Còn nếu là một file nhập liệu độc lập thì tắt net thì cách nào xử lý hiệu quả hơn?
 
Upvote 0
Nhân viên chỉnh bằng tay, mình chỉnh bằng code cmd, ai chắc hơn.
2 nữa, thời gian request được thì dùng javascript để convert thời gian, ai lại đi dùng hàm VBA.
Lỡ may nhân viên "tiểu xảo" ngắt internet, hàm trả giá trị 0. Bước tiếp theo mình phải xử lý ra sao
Trong thời gian ngắt internet thì mình ngăn không cho chỉnh sửa trong thời gian này. Mà làm sao biết lúc này NV chỉnh sửa mà dùng CMD chứ!
 
Upvote 0
Kiểm tra thời gian hệ thống có bị chỉnh sửa không dùng winapi wm timechanged
 
Upvote 0
Kiểm tra thời gian hệ thống có bị chỉnh sửa không dùng winapi wm timechanged
Cái này tôi không biết, bạn có thể hướng dẫn cho tôi được không?

Còn tôi đang làm như vầy:

Mã:
Function GetGMTNetTime(Optional ByRef blnInternetDisconnected As Boolean) As Date
    Const sURL As String = "https://www.timeanddate.com"
    Dim oHTTP As Object
    Dim sResp As String
    Set oHTTP = CreateObject("Microsoft.XMLHTTP")
    On Error GoTo ErrorHandler
    oHTTP.Open "GET", sURL, False, "", ""
    oHTTP.Send
    sResp = oHTTP.getResponseHeader("Date")
    GetGMTNetTime = CDate(Mid(sResp, 6, 20)) + TimeSerial(7, 0, 0)
    Set oHTTP = Nothing
    Exit Function
ErrorHandler:
    Set oHTTP = Nothing
    blnInternetDisconnected = True
    'MsgBox "Internet disconnected!"
End Function

Sau đó là kiểm tra kết nối Internet, thế là xong.

Mã:
Sub test()
    Dim blnCheck As Boolean
    Dim dteDateTime As Date
    dteDateTime = GetGMTNetTime(blnCheck)
    If blnCheck Then
        MsgBox "Trong thoi gian mat ket noi Internet, ban khong duoc chinh sua"
        Exit Sub
    End If
    ''...
End Sub
 
Upvote 0
Trong thời gian ngắt internet thì mình ngăn không cho chỉnh sửa trong thời gian này.
Cái vụ này khó à. Nếu cty rớt mạng toàn hệ thống thì công việc nhập liệu, xử lý dữ liệu hàng ngày cũng ngưng luôn sao được bạn.
Bài đã được tự động gộp:

Kiểm tra thời gian hệ thống có bị chỉnh sửa không dùng winapi wm timechanged

Vậy có một giải pháp khác là ngăn không cho người dùng thay đổi giờ hệ thống.
 
Upvote 0
Web KT
Back
Top Bottom