Timezone-Aware Document Metadata

I’m attempting to store DateTime information about a text document (accessible in File > Properties) and I would like to ensure that the timezone offset is appended to the timestamp when it’s stored.

It’s currently writing this to the file:
<meta:user-defined meta:name="Date completed" meta:value-type="date">2025-08-06T00:03:36</meta:user-defined>

The output should be either:
<meta:user-defined meta:name="Date completed" meta:value-type="date">2025-08-06T00:03:36-08:00</meta:user-defined>
or
<meta:user-defined meta:name="Date completed" meta:value-type="date">2025-08-06T08:03:36Z</meta:user-defined>

If it’s possible, I would like to replace the naive timestamps (such as creation-date) with timezone-aware timestamps throughout the entire document at the time of its saving. Have I overlooked a configuration option somewhere? I’m using LibreOffice version 25.2.5.2 from Flatpak.

Note:
tdf#65209
tdf#67763
tdf#160423
tdf#165876

= …

as a workaround:
in ⇒ File ⇒ Properties ⇒ Userdefed Properties
create a new Field with Name creation_utc and Type »Text«,
and run:

from datetime import datetime as dt, timezone as tz

def set_user_defined_utc_creation_date():
    """
    takes the naiv creation_date from Document_Properties
    and inserts it as timezone_aware utc_date into
    User_defined_properties: »creation_utc« 
    """

    doc = XSCRIPTCONTEXT.getDocument()
    doc_props = doc.DocumentProperties
    c_date = doc_props.CreationDate
    date_naiv = dt( (d:=c_date).Year, d.Month, d.Day,
                    d.Hours, d.Minutes, d.Seconds)
    date_aware = date_naiv.astimezone(tz.utc)
    
    user_props = doc_props.UserDefinedProperties
    user_props.creation_utc = date_aware.isoformat()

A. Pitonyak has a similar macro, my version is a little more relevant for current versions of LO.

' ----------------------------------------------------------------------------------------------
' Set document user defined property.
' - oDoc   Document (object).
' - pName  Property name.
' - pValue Property value.
' If a property named `pName` is missing, it is created. 
' The property type (double, string, dateTime, boolean) is determined by the `pValue` type.   
Sub SetDocUDP(Byval oDoc as Object, ByVal pName As String, ByVal pValue)
  Dim oUDP as Object, t As String, v
  t = VarType(pValue)
  If t = V_DATE Then
    v = CdateToUnoDateTime(pValue)     
  ElseIf t = V_STRING Or t = 11 Then  ' string or boolean
    v = pValue
  Else
    v = CreateUnoValue("double", pValue)     
  End If
  
  oUDP = oDoc.DocumentProperties.UserDefinedProperties
  If NOT oUDP.getPropertySetInfo().hasPropertyByName(pName) Then
    oUDP.addProperty(pName, _
      com.sun.star.beans.PropertyAttribute.MAYBEVOID + _
      com.sun.star.beans.PropertyAttribute.REMOVEABLE + _
      com.sun.star.beans.PropertyAttribute.MAYBEDEFAULT, _
      v)
  Else
    oUDP.setPropertyValue(pName, v)
  End If
End Sub


Sub TestSetDocUDP()
  Dim oDoc 
  oDoc = StarDesktop.LoadComponentFromUrl("private:factory/scalc", "_default", 0, Array())
  'oDoc = ThisComponent
  SetDocUDP oDoc, "MyDate", Now()
  SetDocUDP oDoc, "MyNumber", 17
  SetDocUDP oDoc, "MyBool", True
  SetDocUDP oDoc, "MyString", "LO Forum"
  ' mri oDoc.DocumentProperties.UserDefinedProperties
End Sub   

@sokol92 thankyou … that solves the part »how to create userdefined properties by code.

Unfortunatly your »MyDate« -field has no Information about the TimeZone.
compare:

from datetime import datetime as dt, timezone as tz
from zoneinfo import ZoneInfo as zone, available_timezones 
# lookup available names by calling »available_timezones()«

naive, aware = dt.now(), dt.now(tz.utc)
print(f"{naive = :%Y-%m-%d %H:%M:%S %:z}")
print(f"{aware = :%Y-%m-%d %H:%M:%S %:z}")
print(f"{naive.astimezone(zone('localtime')) = :%Y-%m-%d %H:%M:%S %:z}")
print(f"{aware.astimezone(zone('localtime')) = :%Y-%m-%d %H:%M:%S %:z}")

which shows here (Europe/Berlin CEST):

naive = 2025-08-07 14:19:24 
aware = 2025-08-07 12:19:24 +00:00
naive.astimezone(zone('localtime')) = 2025-08-07 14:19:24 +02:00
aware.astimezone(zone('localtime')) = 2025-08-07 14:19:24 +02:00

I think it is possible to save UTC dates (and reflect this in the property name). The author of this topic suggests this in the opening message.

of course, you need to cast the naive_Uno-Date-Time to the respective utc-date and create from this another Uno-DateTime-struct with the property IsUTC=true

@karolus , see also my first message on the forum. :slight_smile:

fine … and now try:

Function getUTCTime() As Double
  Dim aLocale As New com.sun.star.lang.Locale
  Dim oLocaleCalendar2 As Object
  oLocaleCalendar2=CreateUnoService("com.sun.star.i18n.LocaleCalendar2")
  With oLocaleCalendar2
    .loadDefaultCalendarTZ(aLocale, "GMT") 
     getUTCTime=.getLocalDateTime
  End With  
End Function

Sub TestgetUTCTime
  msgbox format(getUTCTime(), "YYYY-mm-dd HH:MM:SS")
End Sub 

:joy: :joy:

1 Like

Cuncta fluunt, omnia mutantur :cry:

But I fixed it in the same topic:

Function getUTCDateTime() As Date
  Dim aLocale As New com.sun.star.lang.Locale
  Dim oLocaleCalendar2 As Object
  oLocaleCalendar2=CreateUnoService("com.sun.star.i18n.LocaleCalendar2")
  With oLocaleCalendar2
    .loadDefaultCalendarTZ(aLocale, "UTC") 
     getUTCDateTime=DateSerial(1970,1,1) + .getLocalDateTime
  End With  
End Function

Sub TestgetUTCDateTime
  Msgbox getUTCDateTime
End Sub

Yes, can be fixed, but why does this stupid calendar thing return the floating point days since the Unix epoch and not, for example, the floating point days since the LO epoch, or better yet, a Uno DateTime struct?

I think the authors of UNO interfaces were guided by the Java language constructs: date - the milliseconds since January 1, 1970, 00:00:00 GMT.