I’m pulling a date/time value from the http response headers of a webserver in the format:
Date: Mon, 24 Mar 2025 09:32:51 GMT
I’d like to get this value into a DateTime variable. Is there a way to have the xojo framework do the conversion from the string (ie is there perhaps a locale that will work with this format?) or do I have to parse it manually?
To be clear, parsing it would not be a big deal, just want to know for future reference if this is something Xojo can do.
Public Function ParseHTTPDate(dateString As String, convertToLocalTime As Boolean = False) As DateTime
'------------------------------------------------------------------------------
' ParseHTTPDate
'
' Purpose:
' Parses an HTTP-style date string (commonly found in HTTP headers) into a
' DateTime object. This function handles the RFC 7231 format used in HTTP
' date headers.
'
' Parameters:
' dateString (String) - The date string to parse. Can be in either of these formats:
' - "Mon, 24 Mar 2025 09:32:51 GMT" (standard format)
' - "Date: Mon, 24 Mar 2025 09:32:51 GMT" (with "Date: " prefix)
'
' convertToLocalTime (Boolean) - Optional parameter, defaults to False
' - If True: Converts the parsed GMT time to the local system time zone
' - If False: Returns the DateTime in GMT/UTC time zone
'
' Returns:
' DateTime - A DateTime object representing the parsed date and time
' Nil - If the date string could not be parsed (invalid format)
'
' Notes:
' - This function expects the HTTP date format as defined in RFC 7231
' - The time zone in the string is assumed to be GMT/UTC
' - Month names are expected to be the English three-letter abbreviations
' - The time zone conversion uses the system's current time zone settings
'
' Example Usage:
' Var gmtTime As DateTime = ParseHTTPDate("Date: Mon, 24 Mar 2025 09:32:51 GMT")
' Var localTime As DateTime = ParseHTTPDate("Mon, 24 Mar 2025 09:32:51 GMT", True)
'
' Potential Caveats:
' - Does not handle all possible HTTP date formats (e.g., obsolete RFC 850 format)
' - Relies on the system's time zone settings being correct
' - No handling for malformed time components (e.g., if hours > 23)
' - If the input contains a timezone other than GMT, it will still be treated as GMT
' - String parsing is not locale-aware; relies on English month abbreviations
'------------------------------------------------------------------------------
// Handle both formats with and without "Date: " prefix
If dateString.BeginsWith("Date: ") Then
dateString = dateString.Middle(6) // Skip the "Date: " prefix
End If
// Split the string by spaces and commas
Var parts() As String = dateString.ReplaceAll(",", "").Split(" ")
// Check if we have enough parts
If parts.Count < 6 Then
Return Nil // Invalid format
End If
// Parse the components
Var day As Integer = parts(1).ToInteger()
Var month As Integer = 0
Var year As Integer = parts(3).ToInteger()
// Convert month name to month number
Select Case parts(2).Lowercase
Case "jan"
month = 1
Case "feb"
month = 2
Case "mar"
month = 3
Case "apr"
month = 4
Case "may"
month = 5
Case "jun"
month = 6
Case "jul"
month = 7
Case "aug"
month = 8
Case "sep"
month = 9
Case "oct"
month = 10
Case "nov"
month = 11
Case "dec"
month = 12
End Select
// Parse time components
Var timeParts() As String = parts(4).Split(":")
Var hour As Integer = timeParts(0).ToInteger()
Var minute As Integer = timeParts(1).ToInteger()
Var second As Integer = timeParts(2).ToInteger()
// Create the DateTime object in GMT
Var gmtTimeZone As New TimeZone(0) // GMT/UTC has zero offset
Var dateTime As New DateTime(year, month, day, hour, minute, second, 0, gmtTimeZone)
// Convert to local time if requested
If convertToLocalTime Then
// Get the seconds since 1970 and create a new DateTime in the local timezone
Var secondsSince1970 As Double = dateTime.SecondsFrom1970
Return New DateTime(secondsSince1970, TimeZone.Current)
Else
// Return the DateTime in GMT
Return dateTime
End If
End Function
// Rick's approach to the HTTP DateTime conversion problem
Static MonthArray() As String = Array("", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
Var dateStr As String = "Date: Mon, 24 Mar 2025 09:32:51 GMT"
// clean it and break the parts
Var p() As String = dateStr.Replace(" GMT","")_
.ReplaceAll(":", " ")_
.Middle(dateStr.IndexOf(", ")+2)_
.Split()
Var theDateTime As New DateTime(_
p(2).ToInteger, MonthArray.IndexOf(p(1)), p(0).ToInteger,_
p(3).ToInteger, p(4).ToInteger, p(5).ToInteger,_
0, New TimeZone(0))
break