Date and time difference
Jamil, December 03, 2003 - 6:19 am UTC
Dear Sir
In this example I am calculating the consume time for the cars journey, my table structure as follow:
SQL> descr travel_table
Name Null? Type
------------------------------- -------- ----
J_START_DATE DATE
J_START_TIME CHAR(5)
J_START_TIME_STATUS NUMBER(1)
J_END_DATE DATE
J_END_TIME CHAR(5)
J_END_TIME_STATUS NUMBER(1)
J_CONS_DAY CHAR(5)
J_CONS_HOUR CHAR(5)
J_CONS_MIN CHAR(5)
In my form I am using this code for calculating
the consume days and consume hours and the consume minutes
the code for the bush button as follow
--------------------------------
when-button-pressed
DECLARE
ST_DATE VARCHAR2(10);
ST_TIME VARCHAR2(5);
ST_TIME_STATUS VARCHAR2(2);
EN_DATE VARCHAR2(10);
EN_TIME VARCHAR2(5);
EN_TIME_STATUS VARCHAR2(2);
DATA_RET VARCHAR2(50);
CON_L NUMBER(4) := 0;
BEGIN
CHECK_DATE_RANGE(:J_START_DATE,:J_END_DATE);
ST_DATE := TO_CHAR(:J_START_DATE,'MM-DD-YYYY');
ST_TIME := RTRIM(LTRIM(:J_START_TIME));
IF :J_START_TIME_STATUS = 1 THEN
ST_TIME_STATUS :='AM';
ELSIF :J_START_TIME_STATUS = 2 THEN
ST_TIME_STATUS :='PM';
END IF;
EN_DATE :=to_char(:J_END_DATE,'MM-DD-YYYY');
EN_TIME := RTRIM(LTRIM(:J_END_TIME));
IF :J_END_TIME_STATUS = 1 THEN
EN_TIME_STATUS :='AM';
ELSIF :J_END_TIME_STATUS = 2 THEN
EN_TIME_STATUS :='PM';
END IF;
BEGIN
DATA_RET :=travel_time(ST_DATE,ST_TIME,ST_TIME_STATUS,
EN_DATE,EN_TIME,EN_TIME_STATUS);
MESSAGE('Time Calculated='||DATA_RET);
:J_CONS_DAY := SUBSTR(DATA_RET,2,INSTR(DATA_RET,' ')-1);
CON_L :=INSTR(DATA_RET,'H');
CON_L := CON_L + 1;
MESSAGE('CON_L ='||' ' ||CON_L);
:J_CONS_HOUR := SUBSTR(DATA_RET,CON_L,INSTR(DATA_RET,' ')-1);
CON_L :=INSTR(DATA_RET,'M');
CON_L := CON_L + 1;
:J_CONS_MIN := SUBSTR(DATA_RET,CON_L,INSTR(DATA_RET,' ')-1);
COMMIT;
END;
END;
---------------------------------------
And the code for the function travel_time as follow:
---------------------------------------
FUNCTION travel_time (sd varchar2,st varchar2,s_ampm varchar2,
ed varchar2,et varchar2,e_ampm varchar2)
RETURN varchar2
IS
s_dt date;
e_dt date;
rtrn varchar2(50);
ET1 NUMBER; -- Elapsed time
Begin
begin
s_dt := to_date(sd || st || s_ampm,'MM-DD-YYYYHH:MIAM');
exception when others then
MESSAGE('Invalid start date/time: '||sd||st||s_ampm);
rtrn := 'Invalid start date/time: '||sd||st||s_ampm;
end ;
if rtrn is null then
begin
e_dt := to_date(ed || et || e_ampm,'MM-DD-YYYYHH:MIAM');
exception when others then
MESSAGE('Invalid end date/time: '||ed||et||e_ampm);
rtrn := 'Invalid end date/time: '||ed||et||e_ampm;
end;
end if;
if rtrn is null then
ET1 := e_dt - s_dt;
rtrn := 'D'||Trunc(ET1)||' '
||'H'||Mod(Trunc(ET1*24),24)||' '
||'M'||Mod(Round(ET1*1440),60);
end if;
return rtrn;
End travel_time;
-----------------------------------------
So my problem is when I run this form I am getting this message when I press the bush button
1) Invalid start date/time : 12-03-200310:30AM
2) FRM-40735:WHEN-BUTTON-PRESSED trigger raised unhandled exception ORA-06502
Can you please tell me what is wrong with the above code.
Notice :
The above code works fine if I change the
NLS_LANG from ARABIC_UNITED ARAB EMIRATES.AR8MSWIN1256
To
AMERICAN_AMERICA.AR8MSWIN1256
I have make this changed for NLS_LANG in the registry editor,But I required to use the NLS_LANG as
ARABIC_UNITED ARAB EMIRATES.AR8MSWIN1256
Because my form layout is Arabic not English
Waiting for your valuable answer.
Best Regards
Jamil
Date difference
Jamil Shaibani, December 04, 2003 - 12:30 am UTC
Dear sir
Would you please tell me what is wrong with my code,because the user must enter the data in the form using these fields
J_START_DATE DATE
J_START_TIME CHAR(5)
J_START_TIME_STATUS NUMBER(1)
J_END_DATE DATE
J_END_TIME CHAR(5)
J_END_TIME_STATUS NUMBER(1)
And also the time format it should be in this format HH12:MI not as HH24:MI hours
If you have time to correct my code , it will be very help full to me, because this code is working fine except that as I mention before it is working when I change the NLS_LANG to English.
Thank you very much for your replay
waiting for your valuable replay.
Best regards
Jamil
December 04, 2003 - 7:48 am UTC
i see two dates there
start date
end date
use my code, no time to debug others ;) you have everything you need.
and remember -- formats are formats -- not data. DATES are stored in 7 bytes, in binary. formats are used to translate strings on the way in and format them on the way out of the database. they have no bearing on HOW the data is actually stored. they are purely for your viewing pleasure. so you can in fact format the dates however you like.
don't work with dates as strings (as you are). work with DATES.
excellent
عا شد, December 04, 2003 - 9:46 am UTC
کیا
Date validation using sql
A reader, March 19, 2004 - 11:22 am UTC
date validation:
----------------
I have two dates given to my procedure p.
Now I should validate them and see that the two dates do no span over one month i.e.
Dates like 01/01/2003 , 02/02/2003 are not valid. If the first date is 01/01/2003 then the second date
at the max can only be 01/31/2003 i.e. if should fall within the month of the first date.
I'm pondering how to do this validation using sql, and avoid writing a procedure to do the same.
can you help.
March 19, 2004 - 1:34 pm UTC
"when abs( months_between(a,b) ) <= 1"
ops$tkyte@ORA9IR2> select abs(months_between('01-jan-2003','02-feb-2003')) from dual
2 /
ABS(MONTHS_BETWEEN('01-JAN-2003','02-FEB-2003'))
------------------------------------------------
1.03225806
ops$tkyte@ORA9IR2> select abs(months_between('01-jan-2003','31-jan-2003')) from dual
2 /
ABS(MONTHS_BETWEEN('01-JAN-2003','31-JAN-2003'))
------------------------------------------------
.967741935
ops$tkyte@ORA9IR2> select abs(months_between('15-jan-2003','15-feb-2003')) from dual
2 /
ABS(MONTHS_BETWEEN('15-JAN-2003','15-FEB-2003'))
------------------------------------------------
1
doesnt work for me, but good solution
A reader, March 19, 2004 - 1:56 pm UTC
Tom
date validation:
----------------
I have two dates given to my procedure p.
Now I should validate them and see that the two dates do no span over one month
i.e.
Dates like 01/01/2003 , 02/02/2003 are not valid. If the first date is
01/01/2003 then the second date
at the max can only be 01/31/2003 i.e. if should fall within the month of the
first date.
I'm pondering how to do this validation using sql, and avoid writing a procedure
to do the same.
can you help.
Followup:
"when abs( months_between(a,b) ) <= 1"
ops$tkyte@ORA9IR2> select abs(months_between('01-jan-2003','02-feb-2003')) from
dual
2 /
ABS(MONTHS_BETWEEN('01-JAN-2003','02-FEB-2003'))
------------------------------------------------
1.03225806
ops$tkyte@ORA9IR2> select abs(months_between('01-jan-2003','31-jan-2003')) from
dual
2 /
ABS(MONTHS_BETWEEN('01-JAN-2003','31-JAN-2003'))
------------------------------------------------
.967741935
ops$tkyte@ORA9IR2> select abs(months_between('15-jan-2003','15-feb-2003')) from
dual
2 /
ABS(MONTHS_BETWEEN('15-JAN-2003','15-FEB-2003'))
------------------------------------------------
1
This will not work for me, I cant have the dates spanning across months, the dates should be within one month.
The whole point behind this question was to force the users enter begin and end dates which fall within a month, any month but within that month. If they enter 01/01/2003 as the begin date , then they should enter a date which falls in jan for the end date.
I should capture what they have entered and let them know if their dates span accross more than 1 month i.e. jan in the give example.
March 19, 2004 - 2:20 pm UTC
then it is even easier?
where trunc(d1,'mm') = trunc(d2,'mm')
Converting numbers to date format
Arya, July 07, 2005 - 11:20 am UTC
Hi Tom,
I am loading data from source table in which dates have been stored as numbers and I have no control over the source tables.
When I looked at the data there are many records with invalid dates here is the sample data I have provided.
Column Name Null? Data Type
COL1 Y NUMBER
COL2 Y NUMBER
COL3 Y NUMBER
CREATE_DTS Y NUMBER
UPDATE_DTS Y NUMBER
COL1 COL2 COL3 CREATE_DTS UPDATE_DTS
1 10 100 2000366
2 20 200 2004366
3 30 300 2005365
4 40 400 2005190
5 50 500 2005366
6 60 600 2005190
7 70 700 2005365
8 80 800 2005366
9 90 900 2005367
I need to select records which have valid dates. so I tried the following sql.
select col1,to_date(create_dts,'yyyyddd')
from test_source
where substr(create_dts,5,3) <=366
But with the above query 1 and 2 records are ignored even though they are valid.
I appreciate your help to get all the records which are valid for ex.
1 10 100 2000366
2 20 200 2004366
3 30 300 2005365
4 40 400 2005190
6 60 600 2005190
7 70 700 2005365
Thanks
Arya
July 07, 2005 - 1:44 pm UTC
ops$tkyte@ORA9IR2> create table t ( x number );
Table created.
ops$tkyte@ORA9IR2> insert into t values ( 2000366 );
1 row created.
ops$tkyte@ORA9IR2> select * from t where substr(x,5,3) <= 366;
X
----------
2000366
ops$tkyte@ORA9IR2>
you'll have to give me an example - create tables, insert intos etc etc
(does not it scare you to compare a string to a number? and does the where clause HAVE to take place before the SELECT, best to use case
select case when mod(x,1000) <= 366 then to_date(......) end, ...
from t
where mod(x,1000) <= 366;
Converting to Dates
Arya, July 11, 2005 - 11:05 am UTC
Hi Tom,
Here is the table test_source
COL1 COL2 COL3 CREATE_DTS UPDATE_DTS
1 10 100 2000366
2 20 200 2004366
3 30 300 2005365
4 40 400 2005190
5 50 500 2005366
6 60 600 2005190
7 70 700 2005365
8 80 800 2005366
9 90 900 2005367
Select *
from test_source
Where substr(create_dts,5,3) <= 366;
Returns 8 records except the date with 367 days which is invalid.
1 10 100 2000366
2 20 200 2004366
3 30 300 2005365
4 40 400 2005190
5 50 500 2005366
6 60 600 2005190
7 70 700 2005365
8 80 800 2005366
To insert into another table test_dest same as test_source except dates are dates not numbers.
test_dest
col1 number
col2 number
col3 number
create_dts date
update_dts date
insert into test_dest
select col1,col2,col3,To_Date(create_dts,'YYYYDDD'),to_date(update_dts,'YYYYDDD')
from test_source
where substr(create_dts,5,3) <= 366
I'm getting ora-1848 error
So I did the following to avoid this error looks like it working fine.
insert into test_dest
SELECT col1, col2, col3, to_date(create_dts,'YYYYDDD'), to_date(update_dts,'YYYYDDD')
FROM test_source
WHERE TO_NUMBER (SUBSTR (create_dts, 5)) <= (TO_DATE (SUBSTR (create_dts, 1, 4), 'YYYY') - TO_DATE (TO_CHAR (TO_NUMBER (SUBSTR (create_dts, 1, 4) - 1)),'YYYY'))
Thanks
Arya
July 11, 2005 - 11:45 am UTC
hmmm....
(does not it scare you to compare a string to a number? and does the where
clause HAVE to take place before the SELECT, best to use case
select case when mod(x,1000) <= 366 then to_date(......) end, ...
from t
where mod(x,1000) <= 366;
..... just repeating myself.
Converting to dates
Arya, July 11, 2005 - 3:25 pm UTC
Hi Tom,
I have to insert into test_dest table and create_dts and update_dts columns in this table are in date datatype so when I convert create_dts of test_source table to date i'm getting ora-1848 error because of record no 8.
select COL1, col2,col3, case when mod(create_dts,1000) <= 366 then to_date(CREATE_DTS,'YYYYDDD') end AS A
from test_source
where mod(create_dts,1000) <= 366;
if i try the following query it works fine but retreives wrong data for ex. record no 8 which is not right 2005366( it is not a leap year so it cannot have 366, as I told you earlier that we have no control of the data coming in)
select COL1, col2,col3, case when mod(create_dts,1000) <= 366 then CREATE_DTS end AS A
from test_source
where mod(create_dts,1000) <= 366;
COL1 COL2 COL3 create_dts
1 10 100 2000366
2 20 200 2004366
3 30 300 2005365
4 40 400 2005190
5 50 500 2005366
6 60 600 2005190
7 70 700 2005365
8 80 800 2005366
Thanks
Arya
July 11, 2005 - 3:52 pm UTC
then you need quite simply a more sophisticated case statement, you can use and/ors in there.
Converting to Dates
Arya, July 12, 2005 - 4:33 pm UTC
Hi Tom,
Do you see any problems with the way I have written conversions Could you please explain me with an example where it can go wrong. It is working fine as of now.
Your input is highly appreciated.
Thanks
Arya
July 13, 2005 - 10:53 am UTC
it is up to you, i didn't thoroughly debug you code, no.
I prefer to use the case statement, because you cannot control when oracle will call to_date, there is nothing say we cannot to_date the field BEFORE the predicate is applied. the case statement is "safer"
Data Validation
Thirumaran, November 23, 2005 - 4:42 am UTC
Hi Tom,
I am working on moving data from one oracle DB to another oracle DB using Sql*loader.
I am thinking about the validation mechansim. The big question "How will i verify that the data migrated from As Is to NEW DB is 100% accurate?".
What mechanism should i adopt to validate the data migration.
A small example will be greater help to me.
Thanks
Thirumaran
November 23, 2005 - 9:49 am UTC
why not just use a dblink and know the data got moved?
what does 100% accurate mean to you?
same number of rows?
same data byte for byte (think about character set translations....)
Date Format
Ramu, December 29, 2006 - 3:44 am UTC
Hi Tom
Is there any better way to validate my data before inserting into a table which has column with date as a datatype¿The source data has a character filed and we don¿t know the format how it comes(ex mm/yyyy,dd/mm/yy etc..) . Currently I am programmatically added some date formats but I am facing a problem when the format other than mentioned in the program comes. Also I need to check before itself the source data has a valid date format or not. Could you please help us how to handle this situation if possible with an example.
Thanks In Advance
Ramu
December 29, 2006 - 9:48 am UTC
insufficient data to answer.
the only answer I could think to give given this input, would be the original answer above to the original question.
time diff
ram, April 05, 2007 - 2:37 pm UTC
I have situation where i need find the time diff in two dates
I need your help how do we calculate the diff between sydate time - create_date
for ex : 1) sysdate -> 04/12/2006 12:05:36 PM
create_date -> 04/12/2006 11:48:36 PM
it should display as 0 hrs 17 min
2) sysdate -> 04/12/2006 12:45:36 PM
create_date -> 04/12/2006 9:44:36 PM
it should display as 2 hrs 59 min
can you please help me
April 05, 2007 - 3:38 pm UTC
1* select username, systimestamp - cast( created as timestamp ) diff from all_users
ops$tkyte%ORA10GR2> /
USERNAME DIFF
------------------------------ ---------------------------
PERFSTAT +000000018 23:14:26.607458
U2 +000000105 07:57:32.607458
OPS$TKYTE +000000001 18:54:32.607458
....
Job gets aborted due to invalid data in the table
A reader, April 25, 2008 - 12:11 am UTC
Tom:
We have a datastage job (Query) which gets aborted after fetching few million records from the table due to data issue (either because of bad/invalid data in the columns).
Is there any way to find out which particular record(s) or the column in a table having the invalid data.
We do have some date columns used in the query, which we would like to further check. Appreciate your suggestions and inputs.
Thanks
April 28, 2008 - 12:33 pm UTC
no clue what capabilities 'datastage' might or might not have - this would be a question for datastage.
If you have access to the query and can run it in something we have control over - you can remove all of the implicit/explicit datatype conversions and we can then certainly scan the data...
date validation
A reader, February 26, 2009 - 9:48 pm UTC
Sql Comaprision of dates
Himansu, February 27, 2009 - 3:42 am UTC
the code was quite resourceful but the requirment is to compare two dates....if the date is validated it shows a voilation in the sql database
March 03, 2009 - 9:39 am UTC
umm, the question was about "why am I getting this error", which I corrected.
The already had their logic in place. And well, I redid their logic more efficiently:
ops$tkyte@8i> create or replace
2 FUNCTION check_date_func(in_date in date) RETURN BOOLEAN
3 IS
4 BEGIN
5 return trunc(in_date,'dy') =
6 trunc(new_time(sysdate,'cdt','pdt'),'dy');
7 end;
8 /
so, what exactly what missing in your mind? code fixed, logic implemented, routine demonstrated.