What API service/interface can update/return a com.sun.star.util.DateTime
with current UTC values at high resolution?
Hallo
from datetime import datetime, timezone
print(datetime.utcnow())
print(datetime.now(timezone.utc))
2023-02-13 11:57:26.624702
2023-02-13 11:57:26.630255+00:00
the resulution is in nanomikroseconds ( in theory âŠ). In practice, however, it depends on how accurately your system clock is ticking.
It should probably not depend on the system clock mainly, but rather on the systemâs synchronization with NTP servers.
If I insert a DateTime textfield into a Writer text, I also get a time value pretending to resolve the time to ns (1E-9 s), but if I do the same trick with a spreadsheet cell (by code; not supported by the UI) I get the time (in the same structure) only resolved to ms as it is appropriate if it is derived from a IEEE 754 Double
datetime due to the many integer days contained there spoiling the fractional precision. With the same resolution I get the time initializing a LocaleCalendar
instance with null Locale
. (Thatâs the way I did it for my utcNow() function once discussed in forum.openoffice.org; you may remember.)
Now I wonder if the ”s and ns in the Writer field are just artifacts or contain some reality.
Of course, I donât actually need time at that resolution. Iâm not running a GPS.
OK, letâs build an add-in âPyUTCâ. I can think of 3 date-time functions.
EPOCH() returns the seconds since 1970-1-1.
UTC() returns Double.
GMT() returns an ISO string.
I think, the idl definition might look like this:
module org { module openoffice { module sheet { module addin {
interface XPyUTC{
long epoch();
double utc();
string gmt();
};
}; }; }; };
No, parameters, all 3 functions should be volatile and appear in the formula wizard under category âDate & Timeâ.
Sorry. It doesnât seem that you are interested in my actual request, nor that you read my comment above on the post by @karolus.
Well, I didnât emphasize the API relation in the questionâs subject line. I will now edit the subject to make this more clear. If you remember the bloated discussion concerning my utcNow()-snippet
in the already mentioned forum you wonât be surprised that I neither suspect âkarolusâ nor âVilleroyâ to exactly have addressed the actual topic there. The function I supplied there, however, works exactly as I described it.
Once again: I agree that LibreOffice Basic is a very poor language. The LibreOffice API, however, offers lots of valuable and efficient means and tools. (It also has serious shortcomings of course.) Only with its short and wide bridge to the API Basic is of real interest. You or whoever may prefer Python
functions over API methods. Itâs your choice. I make mine.
A result in whole seconds (UNIX-dts like), or one restricted to the resolution âDoubleâ used for a dts can provide, surely canât be the answer to my request.
Thanks for your interest.
BTW: The questionâs text wasnât edited. It refered from the beginning to the API.
If the API doesnât have it, an add-in can add it.
Finally, you can call something like:
srv = createUnoService("com.sun.star.sheet.FunctionAccess")
lSeconds = srv.callFunction("org.openoffice.addin.XPyUTC.EPOCH", Array())
I use this:
' The Round function is only defined when VBASupport is 1.
Option VbaSupport 1
Option Explicit
' lang:en
' Converts d to UTC according to the time zone set by the operating system.
Function getUTC(ByVal d As Date) As Date
Static diff As Double, firstCall As Long
Dim aLocale As New com.sun.star.lang.Locale
Dim oLocaleCalendar2 As Object
If firstCall=0 Then
oLocaleCalendar2=CreateUnoService("com.sun.star.i18n.LocaleCalendar2")
With oLocaleCalendar2
.loadDefaultCalendarTZ(aLocale, "UTC")
diff=Now() - DateSerial(1970,1,1) - .getLocalDateTime
' Round off the timezone offset to the nearest minute.
diff=Round(diff * 24 * 60, 0) / 24 / 60
End With
firstCall=1
End If
getUTC=d-diff
End Function
Sub Test
Msgbox getUTC(Now())
End Sub
This way we would be getting into a similar discusion as compared to the already mentioned one. If you at that time read my posts there, you may remember that I knew appropriate API means (though they werenât at your taste).
A LocaleCalendar object actually behaves as I described and used it there, and the reason for the repellent length of the respecive function wasnât âsilly Basicâ but an included explanation and lots of lines needed to be able to return the result in numeric form regarding the (actually) silly NullDate preset in the environment. Of course, I can also ignore needed case distinctions in Basic if I donât worry about reliability.
To avoid further complications: I know that the UTC functions you recommended donât need to look at a NullDate. LocaleCalendar also doesnât.
I think we should terminate this now.
Thank you.
You posted this earlier, and it was the basis for what I posted in this forum thread.
However, the LocaleCalendar
service again treats date and time in one datetime value of IEEE type Double. Currently this allows for time resolution to the ms (and even a bit more), but wait a few centuries and the seconds get in danger due to the increasing magnitude of the number of days. On the other hand the API knows a structure com.sun.star.util.DateTime
which separates the contributions and is prepared to resolve time to the ns (1E-9 s)
. It looks funny: The only case I know where this structure actually is used to store the time is in com.sun.star.text.textfield.DateTime
. If I look inside there, it actually contains a value to a resolution far below the ms. Why? And why do other services ignore the available resolution and stick to one Double value for everything? This was the sole background of my question. (I know UNIX timestamps anyway, and donât need Python to get them.)
Sorry if you wasted your time trying to help me. And thanks again!
Hello Wolfgang!
I wrote the text of the macro only because I wanted to emphasize the importance of rounding to the minute offset of the current time zone from UTC. If this is not done, then errors in fractions of a second will occur, which can be significant.
To understand that clearly, I would have to be really well rested.
I even didnât understand why you use loadDefaultCalendarTZ
instead of loadDefaultCalendar
.
If you think the âsnippetâ I mentioned is erroneous, please tell me. Precisely:
Is this wrong?
I donât see any errors in your functions.
Returning to the subject of the topic title, the task of getting the exact value of UTC is equivalent to the task of getting the exact local time, since the difference is always an integer number of minutes (for all time zones). For Basic Timestamp
, I would suggest using Now() + thousandths of a second from getSystemTicks() (may have to do some âcalibrationâ).