DateTime parsing in PowerShell - datetime

I'm trying to write a PowerShell script that will generate a table of information with two columns: a name, and a date (which will be retrieved from a third-party application - in this case svn.exe).
The overall script works well, but I'm struggling to get the date that the server sends back into the DataTable. Here's a simplified version of my script:
# Set up a DataTable and initialise columns
$table = New-Object system.Data.DataTable “Test Table”
$col1 = New-Object system.Data.DataColumn Name,([string])
$col2 = New-Object system.Data.DataColumn DateFromServer,([DateTime])
$table.columns.add($col1)
$table.columns.add($col2)
# Create a new row and add the data
$row = $table.NewRow()
$row.Name = "Test"
$lastCommit = GetDateFromExternalApp
$lastCommit.GetType() # this returns DateTime as I would expect
$row.DateFromServer = $lastCommit # this throws up an error
$table.Rows.Add($row)
# Output the table
$table | Format-Table -AutoSize
# This function simulates what the actual function does
# (the real one goes to SVN and pulls down data, but it
# ends up with the same resulting date)
Function GetDateFromExternalApp
{
$externalAppDate = "2012-09-17T16:33:57.177516Z"
return [DateTime]($externalAppDate)
}
The problem (noted in comments in the script above) is that while the function seems to be happily returning a DateTime instance, when I try to add this into the table row's DateFromServer column it's throwing up an error:
Exception setting "DateFromServer": "Unable to cast object of type 'System.Management.Automation.PSObject' to type 'System.IConvertible'.Couldn't store <18/09/2012 2:33:57 AM> in DateFromServer Column. Expected type is DateTime." At line:13 char:6
+ $row. <<<< DateFromServer = $lastCommit
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
However, the call to $lastCommit.GetType() shows that this is indeed a DateTime - and in fact if I add this line somewhere in the script:
$lastCommit
then I can see a nicely formatted datetime, suggesting that it is indeed parsing it and converting it correctly:
Date : 18/09/2012 12:00:00 AM
Day : 18
DayOfWeek : Tuesday
DayOfYear : 262
Hour : 2
Kind : Local
Millisecond : 177
Minute : 33
Month : 9
Second : 57
Ticks : 634835324371775160
TimeOfDay : 02:33:57.1775160
Year : 2012
DateTime : Tuesday, 18 September 2012 2:33:57 AM
As such I'm quite puzzled as to why I'm getting the exception above. I realise that PowerShell does function return values differently than C#, but it looks to me like the function is returning the right type!

The issue here is due to a bug in PowerShell's type adaptation system (I would recommend reporting this to Microsoft if you have not already done so).
When you work with objects in PowerShell, you are actually working with a PSObject wrapper. Most calls (like GetType) are forwarded to the underlying object, though you can add additional members that do not interact with the object itself:
PS> Get-Date | Add-Member NoteProperty Yowza 'for example' -PassThru | Format-List y*
Yowza : for example
Year : 2012
Normally this is not an issue, as PowerShell has extensive type coercion capabilities. In the case of DataRow however, there appears to be a bug with the DataRowAdapter type used to support the property access syntax. If you use the indexer directly, $row['DateFromServer'] = $lastCommit instead of $row.DateFromServer, the value is correctly unwrapped before it is sent to the .NET type.
You can also get around this by unwrapping the value yourself, either using a cast (as vonPryz already showed: [DateTime]$lastCommit), or by retrieving the BaseObject ($lastCommit.PSObject.BaseObject).

I'd like to know the reason for this behaviour too.
Anyway, you can work around the problem by casting the date variable as DateTime or by explicitly declaring it to be one. Like so,
...
$row.DateFromServer = [DateTime]$lastCommit # Doesn't throw exception
...
Or
...
[DateTime]$lastCommit = GetDateFromExternalApp
$row.DateFromServer = $lastCommit # Doesn't throw exception
...

I suspect the reason is as stated in the error message:
"Unable to cast object of type 'System.Management.Automation.PSObject' to type 'System.IConvertible'...Expected type is DateTime." At line:13 char:6
What that is saying is that PowerShell tried to convert $lastCommit into a date and time but failed. The best way is, as vonPryz suggests - cast it to [datetime]
To see the issue more clearly, try looking at the both:
$lastcommit.gettype() and
$row.DateFromServer.gettype()
I don't have the GetDateFromExternalApp to check

Related

LibreOffice CALC macro Hex2Bin and Bin2Hex functions

