How to concatenate and format date and time to timestamp/datetime in Intersystems Caché database - intersystems-cache

Utilizing the Intersystems Cache documentation and my limited SQL knowledge, I have figured out that Cache has it's own internal way to turn datetime into a six digit integer, but I can't figure out how to get it back to a human understandable format (the Intersystems documentation on how to do this is not comprehensible to me). I have a date column in yyyy-mm-dd, and a text time column in hh:ss xm, and I'm working in DBeaver. I need one column in datetime or datetime2.
SELECT appointment_date, CAST(appointment_start_time as TIME) ast,
appointment_date + appointment_start_time as sdt
FROM foobar
Example:
appointment_date ast sdt
2016-09-21 14:30:00 64184
Desired outcome:
appointment_date ast sdt
2016-09-21 14:30:00 2016-09-21 14:30:00

You can use CAST or CONVERT, and instead of '+', use STRING for concatenation
STRING(CAST(appointment_date as VARCHAR) , ' ' , appointment_start_time)
STRING(CONVERT(VARCHAR,appointment_date,105), ' ' , appointment_start_time)
105 is for format dd-mm-yyyy

Related

date and time concatenation in postgres

I wanted to get the only the hour of the time and concatenate it with the date.
here's my query
SELECT distinct TOTALIZER_METER_READINGS.date + to_char(TOTALIZER_METER_READINGS.time ,'HH')
FROM TOTALIZER_METER_READINGS
is there any other way to get the hour of the time without turning it into text?
+ is the operator to add numbers, dates or intervals.
The string concatenation operator in SQL is ||.
As you are storing date and time in two columns rather then using a single timestamp column, I would convert them to a single timestamp value, then apply to_char() on the "complete" timestamp:
Adding a time to a date returns a timestamp that can then be formatted as you want:
SELECT distinct to_char(TOTALIZER_METER_READINGS.date + TOTALIZER_METER_READINGS.time, 'yyyy-mm-dd HH')
FROM TOTALIZER_METER_READINGS
You can use EXTRACT (or the date_part function):
SELECT EXTRACT(hour FROM current_timestamp);
The result type is double precision.

Postgres Converting Data Types

