Update Stock Time Stamp to Eastern Time

This commit is contained in:
Rufus King 2026-07-28 17:09:50 -04:00
parent 547a74768e
commit 70a1a14735

View file

@ -1,30 +1,46 @@
' ========================================================================= ' =========================================================================
'
' StockFunctions.bas ' StockFunctions.bas
' Collabora / LibreOffice Basic ' Collabora / LibreOffice Basic
' '
' FUNDTIME now returns Yahoo's latest market update date/time: ' FUNDTIME returns Yahoo's latest market update date/time
' converted from UTC to U.S. Eastern Time.
' '
' Example:
'
' stockproxy UTC:
' 2026-07-27 19:58:00 ' 2026-07-27 19:58:00
' '
' The date and time are obtained from the stockproxy /current endpoint. ' FUNDTIME:
' 2026-07-27 15:58:00
'
' Eastern Time automatically observes:
'
' EDT = UTC-4
' EST = UTC-5
'
' ========================================================================= ' =========================================================================
Option Explicit Option Explicit
' ---- Config ------------------------------------------------------------- ' ---- Config -------------------------------------------------------------
Function PROXY_BASE() As String Function PROXY_BASE() As String
PROXY_BASE = "https://stocks.kingdezigns.com" PROXY_BASE = "https://stocks.kingdezigns.com"
End Function End Function
Function PROXY_SECRET() As String Function PROXY_SECRET() As String
PROXY_SECRET = "90c2528e9b5221c110f7c2c9cd6c65dc" PROXY_SECRET = "90c2528e9b5221c110f7c2c9cd6c65dc"
End Function End Function
' ---- Public spreadsheet functions --------------------------------------- ' ---- Public spreadsheet functions --------------------------------------
Function FUNDPRICE(ticker As String) As Variant Function FUNDPRICE(ticker As String) As Variant
Dim sUrl As String Dim sUrl As String
Dim sJson As String Dim sJson As String
Dim vPrice As Variant Dim vPrice As Variant
@ -46,10 +62,12 @@ Function FUNDPRICE(ticker As String) As Variant
Else Else
FUNDPRICE = vPrice FUNDPRICE = vPrice
End If End If
End Function End Function
Function FUNDPRICE_HIST(ticker As String, dateStr As String) As Variant Function FUNDPRICE_HIST(ticker As String, dateStr As String) As Variant
Dim sUrl As String Dim sUrl As String
Dim sJson As String Dim sJson As String
Dim vPrice As Variant Dim vPrice As Variant
@ -72,23 +90,61 @@ Function FUNDPRICE_HIST(ticker As String, dateStr As String) As Variant
Else Else
FUNDPRICE_HIST = vPrice FUNDPRICE_HIST = vPrice
End If End If
End Function End Function
' ---- Yahoo market update date/time -------------------------------------- ' ---- Yahoo market update date/time --------------------------------------
' '
' Returns: ' stockproxy supplies the Yahoo timestamp in UTC.
' '
' FUNDTIME converts that UTC timestamp to U.S. Eastern Time.
'
' During daylight saving time:
'
' EDT = UTC - 4 hours
'
' During standard time:
'
' EST = UTC - 5 hours
'
' Example:
'
' UTC:
' 2026-07-27 19:58:00 ' 2026-07-27 19:58:00
' '
' This combines the "date" and "time" fields returned by stockproxy. ' Eastern:
' 2026-07-27 15:58:00
' '
Function FUNDTIME(ticker As String) As String Function FUNDTIME(ticker As String) As String
Dim sUrl As String Dim sUrl As String
Dim sJson As String Dim sJson As String
Dim sDate As String Dim sDate As String
Dim sTime As String Dim sTime As String
Dim iYear As Integer
Dim iMonth As Integer
Dim iDay As Integer
Dim iHour As Integer
Dim iMinute As Integer
Dim iSecond As Integer
Dim dUTC As Date
Dim dMarch As Date
Dim dNovember As Date
Dim dDSTStart As Date
Dim dDSTEnd As Date
Dim iMarchSunday As Integer
Dim iNovemberSunday As Integer
Dim iOffset As Integer
' ---------------------------------------------------------------
' Get current stock data from stockproxy
' ---------------------------------------------------------------
sUrl = PROXY_BASE() & "/current?ticker=" & EncodeUrl(ticker) & _ sUrl = PROXY_BASE() & "/current?ticker=" & EncodeUrl(ticker) & _
"&key=" & PROXY_SECRET() "&key=" & PROXY_SECRET()
@ -99,6 +155,11 @@ Function FUNDTIME(ticker As String) As String
Exit Function Exit Function
End If End If
' ---------------------------------------------------------------
' Get UTC date and time from JSON
' ---------------------------------------------------------------
sDate = JsonString(sJson, "date") sDate = JsonString(sJson, "date")
sTime = JsonString(sJson, "time") sTime = JsonString(sJson, "time")
@ -107,14 +168,116 @@ Function FUNDTIME(ticker As String) As String
Exit Function Exit Function
End If End If
FUNDTIME = sDate & " " & sTime
' ---------------------------------------------------------------
' Parse date
'
' Expected:
' YYYY-MM-DD
' ---------------------------------------------------------------
iYear = CInt(Left(sDate, 4))
iMonth = CInt(Mid(sDate, 6, 2))
iDay = CInt(Right(sDate, 2))
' ---------------------------------------------------------------
' Parse time
'
' Expected:
' HH:MM:SS
' ---------------------------------------------------------------
iHour = CInt(Left(sTime, 2))
iMinute = CInt(Mid(sTime, 4, 2))
iSecond = CInt(Right(sTime, 2))
' ---------------------------------------------------------------
' Create UTC date/time
' ---------------------------------------------------------------
dUTC = DateSerial(iYear, iMonth, iDay)
dUTC = dUTC + TimeSerial(iHour, iMinute, iSecond)
' ---------------------------------------------------------------
' Find second Sunday in March
' ---------------------------------------------------------------
dMarch = DateSerial(iYear, 3, 8)
iMarchSunday = 8 - WeekDay(dMarch)
If iMarchSunday < 0 Then
iMarchSunday = iMarchSunday + 7
End If
dDSTStart = dMarch + iMarchSunday
' 2:00 AM EST = 07:00 UTC
dDSTStart = dDSTStart + TimeSerial(7, 0, 0)
' ---------------------------------------------------------------
' Find first Sunday in November
' ---------------------------------------------------------------
dNovember = DateSerial(iYear, 11, 1)
iNovemberSunday = 8 - WeekDay(dNovember)
If iNovemberSunday < 0 Then
iNovemberSunday = iNovemberSunday + 7
End If
dDSTEnd = dNovember + iNovemberSunday
' 2:00 AM EDT = 06:00 UTC
dDSTEnd = dDSTEnd + TimeSerial(6, 0, 0)
' ---------------------------------------------------------------
' Determine Eastern Time offset
' ---------------------------------------------------------------
If dUTC >= dDSTStart And dUTC < dDSTEnd Then
' Eastern Daylight Time
iOffset = 4
Else
' Eastern Standard Time
iOffset = 5
End If
' ---------------------------------------------------------------
' Convert UTC to Eastern Time
' ---------------------------------------------------------------
dUTC = dUTC - TimeSerial(iOffset, 0, 0)
' ---------------------------------------------------------------
' Return:
'
' YYYY-MM-DD HH:MM:SS
' ---------------------------------------------------------------
FUNDTIME = Format(dUTC, "YYYY-MM-DD HH:MM:SS")
End Function End Function
' ---- Internal helpers ---------------------------------------------------- ' ---- Internal helpers ---------------------------------------------------
' Synchronous HTTP GET, returns response body as text, "" on failure. ' Synchronous HTTP GET, returns response body as text, "" on failure.
Function HttpGetText(sUrl As String) As String Function HttpGetText(sUrl As String) As String
Dim oSFA As Object Dim oSFA As Object
Dim oStream As Object Dim oStream As Object
Dim oTextStream As Object Dim oTextStream As Object
@ -132,21 +295,29 @@ Function HttpGetText(sUrl As String) As String
sResult = "" sResult = ""
Do While Not oTextStream.isEOF() Do While Not oTextStream.isEOF()
sResult = sResult & oTextStream.readLine() & Chr(10) sResult = sResult & oTextStream.readLine() & Chr(10)
Loop Loop
oTextStream.closeInput() oTextStream.closeInput()
HttpGetText = sResult HttpGetText = sResult
Exit Function Exit Function
ErrHandler: ErrHandler:
HttpGetText = "" HttpGetText = ""
End Function End Function
' Pulls a numeric value out of a flat JSON string for a given key. ' Pulls a numeric value out of a flat JSON string for a given key.
Function JsonNumber(sJson As String, sKey As String) As Variant Function JsonNumber(sJson As String, sKey As String) As Variant
Dim iPos As Integer Dim iPos As Integer
Dim iStart As Integer Dim iStart As Integer
Dim iEnd As Integer Dim iEnd As Integer
@ -156,97 +327,147 @@ Function JsonNumber(sJson As String, sKey As String) As Variant
iPos = InStr(sJson, Chr(34) & sKey & Chr(34)) iPos = InStr(sJson, Chr(34) & sKey & Chr(34))
If iPos = 0 Then If iPos = 0 Then
JsonNumber = Null JsonNumber = Null
Exit Function Exit Function
End If End If
iPos = InStr(iPos, sJson, ":") iPos = InStr(iPos, sJson, ":")
If iPos = 0 Then If iPos = 0 Then
JsonNumber = Null JsonNumber = Null
Exit Function Exit Function
End If End If
iStart = iPos + 1 iStart = iPos + 1
Do While iStart <= Len(sJson) And Mid(sJson, iStart, 1) = " "
Do While iStart <= Len(sJson) And _
Mid(sJson, iStart, 1) = " "
iStart = iStart + 1 iStart = iStart + 1
Loop Loop
iEnd = iStart iEnd = iStart
Do While iEnd <= Len(sJson) Do While iEnd <= Len(sJson)
cChar = Mid(sJson, iEnd, 1) cChar = Mid(sJson, iEnd, 1)
If (cChar >= "0" And cChar <= "9") Or _ If (cChar >= "0" And cChar <= "9") Or _
cChar = "." Or cChar = "-" Then cChar = "." Or cChar = "-" Then
iEnd = iEnd + 1 iEnd = iEnd + 1
Else Else
Exit Do Exit Do
End If End If
Loop Loop
sNum = Mid(sJson, iStart, iEnd - iStart) sNum = Mid(sJson, iStart, iEnd - iStart)
If Len(sNum) = 0 Then If Len(sNum) = 0 Then
JsonNumber = Null JsonNumber = Null
Else Else
JsonNumber = CDbl(sNum) JsonNumber = CDbl(sNum)
End If End If
End Function End Function
' Pulls a quoted string value out of a flat JSON string. ' Pulls a quoted string value out of a flat JSON string.
Function JsonString(sJson As String, sKey As String) As String Function JsonString(sJson As String, sKey As String) As String
Dim iPos As Integer Dim iPos As Integer
Dim iColon As Integer Dim iColon As Integer
Dim iQuoteStart As Integer Dim iQuoteStart As Integer
Dim iQuoteEnd As Integer Dim iQuoteEnd As Integer
iPos = InStr(sJson, Chr(34) & sKey & Chr(34)) iPos = InStr(sJson, Chr(34) & sKey & Chr(34))
If iPos = 0 Then If iPos = 0 Then
JsonString = "" JsonString = ""
Exit Function Exit Function
End If End If
iColon = InStr(iPos, sJson, ":") iColon = InStr(iPos, sJson, ":")
If iColon = 0 Then If iColon = 0 Then
JsonString = "" JsonString = ""
Exit Function Exit Function
End If End If
iQuoteStart = InStr(iColon, sJson, Chr(34)) iQuoteStart = InStr(iColon, sJson, Chr(34))
If iQuoteStart = 0 Then If iQuoteStart = 0 Then
JsonString = "" JsonString = ""
Exit Function Exit Function
End If End If
iQuoteEnd = InStr(iQuoteStart + 1, sJson, Chr(34)) iQuoteEnd = InStr(iQuoteStart + 1, sJson, Chr(34))
If iQuoteEnd = 0 Then If iQuoteEnd = 0 Then
JsonString = "" JsonString = ""
Exit Function Exit Function
End If End If
JsonString = Mid(sJson, iQuoteStart + 1, _ JsonString = Mid(sJson, iQuoteStart + 1, _
iQuoteEnd - iQuoteStart - 1) iQuoteEnd - iQuoteStart - 1)
End Function End Function
' Minimal percent-encoder. ' Minimal percent-encoder.
Function EncodeUrl(s As String) As String Function EncodeUrl(s As String) As String
Dim i As Integer Dim i As Integer
Dim c As String Dim c As String
Dim sOut As String Dim sOut As String
sOut = "" sOut = ""
For i = 1 To Len(s) For i = 1 To Len(s)
c = Mid(s, i, 1) c = Mid(s, i, 1)
If (c >= "A" And c <= "Z") Or _ If (c >= "A" And c <= "Z") Or _
(c >= "a" And c <= "z") Or _ (c >= "a" And c <= "z") Or _
(c >= "0" And c <= "9") Or _ (c >= "0" And c <= "9") Or _
@ -256,18 +477,23 @@ Function EncodeUrl(s As String) As String
Else Else
sOut = sOut & "%" & Right("0" & Hex(Asc(c)), 2) sOut = sOut & "%" & _
Right("0" & Hex(Asc(c)), 2)
End If End If
Next i Next i
EncodeUrl = sOut EncodeUrl = sOut
End Function End Function
' ---- Snapshot ------------------------------------------------------------ ' ---- Snapshot ------------------------------------------------------------
Sub RefreshPriceSnapshot Sub RefreshPriceSnapshot
Dim oDoc As Object Dim oDoc As Object
Dim oSheet As Object Dim oSheet As Object
Dim i As Integer Dim i As Integer
@ -275,7 +501,9 @@ Sub RefreshPriceSnapshot
oDoc = ThisComponent oDoc = ThisComponent
oSheet = oDoc.Sheets.getByIndex(0) oSheet = oDoc.Sheets.getByIndex(0)
' Copy P3:Q53 -> R3:S53 as values only ' Copy P3:Q53 -> R3:S53 as values only
For i = 2 To 4 For i = 2 To 4
oSheet.getCellByPosition(17, i).setValue( _ oSheet.getCellByPosition(17, i).setValue( _
@ -286,5 +514,7 @@ Sub RefreshPriceSnapshot
Next i Next i
MsgBox "Price snapshot refreshed." MsgBox "Price snapshot refreshed."
End Sub End Sub