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

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.

Related

sql statement - would like to subtract 1 date from another and get the days hours and mins inbetween

I would like to subtract 1 date from another and get the days hours and mins in-between.
I know there is a DateDiff function, however it does not work with all 3 time values; days hours and mins. I would like this doable in an SQL statement. Currently I have the following.
SELECT id, pickupdateandtime, GETDATE() AS CurrentTime,
(DATEDIFF(day,GETDATE(),pickupdateandtime)) AS Days,
(DATEDIFF(hour,GETDATE(),pickupdateandtime)) AS Hours,
(DATEDIFF(minute,GETDATE(),pickupdateandtime)) AS Mins FROM orders
And it shows up like this:
If we can stick it all in 1 column that's fine too.
I agree with #AndyMcLaughlin about the use of the mod operator % here. It's very handy for this sort of thing. However, I have a general distrust of DATEDIFF. That function does not count the whole number of years (say) between two dates, but the number of year boundaries between them.
So DATEDIFF "thinks" the difference in years between 01-Jan-2000 and 01-Jan-2001 is the same as that between 31-Dec-2000 and 01-Jan-2001.
This is why #Michael saw a need to subtract 1 from #AndyMcLaughlin's results. Unfortunately, that doesn't always work, it will depend on the individual case.
As a rule, DATEDIFF works well when it's used against the smallest interval you are interested in. So if you are interested in years and simply want to separate one calendar year from another, it'll serve you well.
I think the smallest interval we are interested in here is minutes. So we can use DATEDIFF for that, but have to work upwards from there to hours and days:
select
mf.id,
mf.pickupdateandtime,
mf.CurrentTime,
--The divisions in the following lines simply
--truncate since all the numbers are integers
--but that works in our favour here
(mf.MinutesFull/(60*24)) as Days,
(mf.MinutesFull/60) % 24 as Hours,
mf.MinutesFull % 60 as Minutes
from
(
select
id,
pickupdateandtime,
getdate() as CurrentTime,
datediff(minute, getdate(), pickupdateandtime) as MinutesFull
from #orders
) mf
You need to use the mod operator % to remove whole days from hours and whole hours from minutes.
So you can do something like:
SELECT
id,
pickupdateandtime,
GETDATE() AS CurrentTime,
(DATEDIFF(day,GETDATE(),pickupdateandtime)) AS Days,
(DATEDIFF(hour,GETDATE(),pickupdateandtime) % 24) AS Hours,
(DATEDIFF(minute,GETDATE(),pickupdateandtime) % 60) AS Mins FROM orders

Cannot convert number to date

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

Does DateDiff Round up?

I found a place in our old code where the original programmer tried to calculate whether an employee had been hired for a certain number of years. The calculation used the difference in days between the date hired and today divided by 364. This didn't make sense to me so I changed it to the difference in years. This also seemed to give an incorrect answer. Does DateDiff round up to the nearest year? Running this formula in the immediate window gives 15 as the answer. I was hoping it would give 14.
?datediff("yyyy",#3/1/1999#,#2/19/2014#)
Would it be better to use.
?datediff("m",#3/1/1999#,#2/19/2014#)/12
DateDiff for years only considers the year parts of the dates you supply. And it does not return what you might want as "how many years" ...
For example, the last day of 2013 to the first day of 2014 would be one year as far as DateDiff("yyyy" is concerned.
? DateDiff("yyyy", #2013-12-31#, #2014-1-1#)
1
DateDiff rounds off to the very next year if the year difference is like x years and y months.
For example:
if a person's age is 18 years and 1 months, datediff(yy,DDOB,GetDate()) will give result as '19'.
In case you dont want this rounding off, you can
Get difference in days between two dates after casting them in
INTEGER
Divide the difference with 365.25
Use FLOOR to ignore the the decimal part (don't round off as the
next number):
FLOOR((CAST (GetDate() AS INTEGER) - CASR(YourDate AS INTEGER)) / 356.25)
You can do the combination of IIf,DateDiff and DateAdd, like this:
=IIf(DateDiff("m";DateAdd("yyyy";DateDiff("yyyy";[DDOB];Date());[DDOB]);Date())<0;
DateDiff("yyyy";[DDOB];Date())-1;
DateDiff("yyyy";[DDOB];Date()))
So, firstly you calculate months between DDOB plus DateDiff years and Date(), and if integer form DateDiff "m" are in minus, then IIf will reduce the value for the year for one.

Difference between two dates in sql [duplicate]

This question already has an answer here:
Get the number of days between two dates in Oracle, inclusive of the dates
(1 answer)
Closed 8 years ago.
I want to calculate difference between two dates, something like:
SELECT TO_DATE('22-NOV-08')-TO_DATE('25-AUG-2008') FROM DUAL;
which comes out to be 89 is the TO_DATE('22-NOV-08') and TO_DATE('25-AUG-2008') included in this 89 days ?
To explain your query
SELECT TO_DATE('22-NOV-08')-TO_DATE('25-AUG-2008') FROM DUAL;
TO_DATE('22-NOV-08') converts the varchar value to date datatype and then what you are doing is nothing but enddate - startdate which will return the number of days elapsed.
In case you want the result in
1.hours -- multiply the result with 24
2.Minutes -- multiply the result with 24*60
so on ...
EDIT: if your question is; whether the result is inclusive of enddate and startdate then the answer is yes and so you have got the result as 89; else you would have got a result of 87 instead.
Yes, the difference is in units of days. Here is a tutorial for Date Arithmetic

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.