I have a column saved as a character data type. This column is what I am going to be using as a date. The column goes "YYYY-MM-DD" in that format.
This is a problem because if I ever need to filter by date, I have to go
select col_1, col_2
from table
where date LIKE '2016-04%;
If I want to search for a date range, this turns into a giant complicated mess.
What is the easiest way to convert this to a "date" data type? I want it to continue to be in YYYY-MM-DD order (no timestamp).
My ultimate goal is to be able to search for dates in a format like this:
select col_1, col_2
from table
where date between 2016-01-01 AND 2016-05-31;
What do you guys recommend? I am terrified I am going to corrupt my date if I use an alter statement to convert my data type. (I have a copy of the data saved and can upload it again, but it will take forever.)
Edit: This is a VERY Large table.
Edit Part 2: I originally stored the data as a varchar data type because my dates were not uploading correctly and I got an error message when I tried to save as a date data type. The every date in this column is in the "YYYY-MM-DD" order. My solution was to save it as varchar to avoid the error message (I couldn't figure out what was wrong. I even got rid of leading and trailing spaces.)
Storing a date as a varchar was the wrong choice to begin with. It's very good that you want to change that.
The first step is to convert the columns using an ALTER TABLE statement:
alter table the_table
ALTER COLUMN col_1 TYPE date using col_1::date,
ALTER COLUMN col_2 TYPE date using col_2::date;
Note that this will fail if you have any value in those columns that cannot be convert to a correct date. If you get that you need to first fix those invalid strings before you can change the data type.
I want it to continue to be in YYYY-MM-DD order
This is a misconception. A DATE (or timestamp) does not have a "format". Once it's stored as a date you can display it in any format you want.
My ultimate goal is to be able to search for dates in a format like this:
2016-01-01 is not a valid date literal, a proper (i.e. correctly typed) date constant can be specified e.g. using date '2016-01-01' (note the single quotes!
So your query becomes:
select col_1, col_2
from table
where col_1 between date '2016-01-01' AND date '2016-05-31';
If you have a lot of queries like that you should consider creating an index on the date columns.
Regarding the date constant format:
Are you telling me that despite having the varchar data types, I can still (as of right now) search between specific dates by just typing the word date and putting single quotes between two dates
No, that's not the case. SQL is a strongly typed language and as such will only compare values of the same type.
Using an ANSI date literal (or e.g. to_date()) results in a type constant (i.e. a value with a specific data type).
The difference between date '2016-01-01' and '2016-01-01' is the same as between42(a number) and'42'` (a string).
If you compare a string with a date, you are comparing apples and oranges and the database will do an implicit data type conversion from one type to the other. This is something that should be avoided at all costs.
If you do not want to change the table, you should use the query sagi provided which explicitly converts the strings to dates and then does the comparison on (real) date values (not strings)
You can use POSTGRES TO_DATE() cast function :
SELECT col_1,col_2
FROM Your_Table
WHERE to_date(date_col,'yyyy-mm-dd') between to_date('2016-05-31','yyyy-mm-dd') and to_date('2016-01-01','yyyy-mm-dd')
What #a_horse said.
Plus, if you can't change the data type for some odd reason, to_date() is a safe option to convert the column on the column, but there is no point to use the same expression for provided constants. So:
SELECT col_1, col_2
FROM tbl
WHERE to_date(date, 'YYYY-DD-MM') BETWEEN date '2016-05-31' AND date '2016-01-01';
Or just use string literals without type. The type date is deferred from the context in this expression. And you don't even need to_date(). Since you are using ISO format already. A plain cast is safe:
WHERE date::date BETWEEN '2016-05-31' AND '2016-01-01';
Be sure to use ISO 8601 format for all date strings, so they are unambiguous and valid with any locale.
You can even have an expression index to support the query. Match the actual expression used in queries:
CREATE INDEX tbl_date_idx ON tbl ((date::date)); -- parentheses required!
But I wouldn't use the basic type name date as identifier to begin with.

Convert Time Zone in Amazon Redshift

I have a datetime column in a redshift table. It contains date in UTC format.
So, when I am querying based on time_zone like UTC+5:30/ UTC+4:30, I want to convert the table datetime column to chosen time_zone and proceed further. It gives me wrong result.
Using this method :
CONVERT_TIMEZONE ( ['source_zone',] 'target_zone', 'timestamp')
Query Type 1: Wrong input, correct answer
SELECT id, convert_timezone('UTC+5:30','UTC', date) as converted_time, ingest_date
FROM table_name
WHERE conditions
Query Type 2: Correct input, wrong answer -> It again subtracting 5:30 from the date in column
SELECT id , convert_timezone('UTC','UTC+5:30',ingest_date) as converted_time, ingest_date
FROM table_name
WHERE conditions
Query Type 3: Wrong input, correct answer
SELECT id, convert_timezone('UTC','UTC-5:30',ingest_date) as converted_time, ingest_date
FROM table_name
WHERE conditions
How to convert / parse the UTC column into selected timezone?
In Redshift, CONVERT_TIMEZONE interprets the offset as the time from UTC. For example, an offset of +2 is equivalent to UTC–2, and an offset of -2 is equivalent to UTC+2. CONVERT_TIMEZONE does not use the prefix string when calculating the offset, even if the string represents a valid time zone. For example, 'NEWZONE+2’, 'PDT+2', and'GMT+2' all have the same result. If a string does not include an offset, then it must represent a valid time zone or CONVERT_TIMEZONE returns an error.
For converting time_zone, if you send "UTC+5:30/UTC-4:30", amazon interpreting it as "UTC-5:30 / UTC+4:30".
Now you can convert + into - and vice versa before sending it to redshift.
(http://docs.aws.amazon.com/redshift/latest/dg/CONVERT_TIMEZONE.html)

ORA-01843: not a valid month - but what month format? Oracle 11g

I want to know what other MONTH formats exist except MM , MONTH or MON.
When the query below runs it gives me an error ORA-01843: not a valid month and I can understand why, because the server removes the "0" from the month "07" and leaves only the number "7", so the MM format is not the right one.
But which one is it?
select to_char(to_date(START_DATE,'MM/DD/YYYY '), 'DD-MM-YYYY')
from PER_ALL_PEOPLE_F
WHERE person_id=12345
The START_DATE column is DATE TYPE and it provides results like: 7/17/2012 .
Your assumption that the single-digit 7 for the month is a problem is not correct; Oracle is generally quite flexible and will happily parse a single digit month with the MM model:
select to_date('7/17/2012', 'MM/DD/YYYY') from dual;
TO_DATE('7/17/2012'
-------------------
2012-07-17 00:00:00
If start_date is already a DATE type then you should not be calling to_date() for it. You're doing an implicit conversion to a string using your NLS_DATE_FORMAT moodel, and then back to a date with your specified format. So really you're doing:
select to_char(to_date(to_char(START_DATE, <NLS_DATE_FORMAT>),
'MM/DD/YYYY '), 'DD-MM-YYYY')
If your NLS_DATE_FORMAT is something other than MM/DD/YYYY, e.g. DD-MON-YYYY, then you'll get an ORA-1843 error for at least some values.
You can see this with:
select to_date(date '2014-01-16', 'MM/DD/YYYY') from dual;
or the expanded:
select to_date(to_char(date '2014-01-16', 'DD-MON-YYYY'),
'MM/DD/YYYY') from dual;
Dates do not have any specific format, they're stored in an internal representation and then converted to a formatted string for display. You said your dates display like 7/12/2012, but given the error you're seeing your client seems to be doign that formatting, and it isn't related to the session NLS_DATE_FORMAT.
You only need to do:
select to_char(START_DATE, 'DD-MM-YYYY')

Oracle SQL : Expand year to a full date

This must be simple to answer, but how do you expand in Oracle a year to a full date, e.g.
1996 to 1996-01-01 00:00:00 ?
EDIT
The data type of the year is char, and I want to end up by comparing this year to a string-date, e.g.
1996 <= '1998-31-12 12:04:35'
It is important that the expanded data is expanded in the same data Format (since I get the dates preformatted)
At the end I need something like this
WHERE ( to_date(table.year_char ,'YYYY') <= '1996-12-31 00:00:00')
or sth like this
WHERE ( to_char(to_date(table.year_char ,'YYYY')) <= '1996-12-31 00:00:00')
or anything which works
If you're starting with the year as a string and you want to end up with a DATE object, you use the TO_DATE() function; but you need to supply a dummy month or it'll default to the first day of the current month in the specified year:
select to_date('1996', 'YYYY') from dual;
May, 01 1996 00:00:00+0000
SQL Fiddle
With the month, and to make it clearer the day too, appended and a suitable format model:
select to_date('1996' ||'-01-01', 'YYYY-MM-DD') from dual
January, 01 1996 00:00:00+0000
SQL Fiddle. I've left the year and the '-01-01' literal separate and concatenated on the assumption that you'll be using a variable really...
In a WHERE clause, using the sample date you initially showed:
select * from dual
where to_date('1996' ||'-01-01', 'YYYY-MM-DD')
<= to_date('1998-31-12 12:04:35', 'YYYY-DD-MM HH24:MI:SS')
Or if you're actually comparing to a string as your second example suggests, just leave it as a string, as you want both sides of the comparison to be the same data type without any implicit conversion that might cause you problems later. The string you have fortunately has the data in a format that is comparable:
WHERE (table.year_char || '-01-01 00:00:00' <= '1996-12-31 00:00:00')
You could convert it to and back from a DATE but there isn't any benefit in doing so.