can anybody help me with solving my problem of Hex2Bin and Bin2Hex functions?
First I was trying to make the conversion Hex2Bin. I would like to call the AddIn function from macro so I called createUNOservice:
Function fcHex2Bin(arg as variant, NumberOfBits As integer) as string
Dim oService as Object
oService = createUNOService("com.sun.star.sheet.addin.Analysis")
sArg = cStr(arg)
fcHex2Bin = oService.getHex2Bin(sArg,NumberOfBits)
End Function
but all the time ends with fault message like "The object variable is not set.". I already don't know why.
My final goal would be to make all functions of Calc running in macros, but at this moment I would be glad to have two functions Hex2Bin and Bin2Hex running - anyhow.
My LibreOffice version:
Version: 7.1.3.2 (x64) / LibreOffice Community
Build ID: 47f78053abe362b9384784d31a6e56f8511eb1c1
CPU threads: 8; OS: Windows 10.0 Build 19042; UI render: Skia/Raster; VCL: win
Locale: cs-CZ (cs_CZ); UI: cs-CZ
Calc: CL
Thank you for your help.
This way works.
Function fcHex2Bin(aNum As String, rPlaces As Any) As String
Dim oFunc As Object
oFunc = CreateUnoService("com.sun.star.sheet.FunctionAccess")
Dim aArgs(0 to 1) As Variant
aArgs(0) = aNum
aArgs(1) = rPlaces
fcHex2Bin = oFunc.callFunction("com.sun.star.sheet.addin.Analysis.getHex2Bin", aArgs())
End Function
As for why the other way does not work, many analysis functions require a hidden XPropertySet object as the first argument. The following code produces informative error messages:
REM IllegalArgumentException: expected 3 arguments, got 1
sResult = oService.getHex2Bin(ThisComponent.getPropertySetInfo())
REM IllegalArgumentException: arg no. 0 expected: "com.sun.star.beans.XPropertySet"
sResult = oService.getHex2Bin(ThisComponent.getPropertySetInfo(), "2", 4)
However I tried passing ThisComponent.getPropertySetInfo().getProperties() from a Calc spreadsheet and it still didn't work, so I'm not exactly sure what is required to do it that way.
The documentation at https://help.libreoffice.org/latest/he/text/sbasic/shared/calc_functions.html does not really explain this. You could file a bug report about missing documentation, perhaps related to https://bugs.documentfoundation.org/show_bug.cgi?id=134032.

Changing the Session Languge leads to "java.text.ParseException: Unparseable date

whenever I'm defining the timeframe being in German session language after changing to English lang. session (and vice versa) I'm getting the:
java.text.ParseException: Unparseable date: "10.10.2018"
Here is the fragment:
Date startDateFormatted = DateUtils.convertDateToMinusDayNumber(cal, dayRange);
Date endDateFormatted = new Date();
if (StringUtils.isNotEmpty(startDate) && StringUtils.isNotEmpty(endDate))
{
try
{
String datePattern = getLocalizedString("dd.MM.yyyy"); //
startDateFormatted = new SimpleDateFormat(datePattern).parse(startDate); // exception is throwing on this line
endDateFormatted = new SimpleDateFormat(datePattern).parse(endDate);
}
catch (final Exception e)
{
LOG.error(ERROR_DATE_PARSING, e);
}
}
java.time
I recommend you use java.time, the modern Java date and time API, for your date work.
String datePattern = "dd.MM.uuuu";
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(datePattern);
String startDateString = "10.10.2018";
LocalDate startDate = LocalDate.parse(startDateString, dateFormatter);
System.out.println(startDate);
Output:
2018-10-10
If you want to support different date formats for different locales, let Java handle that part for you:
String datePattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.MEDIUM, null, IsoChronology.INSTANCE, Locale.GERMAN);
German locale works with your example string of 10.10.2018. For UK locale, for example, a string like 10 Oct 2018 would be required instead, as Britons would typically expect.
What went wrong in your code?
We cannot tell from the information and code that you have provided exactly what happened. A couple of good guesses are:
As Arvind Kumar Avinash said in a comment, getLocalizedString() may be causing trouble. You may print datePattern to check. Localization is something you do to strings that you display to the user. Trying to localize a format pattern string for a formatter is probably plain wrong, so you should leave out that method call. That the error occurs when changing language seems to support this possibility.
There may be unexpected non-printing characters in your string. One way to check would be to print startDate.length(). If the length is greater than 10, there are more characters than the 10 chars in 10.10.2018.
Link
Oracle tutorial: Date Time explaining how to use java.time.

How to process a query before sending to Jinja2 template? App Engine

