I am importing fields from Excel to my journal. The problem is - it does not import dates that have a dot or slash in end of the date, like 01.01.2020. The field is just empty.
I am trying to find a way to remove teh last symbol, if it exists. I tried str test = date2Str(_country, 123, -1, -1, -1, -1, -1, -1);, but it will take data that does not have a dot or slash in the end. It could be easy to work with date if it was a string, but I am failing to convert it to a string because of that dot or slash in end of the date...
It only converts 01.01.2020 format but it does not convert 01.01.2020. Any suggestions would help a lot. Thanks.
Option 1
Clean up the source data. I cannot image that Excel stores proper date values with a trailing . or /.
Option 2
How are you fetching the Excel values? Does your third party (?) solution offer a method like myCell.getDateValue() that returns a date type instead of a string type?
Option 3
You could apply a simple substr() with length=8 to trim of any trailing characters. The line of code below works for me.
date d = str2Date(subStr('01.01.2020.', 1, 8), 123);
Related
I wrote a code that automatically pulls time-related information from the system. As indicated in the table is fixed t247 Month names to 10 characters in length. But it is a bad image when showing on the report screen.
I print this way:
WRITE : 'Bugün', t_month_names-ltx, ' ayının'.
CONCATENATE gv_words-word '''nci günü' INTO date.
CONCATENATE date ',' INTO date.
CONCATENATE date gv_year INTO date SEPARATED BY space.
TRANSLATE date TO LOWER CASE.
I tried the CONDENSE t_month_names-ltx NO-GAPS. method to delete the spaces, but it was not enough.
After WRITE, I was able to write statically by setting the blank value:
WRITE : 'Bugün', t_month_names-ltx.
WRITE : 14 'ayının'.
CONCATENATE gv_words-word '''nci günü' INTO date.
CONCATENATE date ',' INTO date.
CONCATENATE date gv_year INTO date SEPARATED BY space.
TRANSLATE date TO LOWER CASE.
But this is not a correct use. How do I achieve this dynamically?
You could use a temporary field of type STRING:
DATA l_month TYPE STRING.
l_month = t_month_names-ltx.
WRITE : 'Bugün', l_month.
WRITE : 14 'ayının'.
CONCATENATE gv_words-word '''nci günü' INTO date.
CONCATENATE date ',' INTO date.
CONCATENATE date gv_year INTO date SEPARATED BY space.
TRANSLATE date TO LOWER CASE.
You can not delete trailing spaces from a TYPE C field, because it's of constant length. The unused length is always filled with spaces.
But after you assembled you string, you can use CONDENSE without NO-GAPS to remove any chains of more than one space within the string.
Add CONDENSE date. below the code you wrote and you should get the results you want.
Another option is to abandon CONCATENATE and use string templates (string literals within | symbols) for string assembly instead, which do not have the annoying habit of including trailing spaces of TYPE C fields:
DATA long_char TYPE C LENGTH 128.
long_char = 'long character field'.
WRITE |this is a { long_char } inserted without spaces|.
Output:
this is a long character field inserted without spaces
I'm printing the following year as a string in a report but it prints as 2,018.00. How do I have it print as a four digit year string without decimals or the comma? The Truncate() didn't seem to work.
CStr (Year({Date}) + 1)
You can either omit the CStr-function and set the number format on the formatting tab or, if the formula needs to return a string, you can use the arguments of the CStr- or ToText-function (which are equivalent).
Either set the second argument to define the number format:
CStr(Year({Date}) + 1, "####")
Or
Set the second and third argument to set the number of decimals to 0 and an empty string as thousands separator:
CStr(Year({Date}) + 1, 0, "")
What is happening is the Year() function converts the data into a Number, complete with thousands separator, decimal, and 2 significant digits after the decimal.
To get around this what I have found that works is to remove the CStr() function from your formula. This allows you to access the Formatting tab for a Number data type by right clicking the field and selecting Format Field. Then from the Number tab you can set the Style of the field to one of the styles that doesn't use a separator or decimal in the display.
If you are needing to concatenate this value with another string, then you can get a little more creative and use the LEFT() and REPLACE() functions like this.
Left(Replace(Cstr(Year({Date}) + 1), ",", ""), 4)
I imported 5 excel files into SAS and there are some dates formatted as 8/3/1989 originally and formatted into 03Aug1989 (DATE9.) which is what I really want. However, on 1 file the dates failed to converted into DATE9. and it is read as $CHAR10 when I read the log. I tried several ways to reformat it into DATE9 but failed.
I tried to change all informat/format/input into DATE9. instead of $CHAR10 but failed, the results are all empty (.)
I tried DateNew=input (Date,DATE9.); but it didn't work either.
Any comment?
Thanks!
Joe's suggestion in the comment should be plan A. But occasionally built-in SAS format-specifying options don't work and you still end up with a string. If that's where you're at, here's a good fallback:
data test;
format imported_date $char10.;
imported_date = "8/3/1989";
month = scan(imported_date, 1, "/")*1;
day = scan(imported_date, 2, "/")*1;
year = scan(imported_date, 3, "/")*1;
date_datefmt = mdy(month,day,year);
format date_datefmt date9.;
run;
So I'm reading multiple text files in Matlab that have, in their first columns, a column of "times". These times are either in the format 'MM:SS.milliseconds' (sorry if that's not the proper way to express it) where for example the string '29:59.9' would be (29*60)+(59)+(.9) = 1799.9 seconds, or in the format of straight seconds.milliseconds, where '29.9' would mean 29.9 seconds. The format is the same for a single file, but varies across different files. Since I would like the times to be in the second format, I would like to check if the format of the strings match the first format. If it doesn't match, then convert it, otherwise, continue. The code below is my code to convert, so my question is how do I approach checking the format of the string? In otherwords, I need some condition for an if statement to check if the format is wrong.
%% Modify the textdata to convert time to seconds
timearray = textdata(2:end, 1);
if (timearray(1, 1) %{has format 'MM.SS.millisecond}%)
datev = datevec(timearray);
newtime = (datev(:, 5)*60) + (datev(:, 6));
elseif(timearray(1, 1) %{has format 'SS.millisecond}%)
newtime = timearray;
You can use regular expressions to help you out. Regular expressions are methods of specifying how to search for particular patterns in strings. As such, you want to find if a string follows the formats of either:
xx:xx.x
or:
xx.x
The regular expression syntax for each of these is defined as the following:
^[0-9]+:[0-9]+\.[0-9]+
^[0-9]+\.[0-9]+
Let's step through how each of these work.
For the first one, the ^[0-9]+ means that the string should start with any number (^[0-9]) and the + means that there should be at least one number. As such, 1, 2, ... 10, ... 20, ... etc. is valid syntax for this beginning. After the number should be separated by a :, followed by another sequence of numbers of at least one or more. After, there is a . that separates them, then this is followed by another sequence of numbers. Notice how I used \. to specify the . character. Using . by itself means that the character is a wildcard. This is obviously not what you want, so if you want to specify the actual . character, you need to prepend a \ to the ..
For the second one, it's almost the same as the first one. However, there is no : delimiter, and we only have the . to work with.
To invoke regular expressions, use the regexp command in MATLAB. It is done using:
ind = regexp(str, expression);
str represents the string you want to check, and expression is a regular expression that we talked about above. You need to make sure you encapsulate your expression using single quotes. The regular expression is taken in as a string. ind would this return the starting index of your string of where the match was found. As such, when we search for a particular format, ind should either be 1 indicating that we found this search at the beginning of the string, or it returns empty ([]) if it didn't find a match. Here's a reproducible example for you:
B = {'29:59.9', '29.9', '45:56.8', '24.5'};
for k = 1 : numel(B)
if (regexp(B{k}, '^[0-9]+:[0-9]+\.[0-9]+') == 1)
disp('I''m the first case!');
elseif (regexp(B{k}, '^[0-9]+\.[0-9]+') == 1)
disp('I''m the second case!');
end
end
As such, the code should print out I'm the first case! if it follows the format of the first case, and it should print I'm the second case! if it follows the format of the second case. As such, by running this code, we get:
I'm the first case!
I'm the second case!
I'm the first case!
I'm the second case!
Without knowing how your strings are formatted, I can't do the rest of it for you, but this should be a good start for you.
I have found a statement that compares two dates to see if one is greater than another:
If Format(Date, "m/d/yyyy") > #1/1/2000# Then MsgBox "Okay"
That's basically saying if today is later than January 1st, 2000 then pop up a message box.
This is fine if I am putting the date in the code (i.e., 1/1/2000), but I would like to get a date from the user during run-time and can't figure out how to incorporate that into the statement above.
If I provide a TextBox for the user to enter a date, I have surrounded the text with the # symbol:
If MyDate > "#" & Text1.Text & "#" then
That does not work. I've tried converting the text to Double, Integer, and Long. I have no idea how to use the enclosing # symbols with user input.
Thanks in advance for your help.
Use CDate(Text1.Text) to convert a string to a date. In reality you will want to do some checking to make sure that the value entered is a valid date, something along the lines of:
Dim myDate As Date
If IsDate(Text1.Text) Then
MyDate = CDate(Text1.Text)
Else
'Indicate the error to the user
End If
The # characters are "date quotes", if you will - they serve the same purpose for date literals as " does to delimit a string literal. You can't just concatenate # to a value to make it into a date.