I'm a little puzzled by how PowerShell treats a string that represents a DateTime when it comes down to parameters. My Script has a parameter definition as follows:
[CmdletBinding(DefaultParameterSetName='Kunde')]
param(
[Parameter(Mandatory=$true, ParameterSetName='Kunde')]
[string]$KdNr,
[Parameter(Mandatory=$true, ParameterSetName='Kunde')]
[DateTime]$von,
[Parameter(Mandatory=$true, ParameterSetName='Kunde')]
[DateTime]$bis,
[Parameter(Mandatory=$true, ParameterSetName='Kunde')]
[string]$Empfaenger
)
I want to enter the following date: 1. April 2016 as my locale string 01.04.2016. Now PowerShell does something that is unexpected (at least to me):
I enter the string 01.04.2016 at the command prompt when PowerShell queries the missing mandatory parameter. Then it gets parsed to 1. April 2016.
I enter the same string 01.04.2016 directly at the commandline like this ZippenUndMailen.ps1 -von '01.04.2016' and now PowerShell parses the string using the US notation as January 4th 2016.
I've got two questions:
Why does PowerShell parse the strings differently?
How do I best remedy that behaviour? The Script should be reused and called both manually and via TaskScheduler and this behaviour is rather counter intuitive.
I can't reproduce it too, despite my current culture being different from en-us.
Try removing [DateTime] cast from your parameter definition (set it to [Parameter(Mandatory=$true, ParameterSetName='Kunde')]$von) and use $von = [DateTime]::Parse($von, (Get-Culture)) in your code to force PS to use your current culture.
More info:
To prevent subtle internationalization issues from popping into your
scripts, PowerShell treats [DateTime] '11/26/2007' (a date constant)
like a language feature – just as it does [Double] 10.5 (a numeric
constant.) Not all cultures use the decimal point as the fractions
separator, but programming languages standardize on it. Not all
cultures use the en-US DateTime format, resulting in millions of
internationalization bugs when people don’t consider the impact of
having their software run in those cultures.
Adwaenyth, I can't replicate the differing time resolution you are seeing but it is most likely a culture issue... see this question regarding using culture in Powershell How to set culture in PowerShell?
Related
I have a program that generates random pin codes. These pins are generated in Java, then stored in the mainframe, via a NATURAL program. From there, they are eventually physically printed by a batch JCL job that calls an MVS SCRIPT to print the form, with the pin code on it.
I've come across some issues with special characters before such as: |{}![]^~<>; that for one reason or another do not print properly. I've also removed 0OQ1l for OCR reasons.
Recently, an error came to my attention with another character that doesn't print properly, . but the . character only fails when it is the first character of the PIN Code.
So since I've run into this issue I thought I would see if I could find other special jcl, Natural or MVS Script characters that might interfere with my programs operation so that I can test them now and hopefully not run into this issue later or have to fallback to only using OCR'ed AlphaNumeric characters.
EDIT
Java - Web Application Runs Under Tomcat 6.x on a Solaris Server.
Natural - The Natural Program is called using webmethods Broker generated classes (POJOs).
My understanding is it uses RPC for actual communication.
The program verifies some data and stores the Pin in combination with a GUID on a record, in ADABAS.
There is a batch job that runs to print the forms. The Batch job is written in JCL.
My Understanding from the maintainer of the Batch Job, and the Forms stuff is the actual language to describe the forms themselves and how they get printed is an outdated/unsupported language called MVS SCRIPT.
the Bottom section of the script looks like this:
//**********************************************************************
//* PRINT SORTED FORMS TO #### USING MVS SCRIPT
//**********************************************************************
PRINTALL EXEC PGM=DSMSPEXEC,PARM='LIST'
//* less 'interesting' lines omitted
SYSPRINT DD SYSOUT=*
PRINT1 DD SYSOUT=A, OUTPUT=*.C####,
RECFM=VBM,LRECL=####,BLKSIZE=####
//* less 'interesting' lines omitted
//SYSIN DD *
AUTH /* redacted */
SCRIPT FROM(MYFORMS) (MESSAGE(ID TRACE) CONT -
FILE(PRINT1) PROFILE(redacted) -
NOSEGLIB DEVICE(PG4A) CHARS(X0A055BC))
.C#### is an actual number and is a variable that points to the chosen printer.
NOTE: I'm a Web Programmer, I don't speak mainframe, JCL, MVS, etc.
I think you will find the program (pgm=) is DSMSPEXC and not DSMSPEXEC.
I am guessing (could be wrong) we are talking about Script/DCF (which later became IBM Bookmaster / Bookmanager on other platforms).
Script/DCF is basically a GML based language. It was from GML that SGML was derived (HTML and XML are prominent examples of SGML languages).
In Script : starts a tag, . ends a tag. There are also macro's which have a . in column 1
.* ".*" in column 1 starts a line comment
.* .fo off is Format off (like <pre> in html)
.fo off
.* Starting an ordered list
:ol.
:li.Item in orded list
:eol.
i.e.
Script HTML
: < - Starts tag
. > - end of tag Script/DCF is generally pretty tolerant of .
& & - Starts a variable
There are variables (&gml. = :) for most of the special characters.
Characters to worry about are
: - always
& - always
. - in column one or after a :.
Other characters should be ok provided there are no translation errors. There charset X0A055BC (Mainframe SONORAN SANS SERIF ??) might not have all the special chars in it.
There are manuals around for Script/DCF tags.
Your data is not going to affect the JCL in any way.
I don't know about ADABAS or NATURAL. If you ask here, http://www.ibmmainframeforum.com/viewforum.php?f=25, specifically about that part, with as much detail as you can provide, there is a very expert guy, RDZbrog, who can probably answer that for you.
For the SCRIPT/VS itself, as Bruce Martin has pointed out, there may be some issues. With .xx and :xx there is not a clash with normal text. But you don't have normal text. With the &, which indicates a SCRIPT variable, it is more likely to be problematic and at any location.
I would fire some test data through: Your PINs with position one being all available punctuation preceding "fo" and "ol", and the same with those sequences "embedded" in your PINs. Also include a double & and a triple &.
Your query should be resolved in your specification. It is not, but I'm sure you'll get all the documentation updated when you get a resolution.
I format dates with the command line option -f %Y-%m-%d or even %d-%b-%y
but each date comes out four years and one day ahead of the date I input
for example, date 01.06.2012 after parsing without -f option comes as 2016-06-02
toying with -f gives same result
What is the reason? Are there any workarounds,
except hardcode and substract back these 4 years and 1 day?
I am using xls2csv (by V.B.Wagner, comes with catdoc package in debian)
and switching to another parser can be very expensive option
Tools xls2csv is a Perl application that uses Spreadsheet::ParseExcel library.
Based on such library documentation, one of known problems is:
If Excel has date fields where the specified format is equal to the system-default for the short-date locale, Excel does not store the format, but defaults to an internal format which is system dependent. In these cases ParseExcel uses the date format 'yyyy-mm-dd'.
So you probably manipulate with Excel file that does not contain date formating due to above listed issue.
That's a known bug. A patch is available at
https://www.wagner.pp.ru/cgi-bin/cvstrac/catdoc/tktview?tn=14,4
It works.
By the way, there are two programs called xls2csv, we're talking about the one from the catdoc package, not the Perl program.
I'm having a strange problem that is affecting at least some of my international users of my Delphi 6 application. Here's the scenario:
My program requests status reports periodically from an external device that acts as an HTTP server.
The device sends back the status report as a response document that has a series fields delimited with the pipe character in name value pair format (e.g. - field1=-0.437).
I split the report string into the fields and then again to get each field name and numeric value.
I use StrToFloat() to convert the floating point field values in string format and assign the result of that function to a Variant variable.
This works fine on most PCs, but some of my international users are getting EConvertError's when I try to use StrToFloat() on the numeric values. Here's a concrete example of an error message from my logs:
EConvertError: '-0.685' is not a valid floating point value
As you can see -0.685 is a valid floating point number, yet I am getting the EConvertError Exception. Normally I would expect to see a comma where the decimal point is, or some other locale specific punctuation problem, but the number appears fine in this case. Also, to the best of my knowledge the external device does not even have the option to set the character set.
So what subtle nuance about Delphi 6 and international character sets might be causing this problem, perhaps related to the user's Windows XP/Win7 character settings? Note, I use standard Delphi 6 "string" cast strings throughout my program so I don't see how a multi-byte character set issue could be the root cause. Has anyone had this problem and knows what to do about it?
Your remote user's machine is expecting , for the decimal separator. When it encounters . the EConvertError exception is raised. On a machine which expects , as the decimal separator (e.g. most European and South American countries) -0.685 is indeed not a valid floating point value.
Normally I would expect to see a comma where the decimal point is, or some other locale specific punctuation problem, but the number appears fine in this case.
Your current problem is just the flip-side of the above issue. Normally, because your locale uses . as the separator, you are accustomed to seeing problems when data with , is used instead. Put yourselves in the position of somebody from a country which uses , as a separator. For them, they will be accustomed to seeing exceptions when data with . is used.
You could solve the problem by normalising the input to use the same decimal separator as the the machine locale. On a modern Delphi you could solve the problem by use the StrToFloat overload that receives a TFormatSettings parameter and explicitly specify that . is to be used as the decimal separator for this conversion. Unfortunately that facility is not available in Delphi 6.
I faced this issue for Belgian users. I also had to manually replace the '.' or ',' in the input data.
Also, if you are inserting the data into the database (sql) then, you will have to replace the ',' with '.' during insertion of the data into the database.
I'm working with a Crystal Reports export with different localization. For this example, I'm trying to set the localization to French which uses Euros.
I set the localization with the following C# code:
ReportDocument report = new ReportDocument();
report.ReportClientDocument.LocaleID = CrystalDecisions.ReportAppServer.DataDefModel.CeLocale.ceLocaleFrench;
report.ReportClientDocument.PreferredViewingLocaleID = CrystalDecisions.ReportAppServer.DataDefModel.CeLocale.ceLocaleFrench;
report.ReportClientDocument.ProductLocaleID = CrystalDecisions.ReportAppServer.DataDefModel.CeLocale.ceLocaleFrench;
When I export the report the following value is displayed:
135,00 $
Notice that the format of the number changed correctly, but the currency symbol didn't.
I've been searching for a solution but pretty much everything focuses on changing the currency at design time, but I need to be able to change it at run time depending on some other values that the user selects.
I've seen some hints around using parameters to pass in a value and using a formula in the designer but I'm not familiar enough with Crystal Reports to figure it out.
I'm using Crystal Reports 10.5 with Visual Studio 2010 and .Net 3.5.
Any help or tips is appreciated.
I figured it out and based on the research that I've done I think that this is the only way to do it.
I'm pretty sure that the symbol doesn't change on purpose. Following the logic that a report is used for only one type of currency, even though the format will change with culture, the actual currency value is the same. $100 is always a $100 no matter what language the report is viewed in and this way, the report doesn't have to worry about converting the data to different amount.
In my application, the data is stored as just a number and the currency is determined by other values in the database and the code.
But to get to the point, I specified the locale of the report based on the code in my question. Then to change the currency, symbol I had to go into the report designer and format the currency questions.
In the 'Number' tab of the Format Editor, make sure the 'Display Currency Symbol' box is checked. Then click on the 'Customize' button and the 'Currency Symbol' tab. Go to the Formula Workshop for the currency symbol and then put in the following code:
Local StringVar locale := LowerCase(ContentLocale);
if locale = "fr_fr" then
"€"
else if (locale = "en_gb") then
"£"
else if(locale = "en_us" OR locale = "en_ca") then
"$"
else
""
This is just an example of the languages that I'm supporting but right now, but I think it gets the point across. Also note that Crystal uses underscores in the locale IDs instead of hyphens.
Kind of a log winded answer but hopefully this will help someone else.
I'm writing a Fitnesse test for a web application. One of the items to test is a drop-down box, whose value is determined by the current date, in DD/MM/YYYY format.
I'd thought that using the !today variable in the Fitnesse suite might be a useful way of setting a variable, but I've run into the problem that Fitnesse expresses the date as (for example) 11 Mar, 2011, where I need 11/03/2011. I can get the date in numberic format using the -xml modifier, but I'm still left with a pretty huge string like 2011-03-11T05:51:22.
Is there a way of getting substrings of this, and then piping those into page variables, or am I barking up entirely the wrong tree here?
Thanks!
!today (MM/dd/yyyy) produces 09/17/2012. You can use any format codes you like. It uses the SimpleDateFormat class.
Well, it turns out not entirely the wrong tree :-)
For reference, the !today function has a few other methods, and you can use them to gather individual sections of the date as necessary:
!today (dd) - gives the day of the month, in numeric form
!today (MM) - gives the month of the year, in numeric form
!today (yyyy) - gives the year, in numeric form
There are a few others, but all I ended up using were these. Combine them as necessary, and Robert is your mother's brother, as it were...
This will get you the date you require in Test Cases written in Fitnesse Wiki
${=!today (ddMMyyyy)=}
The ! (Exclamation mark) is interpreted literally, so symbols like !today are not expanded. You can use a plain table:
|class name|
|!today (MM/dd/yyyy)|