How to get current UTC DateTime at high resolution {edited: by LibO API means}?

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
2 Likes

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”).

1 Like