summaryrefslogtreecommitdiff
path: root/wizards
diff options
context:
space:
mode:
authorJean-Pierre Ledure <jp@ledure.be>2021-04-28 17:16:43 +0200
committerJean-Pierre Ledure <jp@ledure.be>2021-04-29 11:02:47 +0200
commit225ee785520bbbee5b2d9bd63915db7197ee7ccc (patch)
treea89d937b8493829a484b564ac30d3ddcbda1782a /wizards
parent5753386c2353ad4866e7c5dd9e8751ccaa58e93c (diff)
ScriptForge - (scriptforge.py) dates passed as UNO dates
In replacement of the ISO format, to avoid any misinterpretation of strings containing accidentally a date, from now on, dates are exchanged between Basic and Python as com.sun.star.util.DateTime structures. The year boundaries are [1900 - 9999]. The code managing the Python-Basic protocol has been changed on both sides. The Basic service receives the - CDateFromUnoDateTime() - CDateToUnoDateTime() methods, equivalent with their Basic homonyms. Change-Id: Ib6ded20c24ff71d3349d242f72bd7b88f69a2661 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114815 Tested-by: Jean-Pierre Ledure <jp@ledure.be> Tested-by: Jenkins Reviewed-by: Jean-Pierre Ledure <jp@ledure.be>
Diffstat (limited to 'wizards')
-rw-r--r--wizards/source/scriptforge/SF_PythonHelper.xba37
-rw-r--r--wizards/source/scriptforge/python/scriptforge.py116
2 files changed, 101 insertions, 52 deletions
diff --git a/wizards/source/scriptforge/SF_PythonHelper.xba b/wizards/source/scriptforge/SF_PythonHelper.xba
index 46c28293415b..b7d8141325b2 100644
--- a/wizards/source/scriptforge/SF_PythonHelper.xba
+++ b/wizards/source/scriptforge/SF_PythonHelper.xba
@@ -177,11 +177,15 @@ Check:
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Try:
- vDate = SF_Utils._CStrToDate(DateArg)
+ If VarType(DateArg) = V_OBJECT Then
+ vDate = CDateFromUnoDateTime(DateArg)
+ Else
+ vDate = SF_Utils._CStrToDate(DateArg)
+ End If
vNewDate = DateAdd(Add, Count, vDate)
Finally:
- If VarType(vNewDate) = V_DATE Then PyDateAdd = SF_Utils._CDateToIso(vNewDate) Else PyDateAdd = vNewDate
+ If VarType(vNewDate) = V_DATE Then PyDateAdd = CDateToUnoDateTime(vNewDate) Else PyDateAdd = vNewDate
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
@@ -219,8 +223,16 @@ Check:
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Try:
- vDate1 = SF_Utils._CStrToDate(Date1)
- vDate2 = SF_Utils._CStrToDate(Date2)
+ If VarType(Date1) = V_OBJECT Then
+ vDate1 = CDateFromUnoDateTime(Date1)
+ Else
+ vDate1 = SF_Utils._CStrToDate(Date1)
+ End If
+ If VarType(Date2) = V_OBJECT Then
+ vDate2 = CDateFromUnoDateTime(Date2)
+ Else
+ vDate2 = SF_Utils._CStrToDate(Date2)
+ End If
lDiff = DateDiff(Add, vDate1, vDate2, WeekStart, YearStart)
@@ -261,7 +273,11 @@ Check:
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Try:
- vDate = SF_Utils._CStrToDate(DateArg)
+ If VarType(DateArg) = V_OBJECT Then
+ vDate = CDateFromUnoDateTime(DateArg)
+ Else
+ vDate = SF_Utils._CStrToDate(DateArg)
+ End If
lPart = DatePart(Add, vDate, WeekStart, YearStart)
@@ -297,7 +313,7 @@ Try:
vDate = DateValue(DateArg)
Finally:
- If VarType(vDate) = V_DATE Then PyDateValue = SF_Utils._CDateToIso(vDate) Else PyDateValue = vDate
+ If VarType(vDate) = V_DATE Then PyDateValue = CDateToUnoDateTime(vDate) Else PyDateValue = vDate
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
@@ -329,7 +345,7 @@ Check:
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
Try:
- If VarType(Value) = V_DATE Then vValue = SF_Utils._CStrToDate(Value) ELse vValue = Value
+ If VarType(Value) = V_OBJECT Then vValue = CDateFromUnoDateTime(Value) ELse vValue = Value
If IsEmpty(Pattern) Or Len(Pattern) = 0 Then sFormat = Str(vValue) Else sFormat = Format(vValue, Pattern)
@@ -600,10 +616,9 @@ Check:
vArg = Null
ElseIf vArg = cstSymMissing Then
Exit For &apos; Next arguments must be missing also
- ElseIf ( CallType And cstDateArg ) = cstDateArg Then &apos; Arguments might be dates
- vArg = SF_Utils._CStrToDate(vArg)
- If vArg &lt; 0 Then vArg = Args(i) &apos; Conversion of iso format failed =&gt; reset
End If
+ ElseIf VarType(vArg) = V_OBJECT Then
+ If ( CallType And cstDateArg ) = cstDateArg Then vArg = CDateFromUnoDateTime(vArg)
End If
iNbArgs = iNbArgs + 1
@@ -810,7 +825,7 @@ Try:
End If
Else &apos; Scalar or Nothing
ReDim vReturnArray(0 To 1)
- If VarType(vReturn) = V_DATE Then vReturnArray(0) = SF_Utils._CDateToIso(vReturn) Else vReturnArray(0) = vReturn
+ If VarType(vReturn) = V_DATE Then vReturnArray(0) = CDateToUnoDateTime(vReturn) Else vReturnArray(0) = vReturn
vReturnArray(1) = VarType(vReturn)
End If
diff --git a/wizards/source/scriptforge/python/scriptforge.py b/wizards/source/scriptforge/python/scriptforge.py
index bcd047ba7fa1..6c65f73d00ca 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -57,6 +57,7 @@
import uno
import datetime
+import time
import os
@@ -318,11 +319,8 @@ class ScriptForge(object, metaclass = _Singleton):
if isinstance(returntuple[cstValue], uno.ByteSequence):
return ()
elif returntuple[cstVarType] == ScriptForge.V_DATE:
- dat = None
- try: # Anticipate fromisoformat('00:00:00') and alike
- dat = datetime.datetime.fromisoformat(returntuple[cstValue])
- finally:
- return dat
+ dat = SFScriptForge.SF_Basic.CDateFromUnoDateTime(returntuple[cstValue])
+ return dat
else: # All other scalar values
pass
return returntuple[cstValue]
@@ -562,9 +560,13 @@ class SFServices(object):
Set the given property to a new value in the Basic world
"""
if self.serviceimplementation == 'basic':
+ flag = self.vbLet
if isinstance(value, datetime.datetime):
- value = value.isoformat()
- return self.EXEC(self.objectreference, self.vbLet + self.flgDateArg, propertyname, value)
+ value = SFScriptForge.SF_Basic.CDateToUnoDateTime(value)
+ flag += self.flgDateArg
+ if repr(type(value)) == "<class 'pyuno'>":
+ flag += self.flgUno
+ return self.EXEC(self.objectreference, flag, propertyname, value)
# #####################################################################################################################
@@ -622,6 +624,61 @@ class SFScriptForge:
MB_OK, MB_OKCANCEL, MB_RETRYCANCEL, MB_YESNO, MB_YESNOCANCEL = 0, 1, 5, 4, 3
IDABORT, IDCANCEL, IDIGNORE, IDNO, IDOK, IDRETRY, IDYES = 3, 2, 5, 7, 1, 4, 6
+ @staticmethod
+ def CDateFromUnoDateTime(unodate):
+ """
+ Converts a UNO date/time representation to a datetime.datetime Python native object
+ :param unodate: com.sun.star.util.DateTime, com.sun.star.util.Date or com.sun.star.util.Time
+ :return: the equivalent datetime.datetime
+ """
+ date = datetime.datetime(1899, 12, 30, 0, 0, 0, 0) # Idem as Basic builtin TimeSeria() function
+ datetype = repr(type(unodate))
+ if 'com.sun.star.util.DateTime' in datetype:
+ if 1900 <= unodate.Year <= datetime.MAXYEAR:
+ date = datetime.datetime(unodate.Year, unodate.Month, unodate.Day, unodate.Hours,
+ unodate.Minutes, unodate.Seconds, int(unodate.NanoSeconds / 1000))
+ elif 'com.sun.star.util.Date' in datetype:
+ if 1900 <= unodate.Year <= datetime.MAXYEAR:
+ date = datetime.datetime(unodate.Year, unodate.Month, unodate.Day)
+ elif 'com.sun.star.util.Time' in datetype:
+ date = datetime.datetime(unodate.Hours, unodate.Minutes, unodate.Seconds,
+ int(unodate.NanoSeconds / 1000))
+ else:
+ return unodate # Not recognized as a UNO date structure
+ return date
+
+ @staticmethod
+ def CDateToUnoDateTime(date):
+ """
+ Converts a date representation into the ccom.sun.star.util.DateTime date format
+ Acceptable boundaries: year >= 1900 and <= 32767
+ :param date: datetime.datetime, datetime.date, datetime.time, float (time.time) or time.struct_time
+ :return: a com.sun.star.util.DateTime
+ """
+ unodate = uno.createUnoStruct('com.sun.star.util.DateTime')
+ unodate.Year, unodate.Month, unodate.Day, unodate.Hours, unodate.Minutes, unodate.Seconds, \
+ unodate.NanoSeconds, unodate.IsUTC = \
+ 1899, 12, 30, 0, 0, 0, 0, False # Identical to Basic TimeSerial() function
+
+ if isinstance(date, float):
+ date = time.localtime(date)
+ if isinstance(date, time.struct_time):
+ if 1900 <= date[0] <= 32767:
+ unodate.Year, unodate.Month, unodate.Day, unodate.Hours, unodate.Minutes, unodate.Seconds =\
+ date[0:6]
+ else: # Copy only the time related part
+ unodate.Hours, unodate.Minutes, unodate.Seconds = date[3:3]
+ elif isinstance(date, (datetime.datetime, datetime.date, datetime.time)):
+ if isinstance(date, (datetime.datetime, datetime.date)):
+ if 1900 <= date.year <= 32767:
+ unodate.Year, unodate.Month, unodate.Day = date.year, date.month, date.day
+ if isinstance(date, (datetime.datetime, datetime.time)):
+ unodate.Hours, unodate.Minutes, unodate.Seconds, unodate.NanoSeconds = \
+ date.hour, date.minute, date.second, date.microsecond * 1000
+ else:
+ return date # Not recognized as a date
+ return unodate
+
@classmethod
def ConvertFromUrl(cls, url):
return cls.SIMPLEEXEC(cls.module + '.PyConvertFromUrl', url)
@@ -637,22 +694,22 @@ class SFScriptForge:
@classmethod
def DateAdd(cls, interval, number, date):
if isinstance(date, datetime.datetime):
- date = date.isoformat()
+ date = cls.CDateToUnoDateTime(date)
dateadd = cls.SIMPLEEXEC(cls.module + '.PyDateAdd', interval, number, date)
- return datetime.datetime.fromisoformat(dateadd)
+ return cls.CDateFromUnoDateTime(dateadd)
@classmethod
def DateDiff(cls, interval, date1, date2, firstdayofweek = 1, firstweekofyear = 1):
if isinstance(date1, datetime.datetime):
- date1 = date1.isoformat()
+ date1 = cls.CDateToUnoDateTime(date1)
if isinstance(date2, datetime.datetime):
- date2 = date2.isoformat()
+ date2 = cls.CDateToUnoDateTime(date2)
return cls.SIMPLEEXEC(cls.module + '.PyDateDiff', interval, date1, date2, firstdayofweek, firstweekofyear)
@classmethod
def DatePart(cls, interval, date, firstdayofweek = 1, firstweekofyear = 1):
if isinstance(date, datetime.datetime):
- date = date.isoformat()
+ date = cls.CDateToUnoDateTime(date)
return cls.SIMPLEEXEC(cls.module + '.PyDatePart', interval, date, firstdayofweek, firstweekofyear)
@classmethod
@@ -660,12 +717,12 @@ class SFScriptForge:
if isinstance(string, datetime.datetime):
string = string.isoformat()
datevalue = cls.SIMPLEEXEC(cls.module + '.PyDateValue', string)
- return datetime.datetime.fromisoformat(datevalue)
+ return cls.CDateFromUnoDateTime(datevalue)
@classmethod
def Format(cls, expression, format = ''):
if isinstance(expression, datetime.datetime):
- expression = expression.isoformat()
+ expression = cls.CDateToUnoDateTime(expression)
return cls.SIMPLEEXEC(cls.module + '.PyFormat', expression, format)
@classmethod
@@ -770,30 +827,6 @@ class SFScriptForge:
The resulting array is empty when the dictionary is empty.
"""
- def CDateToUno(date):
- """
- Converts a datetime object into the corresponding com.sun.star.util.x date format
- :param date: datetime.datetime, date or time
- :return: a com.sun.star.util.DateTime, Date or Time
- """
- pvdate = None
- if isinstance(date, datetime.datetime):
- pvdate = uno.createUnoStruct('com.sun.star.util.DateTime')
- elif isinstance(date, datetime.date):
- pvdate = uno.createUnoStruct('com.sun.star.util.Date')
- elif isinstance(date, datetime.time):
- pvdate = uno.createUnoStruct('com.sun.star.util.Time')
- if isinstance(date, (datetime.datetime, datetime.date)):
- pvdate.Year = date.year
- pvdate.Month = date.month
- pvdate.Day = date.day
- if isinstance(date, (datetime.datetime, datetime.time)):
- pvdate.Hours = date.hour
- pvdate.Minutes = date.minute
- pvdate.Seconds = date.second
- pvdate.NanoSeconds = date.microsecond
- return pvdate
-
result = []
for key in iter(self):
value = self[key]
@@ -809,7 +842,7 @@ class SFScriptForge:
value[i] = None
item = value
elif isinstance(value, (datetime.datetime, datetime.date, datetime.time)):
- item = CDateToUno(value)
+ item = SFScriptForge.SF_Basic.CDateToUnoDateTime(value)
pv = uno.createUnoStruct('com.sun.star.beans.PropertyValue')
pv.Name = key
pv.Value = item
@@ -820,6 +853,7 @@ class SFScriptForge:
"""
nserts the contents of an array of PropertyValue objects into the current dictionary.
PropertyValue Names are used as keys in the dictionary, whereas Values contain the corresponding values.
+ Date-type values are converted to datetime.datetime instances.
:param propertyvalues: a list.tuple containing com.sun.star.beans.PropertyValue objects
:param overwrite: When True, entries with same name may exist in the dictionary and their values
are overwritten. When False (default), repeated keys are not overwritten.
@@ -832,11 +866,11 @@ class SFScriptForge:
item = pv.Value
if 'com.sun.star.util.DateTime' in repr(type(item)):
item = datetime.datetime(item.Year, item.Month, item.Day,
- item.Hours, item.Minutes, item.Seconds, item.NanoSeconds)
+ item.Hours, item.Minutes, item.Seconds, int(item.NanoSeconds / 1000))
elif 'com.sun.star.util.Date' in repr(type(item)):
item = datetime.datetime(item.Year, item.Month, item.Day)
elif 'com.sun.star.util.Time' in repr(type(item)):
- item = datetime.datetime(item.Hours, item.Minutes, item.Seconds, item.NanoSeconds)
+ item = datetime.datetime(item.Hours, item.Minutes, item.Seconds, int(item.NanoSeconds / 1000))
result.append((key, item))
self.update(result)
return True