Cannot convert number to date - sql

I have problem converting number column to date, I did the following
SELECT to_date('12-30-1899 1:00:00','MM-DD-YYYY HH24:Mi:SS') + (createDate/1440)
FROM table_A;
and got the query result
10/17/5826 17:18
The month and date including hours and seconds is right but the year is different I got 5826. Its also the same for the other rows i got different results for year. I did follow some examples on this here. But still got wrong result. Can anyone help on this thanks.
The samples below are createDate column values:
1300844909778
1302831103113
1303210978316
1396963615616

Date arithmetic in Oracle assumes days. As it stands you are dividing a very large number by 1440 and adding that number of days to your starting date. That's why you're getting results in the far future.
So what value does createdate represent? It's clearly not an actual date. Your choice of 1440 as denominator suggests you think it's meant to be "number of minutes" but if the dates are so far out of expectation that is not it either.
I thought could be values represented in the Unix epoch because the numbers start with 13. Except that they're way too big. Current Unix timestamps should be ten digits. You've got thirteen digits.
Could they be Unix epoch plus milliseconds?
I have created a SQLfiddle to test this theory. Treating the first ten digits of your createdate values as seconds and adding that number to the Unix date produces sensible dates. Check it out.
So the theory holds water. But I doesn't help with your query. Adding two dates together doesn't make any sense. What are you actually trying to achieve? If your're looking for an interval you need to subtract the earlier date from the later one.

The createDate could be the number of milliseconds. It is just a guess. If so, then maybe this helps:
SELECT to_date('12-30-1899 1:00:00','MM-DD-YYYY HH24:Mi:SS') + (1300844909778/(1000*60*60*24))
FROM dual
/
3/21/1941 2:48:30 AM

Related

Trying to accommodate relative defined date, such as 5 days ago, into my fixed date condition in PostgreSQL

I'm trying to condition my WHERE clause to accommodate relatively defined dates into my date filter. I'm pretty confused what type I need to use, if it's CONVERT or TO_DATE function, or if I need to put a CASE WHEN statement into my code.
This is the code that I have written so far:
WHERE event_create_verified_user_success.created_at_utc_date
BETWEEN DATE '2021-11-29' AND DATE '2021-12-05'
And this is the condition of the activity I need to finish:
If the desired date-period is not set manually using fixed dates like from “2021-11-29”
to “2021-12-05”, how would you change the where-clause to consider all data from relative
defined dates: “consider messages created between 10 days and 5 days ago (inclusive)”
I've only started PostgreSQL yesterday and the last time I've handle SQL was probably 4 years ago so I'm pretty confused at how much SQL has changed since then.
Thank you so much for helping!
The basic syntax hasn't really changed in the last 4 years (or even 15 years).
You can use current_date to obtain "today's date". You can subtract days from that
where ... between current_date - 10 and current_date - 5
If created_at_utc_date is a timestamp (= date and time) rather than a date (=date without time) it's better to use a range query though:
where created_at_utc_date >= current_date - 10
and created_at_utc_date < current_date - 4
Note the < combined with the next day you want to compare with.

Oracle Months Between does not work properly

Good morning,
I've wrote the following query to get the months difference between a date column (STRT_DT) and a timestamp column (VLD_FRM_TMS) stored in two different tables.
I don't know why it works for some records but does not for others (it calculates one month less)
select ID, floor (months_between (cast(a.VLD_FRM_TMS as date), STRT_DT)) as delta
from TABLE_A a
inner join TABLE_B b
on a.ID = b.ID
This is an example of record for which the calculation does not work:
VLD_FRM_TMS
-----------
28-FEB-21 12.00.00.000000000 AM
STRT_DT
--------
29-OCT-20
The formula calculates 3 months instead of 4...
Could anyone help me in locating the problem?
Thank you in advance
This is exactly the behavior that is described in the documentation:
If date1 and date2 are either the same days of the month or both last days of months, then the result is always an integer. Otherwise Oracle Database calculates the fractional portion of the result based on a 31-day month and considers the difference in time components date1 and date2.
(Note: Highlighting is mine.)
If you run this code:
select months_between(date '2021-02-28', date '2020-10-29') as delta
from dual
The result is 3.9677.
I suspect that you want some other logic. However, the question does not specify what logic you actually do want.
I actually want the months difference regardless of the specific day of the month.
You can truncate both values to the first of the month using the 'MM' format element, and then get the difference between those:
months_between (trunc(a.VLD_FRM_TMS, 'MM'), trunc(STRT_DT, 'MM')) as delta
That will now always be an integer - i.e. a whole number of months - so you don't need to trunc/floor/round the result.
db<>fiddle showing the problem with the old calculation and this version.

sql Teradata difference in months

