lazarus/pascal write filename with current date - pascal

i need to write a file with the filename containing the current date.. everything works besides the date, it gives a class exception 'run error(3)'
(the importo.text is the text of a TEdit.. but i guess it's irrelevant)
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
...
var
contributo:real;
f:textfile;
...
datee: string;
...
contributo:= (StrToInt(importo.text)/ 100)*4;
datee:= DateToStr(Date);
assignfile(f,'fattura minimi n.'+n.text+' '+datee+'.txt');
rewrite(f);
writeln(f,'Giovanna Migliore');
...
closefile(f);

DateToStr() will return the date formatted according to regional settings. In your case this is almost certainly returning a folder/path delimiter character (/ or \) which is causing the problem (path not found).
Even if you change your regional settings to avoid using such characters, the code will still fail on other systems if those regional settings are not "compatible". To avoid this you need to ensure that your encoding of the date in the filename is not sensitive to such potential problems.
You could remove/replace any such characters after forming the filename, or you could explicitly encode the date in a manner that will not introduce such characters to start with, similar to:
var
y, m, d: Word;
..
DecodeDate(Date, y, m, d);
dateStr := Format('%4d-%2d-%2d', [y, m, d]);
// e.g. dateStr value for 31st Dec 2016 would be: '2016-12-31'
You could then incorporate the date component values in your filename either by concatenation as required, or directly in a single format statement:
filename := Format('fattura minimi n.%s %4d-%2d-%2d.txt [n.text, y, m, d]);
assignfile(f, filename);

Related

Adding leading Zeros into Day and Month Value

I have a simple table that has a column with a date in this format:
MM/DD/YYYY.
Unfortunately, there are some folks who are working without leading zeros.
Therefore I would like to add a leading zero into the Month and Day element using Power Query to have a common format.
But how? Does someone have any function to share?
Again, not sure why you want to do this, but
Assuming all of the entries are text that looks like dates, you can use the following M-Code:
Split the string on the delimiter
Change each entry in the list to a number
Add 2000 to the last number
Change the numbers back to text with a "00" format
Recombine with the delimiter
let
Source = Excel.CurrentWorkbook(){[Name="Table29"]}[Content],
//set type = Text
#"Changed Type" = Table.TransformColumnTypes(Source,{{"TextDate", type text}}),
xform = Table.TransformColumns(#"Changed Type",
{"TextDate", each
let
x = Text.Split(_,"/"),
y = List.Transform(x,each Number.From(_)),
z = List.ReplaceRange(y,2,1, {2000+y{2}}),
a= List.Transform(z,each Number.ToText(_,"00")),
b = Text.Combine(a,"/")
in b})
in
xform
I am thinking a better solution might be to set up your data entry method so that all dates are entered as dates rather than text

JDBC Import into sheets, how to keep leading zeros on fields?

I have so much trouble with leading zeros in general. Importing into Sheets using JDBC connection, I haven't figured out a way to keep the zeros. The column types are varchar() for values of varied length, and char() for static length.
In the past with other data I have added a leading ' to values, or chosen to getDisplayValue() to keep them. What would work here?
while (results.next()){
var tmpArr = [];
var rowString = '';
for (var col = 0; col < numCols; col++) {
rowString += results.getString(col + 1) + '\t';
tmpArr.push(results.getString(col + 1));
}
valArr.push(tmpArr);
}
sheet.getRange(3, 1 , valArr.length, numCols).setValues(valArr);
Data Exmaple varchar column:
0110205361
0201206352
140875852
LFCP01367
LGLM00017
You are retrieving data into a Google Sheet from a MySQL database table using Jdbc. One of the database columns is formatted as "varchar" and includes some all-numeric values that have one or more leading zeros. When you update the database values to your Google Sheet, the leading zeros are not displayed.
Why
The reason for this is that the all-numeric values are displayed without the leading zeros is that the cells are formatted as Number, Automatic (or otherwise as a number). This means that they are 'interpreted' by Google Sheets as a number and, by default, all leading zeros are dropped.
On the other hand, if the cells are formatted as Number, Plain Text, then the all-numeric values are 'interpreted' as strings, and any leading zeros are retained.
The effect of formatting can be clearly seen in the following images, which also include istext and isnumber formula to confirm how they are interpreted under each format type.
Formatted as Number - Plain Text - treated as strings
Formatted as Number - Automatic - treated as numbers
Formatting on the fly
An alternative to pre-formatting (which wasn't successful in the OP's case) is to set the format as a part of the setValues() method using setNumberFormat
For example:
sheet.getRange(3, 1 , valArr.length, numCols).setNumberFormat('#STRING#').setValues(valArr);
There is a useful discussion of this methid in Format a Google Sheets cell in plaintext via Apps Script

ISO 8601 date-time format combining 'Z' and offset of '+0000'

I'm playing with date-time format from ISO 8601. I have this pattern:
"yyyy-MM-dd'T'HH:mm:ssZZ'Z'"
and the output is:
"2015-11-17T00:00:00+0000Z"
My question is if the output is ok, if is possible to have in a date +0000 and Z taking in account both has the same meaning time zone offset/id. Thanks in advance for clarification =)
No, not OK
No, the Z is an offset-from-UTC so it should not be combined redundantly with a numerical offset of +00:00 or +0000.
ISO 8601
While I do not have access to a paid copy of the ISO 8601 spec, the Wikipedia page clearly states that the Z must follow the time-of-day:
…add a Z directly after the time without a space.
IETF RFC 3339
The freely-available RFC 3339, a profile of ISO 8601, defines a Z as being attached to a time-of-day:
A suffix … applied to a time …
The RFC also states with formal ABNF notation that we should use either a Z or a number. In ABNF, the slash (SOLIDUS) means “or” (exclusive ‘or’), while the pair of square brackets means “optional”.
time-numoffset = ("+" / "-") time-hour [[":"] time-minute]
time-zone = "Z" / time-numoffset
Furthermore, section 5.4 of the spec specifically recommends against including redundant information.
Java
The modern java.time classes built into Java use the standard ISO 8601 formats by default when parsing/generating strings. See Oracle Tutorial.
Parsing text input
With Z:
Instant instant = Instant.parse( "2019-01-23T12:34:56.123456789Z" ) ;
With +00:00:
OffsetDateTime odt = OffsetDateTime.parse( "2019-01-23T12:34:56.123456789+00:00" ) ;
Generating text output
To create a string with the Z, simply call Instant::toString.
String output = Instant.now().toString() ; // Capture the current moment in UTC, then generate text representing that value in standard ISO 8601 using the `Z` offset-indicator.
2019-05-22T21:00:52.214709Z
To create a string with the 00:00, call OffsetDateTime::format. Generate text using a DateTimeFormatter with a formatting pattern you define.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSxxx" ) ;
String output = OffsetDateTime.now( ZoneOffset.UTC ).format( f ) ;
2019-05-22T21:00:52.319076+00:00
Truncating
You may want to truncate any microseconds or nanoseconds.
Instant
.now()
.truncatedTo( ChronoUnit.MILLIS )
.toString()
2019-05-22T21:11:28.970Z
…and…
OffsetDateTime
.now( ZoneOffset.UTC )
.truncatedTo( ChronoUnit.MILLIS )
.format(
DateTimeFormatter.ofPattern( "uuuu-MM-dd'T'HH:mm:ss.SSSxxx" )
)
2019-05-22T21:11:29.078+00:00
See this code running live at IdeOne.com.

Visual Works smalltalk, how to convert Ascii values to characters

using visualworks, in small talk, I'm receiving a string like '31323334' from a network connection.
I need a string that reads '1234' so I need a way of extracting two characters at a time, converting them to what they represent in ascii, and then building a string of them...
Is there a way to do so?
EDIT(7/24): for some reason many of you are assuming I will only be working with numbers and could just truncate 3s or read every other char. This is not the case, examples of strings read could include any keys on the US standard keyboard (a-z, A-Z,0-9,punctuation/annotation such as {}*&^%$...)
Following along the lines of what Max started to suggest:
x := '31323334'.
in := ReadStream on: x.
out := WriteStream on: String new.
[ in atEnd ] whileFalse: [ out nextPut: (in next digitValue * 16 + (in next digitValue)) asCharacter ].
newX := out contents.
newX will have the result '1234'. Or, if you start with:
x := '454647'
You will get a result of 'EFG'.
Note that digitValue might only recognize upper case hex digits, so an asUppercase may be needed on the string before processing.
There is usually a #fold: or #reduce: method that will let you do that. In Pharo there's also a message #allPairsDo: and #groupsOf:atATimeCollect:. Using one of these methods you could do:
| collectionOfBytes |
collectionOfBytes := '9798'
groupsOf: 2
atATimeCollect: [ :group |
(group first digitValue * 10) + (group second digitValue) ].
collectionOfBytes asByteArray asString "--> 'ab'"
The #digitValue message in Pharo simply returns the value of the digit for numerical characters.
If you're receiving the data on a stream you could replace #groupsOf:atATime: with a loop (result may be any collection that you then convert to a string like above):
...
[ stream atEnd ] whileFalse: [
result add: (stream next digitValue * 10) + (stream next digitValue) ]
...
in Smalltalk/X, there is a method called "fromHexBytes:" which the ByteArray class understands. I am not sure, but think that something similar exists in other ST dialects.
If present, you can solve this with:
(ByteArray fromHexString:'68656C6C6F31323334') asString
and the reverse would be:
'hello1234' asByteArray hexPrintString
Another possible solution is to read the string as a hex number,
fetch the digitBytes (which should give you a byte array) and then convert that to a string.
I.e.
(Integer readFrom:'68656C6C6F31323334' radix:16)
digitBytes asString
One problem with that is that I am not sure about which byte-order you will get the digitBytes (LSB or MSB), and if that is defined to be the same across architectures or converted at image loading time to use the native order. So it may be required to reverse the string at the end (to be portable, it may even be required to reverse it conditionally, depending on the endianess of the system.
I cannot test this on VisualWorks, but I assume it should work fine there, too.

Suppressing a trailing "." in numerical output from Mathematica

Is there some straightforward way to ensure that, when converted to strings, approximate numbers (i.e., numbers with the Real head) won't have a trailing "."? I would like it if they were to only have the decimal point in cases where there's actually a displayed fractional part.
The solutions I've found are not robust, and depend on using Precision and Accuracy together NumberForm in an awkward way, or using RealDigits in an even more awkward way.
Thanks in advance.
I've used this in the past when displaying numbers in figures:
Integerise[x_] := If[Round[x] == x, ToString[Round#x] <> ".0", ToString#x]
Just remove <> ".0" if you don't want integers to be displayed with a zero decimal.
Update: As mentioned by dreeves in the comment, ToString will still truncate a number within 0.0001 or so of an integer and display the dot.
A better way to remove the trailing dot is to use the Inputform format for ToString:
NormalNumber[x_] := ToString[x, InputForm]
with a test:
NormalNumber /# {5, 5.5, 123.001, 123.0001}
This could be incorporated into Integerise above to fix the problem noted.
I recommend this:
shownum[x_] := StringReplace[ToString#NumberForm[x, ExponentFunction->(Null&)],
RegularExpression["\\.$"]->""]
It just does a regex search&replace on the trailing ".". If you want "123." to display as "123.0" instead of "123" then just replace that final empty string with ".0".
UPDATE: My original version displayed wrong for numbers that Mathematica by default displays in scientific notation.
I fixed that with NumberForm.
Here's the version I actually use in real life. It allows for optional rounding:
(* Show Number. Convert to string w/ no trailing dot. Round to the nearest r. *)
Unprotect[Round]; Round[x_,0] := x; Protect[Round];
re = RegularExpression;
shn[x_, r_:0] := StringReplace[
ToString#NumberForm[Round[N#x,r], ExponentFunction->(Null&)], re#"\\.$"->""]
I'd probably just post-process the string. It's faster (and way easier) to just check if the last character is "." than to do redundant arithmetic and take into account all the precision settings.
Edit: maybe you know this, but you can do something like this:
userToString[expr_, form___] := ToString[expr,form];
userToString[expr_Real, form___] := removeTrailingDot[ToString[expr,form]];
The functions NumberForm, ScientificForm, EngineeringForm, etc. ... offers the option NumberFormat to format and arrange the mantissa, base and exponent of a number. With
numberTrim[expr_] := NumberForm[expr,
NumberFormat -> (Row[{StringTrim[#1, "."],
If[#3 == "", "", "\[ThinSpace]\[Times]\[ThinSpace]" <> #2^#3]}] &)];
the default Mathematica output is reproduced, but the trailing dot is removed.

Resources