Storing result of date arithmetic in string - abap

The following code is supposed to subtract 10 days from a given date, store the result in a string variable and write it.
DATA str TYPE string.
DATA date TYPE d.
date = '20130418'. " 2013-04-18
str = date - 10.
WRITE str.
I would expect the output to be 2013-04-08 or at least an unformated 20130408. But the actual output is a quite mysterious number which doesn't make sense to me at all:
734967
Can someone explain me where this number comes from?
I already found a workaround (just put the result in another variable of type d and then assign this variable to the string), but I am still interested in an explanation for this strange result.
SAP_BASIS release is 702.

Take a look at the conversion rules: For the substraction, the date is converted to the number of days since 01.01.0001 internally (source type date, target type I), then the arithmetics take place. IF the result is a date field, a conversion (source type I/Packed, target type D) back into the form YYYYMMDD is applied. However, the conversion I/Packed to string is defined differently - so the string contains the number of days between your result date and 01.01.0001.

Related

SQL Server Not Casting String YYYYMMdd to Date

I have a query that was working fine before a server migration and now is not working. I'm trying to convert all dates to a specific month and year, but I keep getting this error:
Conversion failed when converting date and/or time from character string.
Looking into the data, there are no null values in InputDate, which is a date data type column. When I run the Concat() function everything is formatted as 'YYYYMMdd', yet both CAST and CONVERT fail with the same error.
Is there an issue with my query that I'm not seeing?
SELECT RandoSTUFF,
DATEADD(day,2,CAST(CONCAT('2023','02',FORMAT(InputDate,'dd')) AS date)) AS MovedDate
FROM a_table_
I expect the issue is you have date values near the end of their months, and you're trying to compose the equivalent values for February, which is shorter.
So if you have an InputDate value of, say, 2022-12-31 and run the code in the question, it will extract the 31 and concat it with the other values, and you'll end up trying to do this:
CAST('20230231' as Date)
Of course, there is no such date.
As it is, it's not clear whether you want such an input to map to February 28 or March 3. To fix this, you'll need to rethink the problem so you only try to map to valid dates, and ensure the final result is more clearly defined. This is one of the many reasons it's almost always better to use Date/time functions instead of composing dates from strings.

VBA date format code

I was wondering if there is any possibility to write a VBA code where the column A should always have a date format like this: 12.10.2017 (not 12/10/2017 or 12-10-2017). If anything else is written in the column A like "12" or "car" the entry should be deleted. It has to accept only the date format mentioned above.
I used data validation for this, with length 10 and the date format to take only "." into consideration, but I want to do it as a VBA code instead.
Thanks!
A valid date is a long representing the number of days since the 1st january 1900. So a valid date would be 45603. You can display this date in any format you wish using the format codes d, m and y . So to display the date as dd.mm.yyyy then set that numberformat in the cells in column A. Your problem though is that Excel will only accept a date entered as either a long or in a built in date format (using /, - or space as a separator). You could allow the users to enter a text string in the format dd.mm.yyyy and then convert that string into a date and then reject it if the conversion didn't result in a valid date - but wouldn't it be easier to just train your users to enter dates correctly?

IBM i Date Diff with CYYMMDD - can't use DATE()