I need to get the difference between dates, but I just need to get the whole months that have passed. So for example between "1990-05-24" and "1990-05-27" it should say 0. It would also be 0 for "1990-05-02" and "1990-05-29" because the month has not finished.
I already got the difference in months using MONTHS_BETWEEN(), but I get months with decimals, and ROUNDing is not an option since sometimes it should be up and sometimes down.
I thought about setting al dates to day 01. In both colums Closing_date and Opening_date. But can't figure out how to do it.
I think you want to count boundaries between months. If so, you can use months_between() after truncating to the first of the month:
months_between(trunc(date1, 'MON'), trunc(date2, 'MON')

Oracle SQL - Convert (Date and Julian Hours) to Julian Hours [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
The dates are in gregorian date and the hours are in julian. How do I get the difference between in hours between the two times?
Assuming your date columns are of the date data type, and the time columns are of a string type (varchar2), you could do these calculations:
select to_char(trunc(hours) * 100 + (hours-trunc(hours))*60, 'fm0000') as hours_minutes
from (
select ( (dtrecv - dtcoll)
+ ( to_date(nvl(tmrecv, '0000'), 'hh24mi')
- to_date(nvl(tmcoll, '0000'), 'hh24mi'))
) * 24 as hours
from sample_demog_view
);
When time columns values are null, 0000 is assumed. When either one of the date columns is null the result will be null as well.
Explanation
Summary: the inner SQL calculates the number of hours between the two date/times as a fractional number. The outer query converts this number to the 4-digit 24-clock notation. NB: This second step might or might not be needed for you.
(dtrecv - dtcoll): the two time-less dates are subtracted from each other which gives a numerical value representing a number of days.
to_date(nvl(tmrecv, '0000'), 'hh24mi'): converts the 24-clock notation to a date/time, but the date part is zero. The same conversion is performed for tmcoll and it is subtracted from the first. This gives a numerical value representing a number of days, but it will be a fractional number between -1 and 1.
This gets added to the difference in days we already got, giving a fractional number, still expressing a number of days.
To translate that to number of hours: * 24.
The outer query then takes that value and truncates it to get the integer number of hours: trunc(hours)
Then the decimal part is taken: hours-trunc(hours). This is multiplied by 60 to get the corresponding number of minutes.
Finally, hours and minutes are added (hours multiplied by 100 to make room for the minutes) and formatted as a 4 digit string. Note that the difference may need more than 4 digits, so the to_char format might need to be modified if that is your case.
The reason for the outer query is that I wanted to avoid to repeat the same calculation, so I could just refer to it with hours. If there is a better solution that only refers to hours once, then there is no more need for this select nesting.

Battling Datediff in SQL

I am writing a little query in SQL and am butting heads with an issue that it seems like someone must have run into before. I am trying to find the number of months between two dates. I am using an expression like ...
DATEDIFF(m,{firstdate},{seconddate})
However I notice that this function is tallying the times the date crosses the monthly threshold. In example...
DATEDIFF(m,3/31/2011,4/1/2011) will yield 1
DATEDIFF(m,4/1/2011,4/30/2011) will yield 0
DATEDIFF(m,3/1/2011,4/30/2011) will yield 1
Does anyone know how to find the months between two dates more-so based upon time passed then times passed the monthly threshold?
If you want to find some notional number of months, why not find the difference in days, then divide by 30 (cast to FLOAT as required). Or 30.5-ish perhaps - depends on how you want to handle the variable month length throughout the year. But perhaps that's not a factor in your particular case.
The following statements have the same startdate and the same endate. Those dates are adjacent and differ in time by .0000001 second. The difference between the startdate and endate in each statement crosses one calendar or time boundary of its datepart. Each statement returns 1. ...
SELECT DATEDIFF(month, '2005-12-31 23:59:59.9999999'
, '2006-01-01 00:00:00.0000000'); ....
(from DATEDIFF, section datepart Boundaries ). If you are not satisfied by it, you probably need to use days as unit as proposed by martin clayton
DATEDIFF(m,{firstdate},ISNULL({seconddate},GETDATE())) - CASE
WHEN DATEPART(d,{firstdate}) >= DATEPART(d,ISNULL({seconddate},GETDATE()))
THEN 1
ELSE 0
DATEDIFF is like this by design. When evaluating a particular time measurement (like months, or days, etc.), it considers only that measurement and higher values -- ignoring smaller ones. You'll run into this behavior with any time measurement. For example, if you used DATEDIFF to calculate days, and had one date a few seconds before midnight, and another date a few seconds after midnight, you'd get a "1" day difference, even though the two dates were only a few seconds apart.
DATEDIFF is meant to give a rough answer to questions, like this:
Question: how many years old are you?
Answer: some integer. You don't say "I'm 59 years, 4 months, 17 days, 5 hours, 35 minutes and 27 seconds old". You just say "I'm 59 years old". That's DATEDIFF's approach too.
If you want an answer that's tailored to some contextual meaning (like your son who says "I'm not 8! I'm 8 and 3-quarters!, or I'm almost 9!), then you should look at the next-smallest measurement and approximate with it. So if it's months you're after, then do a DATEDIFF on days or hours instead, and try to approximate months however it seems most relevant to your situation (maybe you want answers like 1-1/2 months, or 1.2 months, etc.) using CASE / IF-THEN kinds of logic.