I'm stuck with how to process the results of a query before sending it to Jinja2 for rendering on the browser.
I'm developing the app on Google App Engine for Python.
I store the amount of working hours in a "calendar" entity as amount of seconds, this will then allow me to make a number of calculations about time. The problem I have is how to modify the result of the query, so that I pass to the Jinja2 html file the time not in seconds (Integer) but as HH:MM (String)
My models.py file is as follows:
'calendars_list': calendars_list,
class Calendar(ndb.Model):
wtd1 = ndb.IntegerProperty() # Working seconds day 1
wtd2 = ndb.IntegerProperty() # " 2
wtd3 = ndb.IntegerProperty() # " 3
wtd4 = ndb.IntegerProperty() # " 4
wtd5 = ndb.IntegerProperty() # " 5
wtd6 = ndb.IntegerProperty() # " 6
wtd7 = ndb.IntegerProperty() # " 7
In the main request handler I get the query (after defining ancestor etc) and need to change the seconds to HH:MM before rendering in the browser.
calendars_query = models.Calendar.query(ancestor = get_calendars_key()).order(models.Calendar.calendar_id)
calendars_list = calendars_query.fetch(10)
# Now: convert working times per day (sec) to HH:MM
for calendar in calendars_list:
calendar.wtd1 = format_as_HHMM(calendar.wtd1)
--> Gives an error: calendar.wtd1 needs to be an integer, can't be a string
template_values = {
'calendars_list': calendars_list,
}
template = JINJA_ENVIRONMENT.get_template('calendars.html')
self.response.write(template.render(template_values))
As shown above, when I modify the calendar.wtd1 element to change it from say 3600 to 01:00 I get an error because it needs to be an integer.
Any ideas how I can change the code so that I can process the query results appropriately?
Thanks!
The issue with your code is that you try to assign a value that is not an integer to a ndb.IntegerProperty().
Replace
calendar.wtd1 = format_as_HHMM(calendar.wtd1)
with
calendar.wtd1_HHMM = format_as_HHMM(calendar.wtd1)
and use calendar.wtd1_HHMM in the template and it will probably work out nicely.
Edit:
If you prefer to convert from integer to HH:mm in the template as part of the presentation logic you could do that easily by writing the conversion function and register it as a filter as explained in the documentation - writing filters
When it comes to functions for doing the conversion you are in luck:
Python: convert seconds to hh:mm:ss

XPages sessionScope variable and DateTime values

I seem to be losing the value of sessionScope variables between XPages when I load DateTime values from a Notes document (not from the XPage). Here is what I do:
I have an EditBox where the contents are set to type Date only:
<xp:inputText value="#{document1.datum}" id="datum" defaultValue="#{javascript:#Now()}" required="true">
<xp:this.converter>
<xp:convertDateTime type="date"></xp:convertDateTime>
</xp:this.converter>
<xp:dateTimeHelper></xp:dateTimeHelper>
</xp:inputText>
I then save this to a sessionScope variable :
sessionScope.put ("datum", getComponent("datum").getValue());
Then I change XPages by doing a:
var extCont = facesContext.getExternalContext();
extCont.redirect("xpNextPage.xsp")
I then do a sessionScope.get:
print (sessionScope.get ("datum"));
And the contents are fine.
if I do the same thing with a document that I have loaded:
var date:NotesDateTime = doc.getItemValueDateTimeArray("datum");
var start:NotesDateTime = doc.getItemValueDateTimeArray("von");
var dt:NotesDateTime = session.createDateTime (date [0].getDateOnly() + " " + start [0].getTimeOnly());
sessionScope.put ("datum", dt);
then switch to the next page and try and load it with:
print (sessionScope.get ("datum"));
I get a value null.
I have attached a screenshot of the problem (I printed other fields as well so you can see it is only the DateTime fields that are the problem). I do notice that the format of the DateTime value is different... could this be the problem?
NotesDataTime is not serializable, so you cannot store it in the memory. When you use getComponent("datum").getValue(), it returns you Java Date not NotesDataTime. Java date is serializable, so its working.
Try convert your NotesDataTime to Java Date.
dt.toJavaDate()

asp ERROR MESSAGE

How I can solve this error message
Microsoft VBScript runtime error
'800a01a8' Object required: 'lUATRef'
/cmgtest/transaction/viewPCReqForm.asp,
line 284
this is some source code that I wrote below
function checkUATReq(aUATRef)
Dim correctness,lUATRef,uatRef
correctness = False
lUATRef = aUATRef
uatRef = lUATRef.Substring(1,2)
rwriteln uatRef
'sqlCheckUATReq = "select * from PC_DETAIL where ID ='"&uatReqRef&"'"
'rwriteln uatReqRef
End function
Seems like your function isn't getting a parameter passed to it. Check whether aUATRef is getting initialized.
In VBScript, Strings aren't objects. You should use the Mid function to get a portion of a string:
uatRef = Mid(IUATRef, 1, 2)

Resources