(title edited)
Good afternoon, all!
Using IBM i version 7.1 and looking to calculate difference between two dates in a query. Since nothing is ever easy, one date is in CYYMMDD format, the other (curdate()) is YYYY-MM-DD. I tried to CAST my CYYMMDD formatted date (field name APENGD) as a varchar(10) then wrapped that in a CAST as a date (since decimals can't be CASTed as dates):
Cast(Cast(APENGD + 19000000 As varchar(10)) As date) As math
but I only see a result ++++++++++++++ for whatever reason. I was able to test a few different versions of this and found I can't use DATE anywhere...can anyone suggest an alternative??
Thanks in advance!
Matt
casting varchar to date only works when the string includes separators.
At 7.1 you could use TIMESTAMP_FORMAT(), but you'd end up with a timestamp instead of just a date. But that's easily dealt with.
Date(Timestamp_format(char(APENGD + 19000000),'YYYYMMDD')) As math
My prefered solution when dealing with numeric/character value dates is creating a User Defined Function to handle conversion.
You could write your own, or use the one I do. iDate written by Alan Campin. Then your code would simple be:
idate(APENGD,'*CYMD') as nath
Note that if you're trying to use date differences in a WHERE clause, like so
WHERE CURRENT_DATE - 3 months <= idate(APENGD,'*CYMD')
The above will perform poorly since an existing index over APENGD can't be used (directly). Assuming a recent(6.1+) version of the OS, you can create a new index that includes the expression you're using to convert APENGD to date.
Or you could code it using the Date->Numeric function ConvertToIdate that Alan helpfully includes. That would allow existing indexes to be used.
WHERE ConvertToiDate(CURRENT_DATE - 3 months,'*CYMD') <= APENGD
The DDL was not offered [to define the column APENGD]. No matter, as the following should suffice, mostly irrespective the definition; either as a string or as a zero-scale numeric. The effect depends on the SQL recognition of a 14-character [up to 26-character, since some v7 release] character-string as an unformatted [i.e. lacking any delimiters, thus digits-only] TIMESTAMP representation:
date(timestamp((APENGD + 19000000) concat '000000'))
IBM i 7.3->Database->Reference->SQL reference->Language elements->Data types->Datetime values->String representations of datetime values->Timestamp strings
A string representation of a timestamp is a character or a Unicode graphic string that starts with a digit and has a length of at least 14 characters. …
If you want calculate difference between 2 dates, you can use:
`TIMESTAMPDIFF(32, cast(MYTIMESTAMP1 - MYTIMESTAMP2 as char(22)))`
The first argument of function specify the type of result.
1 : millisecond
16 : days
2 : second
32 : week
4 : minutes
64 : month
8 : hour
128 : trimester
256 : Year

How to create a Date variable in Elm

I want to hardcode a date in a record in elm. The record signature is
type alias Record = { .., startDate : Date, .. }
On my code I am doing
record = { .., startDate = Date.fromString "2011/1/1", .. }
The problem is that the Record type expects a Date type but Date.fromString signature is
String -> Result.Result String Date.Date
How can I create the Date to use on the Record type?
You're getting the Result because there is a chance that parsing the string to a date failed. You can handle it one of 2 ways.
Ignore it
If you want to just say "I know this string will be valid date and I'm not worried that I may have messed it up" then you can just provide a default date
Date.fromString "2011/1/1" |> Result.withDefault (Date.fromTime 0)
This will leave you with a Date but will default to the unix epoch if the parse fails.
Use it
Think about what you would want to happen if the parse were to fail and handle it where the date is used. Ex. if you're displaying it as a string you could display the date or if the parse failed display "TBA".
Note: You may have noticed that Date.fromTime just returns a Date not a Result (because an Int can always be parsed to a Date). If you don't mind converting your dates to unix timestamps you could hardcode the timestamp and use that without having to deal with Results

character_length Teradata SQL Assistant

I have to run column checks for data consistency and the only thing that is throwing off my code is checking for character lengths for dates between certain parameters.
SEL
sum(case when ( A.date is null or (character_length(A.date) >8)) then 1 else 0 end ) as Date
from
table A
;
The date format of the column is YYYY-MM-DD, and the type is DA. When I run the script in SQL Assistant, I get an error 3580 "Illegal use of CHARACTERS, MCHARACTERS, or OCTET_LENGTH functions."
Preliminary research suggests that SQL Assistant has issues with the character_length function, but I don't know how to adjust the code to make it run.
with chareter length are you trying to get the memory used? Becuase if so that is constant for a date field. If you are trying to get the length of the string representation i think LENGTH(A.date) will suffice. Unfortanatly since teradata will pad zeros on conversions to string, I think this might always return 10.
UPDATE :
Okay so if you want a date in a special 'form' when you output it you need to select it properly. In teradata as with most DBs Date are not store in strings, but rather as ints, counting days from a given 'epoch' date for the database (for example the epoch might be 01/01/0000). Each date type in teradata has a format parameter, which places in the record header instructions on how to format the output on select. By default a date format is set to this DATE FROMAT 'MM/DD/YYYY' I believe. You can change that by casting.
Try SELECT cast(cast(A.date as DATE FORMAT 'MM-DD-YYYY') as CHAR(10)) FROM A. and see what happens. There should be no need to validate the form of the dates past a small sample to see if the format is correct. The second cast forces the database to perform the conversion and use the format header specified. Other wise what you might see is the database will pass the date in a date form to SQL Assitant and sql assitant will perform the conversion on the application level, using the format specified in its own setting rather then the one set in the database.