As a short follow-up to a previous post regarding implicit date conversion and the NLS_DATE_FORMAT, which governs the default date format Oracle will use with the TO_DATE and TO_CHAR functions, I forgot to mention a couple of things:
- how to determine the current NLS_DATE_FORMAT setting
- changing the NLS_DATE_FORMAT via DBMS_SESSION
As noted in the previous post, the NLS_DATE_FORMAT setting is session modifiable via the ALTER SESSION command, e.g.:
ALTER SESSION SET nls_date_format = 'dd/mm/yyyy'
In order to work out what NLS_DATE_FORMAT your session has been configured with then the NLS_SESSION_PARAMETERS view will provide this information:
SELECT value FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT'
If you wanted to work out what the format was for the database, as opposed to your session, then you can query the NLS_DATABASE_PARAMETERS view instead:
SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_DATE_FORMAT'
NLS_DATE_FORMAT may also be set via the DBMS_SESSION.SET_NLS routine. One advantage to setting it via DBMS_SESSION is that it can done from within PL/SQL without having to go through the messy business of dynamic SQL as ALTER SESSION is not directly callable from PL/SQL. The call is simply:
dbms_session.set_nls ('nls_date_format','''dd/mm/yyyy''')
Note, for string NLS parameter values the embedded quotes need to be contained in the string argument to the procedure call, hence the 3 single quotes on either side of the format parameter.
The following is a basic illustration of the above points, setting the NLS_DATE_FORMAT via DBMS_SESSION and querying the session and database properties:
SQL> EXEC dbms_session.set_nls ('nls_date_format','''dd/mm/yyyy''') PL/SQL procedure successfully completed. SQL> SELECT value 2 FROM nls_session_parameters 3 WHERE parameter = 'NLS_DATE_FORMAT' 4 / VALUE ---------------------------------------- dd/mm/yyyy SQL> SELECT value 2 FROM nls_database_parameters 3 WHERE parameter = 'NLS_DATE_FORMAT' 4 / VALUE ---------------------------------------- DD-MON-RR
I am trying to find all occurrences (including those that span midnight) where shift_brk_start & shift_brk_end fall on or within leave_start_time and leave_end_time
1. the following feilds are assigned a date time format by default.
wd.WRKD_START_TIME
wd.WRKD_END_TIME
sb.SHFTBRK_DEF_START
2. the date associated with following is the actual work date of an employee
wd.WRKD_START_TIME
wd.WRKD_END_TIME
3. the date associated with sb.SHFTBRK_DEF_START is the shift creation date, hence sb.SHFTBRK_DEF_START date will never match date for wd.WRKD_START_TIME, wd.WRKD_END_TIME
4. to get shift break end time i need to add
sb.SHFTBRK_DEF_START + sb.SHFTBRK_MINUTES
————
example of output:
APS EMP_NAME WORK_DATE LEAVE_START_TIME LEAVE_END_TIME SHIFT_BRK_START SHIFT_BRK_END SHIFT_BREAK_MINUTES
3100476801 Tania, Ball 01.08.2013 21:30 00:51 21:30 21:45 15
3100476801 Tania, Ball 05.08.2013 21:30 00:51 21:30 21:45 15
3100476801 Tania, Ball 06.08.2013 21:30 00:51 21:30 21:45 15
the issue is that my script is still returning values I dont need to see, for example below the BREAK time (11:00-11:30) is outside of the leave time ( 11:30-13:30) therefore i
do not need to see this record
2504358201 Samantha, John 01.08.2013 11:30 13:30 11:00 11:30 30
—code
select
e.EMP_NAME as APS,
e.EMP_FULLNAME as EMP_Name,
TO_CHAR(ws.WRKS_WORK_DATE,’dd.mm.yyyy’) as Work_Date,
to_char((wd.WRKD_START_TIME), ‘hh24:mi’) as Leave_Start_Time,
to_char((wd.WRKD_end_TIME), ‘hh24:mi’) as Leave_End_Time,
to_char(sb.SHFTBRK_DEF_START,’hh24:mi’) as shift_brk_Start,
to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, ‘hh24:mi’) as shift_brk_end,
sb.SHFTBRK_MINUTES as shift_break_minutes
from
workbrain.WORK_SUMMARY ws,
workbrain.employee e,
workbrain.work_detail wd,
workbrain.TIME_CODE tc,
workbrain.shift s,
workbrain.shift_break sb,
workbrain.EMPLOYEE_SCHEDULE es
where
ws.emp_id=e.emp_id
and wd.WRKD_MINUTES = current_date
and ws.WRKS_WORK_DATE = es.WORK_DATE
and ws.emp_id = es.emp_id
and ws.shft_id = es.EMPSKD_ACT_SHIFT_ID
and es.EMPSKD_ACT_SHIFT_ID = s.SHFT_ID
and s.SHFT_ID = sb.SHFT_ID
and (
(to_date(to_char(wd.WRKD_START_TIME, ‘dd-mm-yyyy’) || ‘ ‘ || to_char(sb.SHFTBRK_DEF_START,’hh24:mi’), ‘dd-mm-yyyy hh24:mi’) wd.WRKD_START_TIME) OR
(to_date(to_char(wd.WRKD_START_TIME, ‘dd-mm-yyyy’) || ‘ ‘ || to_char(sb.SHFTBRK_DEF_START,’hh24:mi’), ‘dd-mm-yyyy hh24:mi’) wd.WRKD_end_TIME) OR
(to_date(to_char(wd.WRKD_START_TIME, ‘dd-mm-yyyy’) || ‘ ‘ || to_char(sb.SHFTBRK_DEF_START,’hh24:mi’), ‘dd-mm-yyyy hh24:mi’) > wd.WRKD_START_TIME and to_date(to_char(wd.WRKD_START_TIME, ‘dd-mm-yyyy’) || ‘ ‘ || to_char(sb.SHFTBRK_DEF_START,’hh24:mi’), ‘dd-mm-yyyy hh24:mi’) + (sb.SHFTBRK_MINUTES+1)*.000694 < wd.WRKD_end_TIME) OR
(to_date(to_char(wd.WRKD_START_TIME, 'dd-mm-yyyy') || ' ' || to_char(sb.SHFTBRK_DEF_START,'hh24:mi'), 'dd-mm-yyyy hh24:mi') = wd.WRKD_END_TIME and to_date(to_char(wd.WRKD_START_TIME, 'dd-mm-yyyy') || ' ' || to_char(sb.SHFTBRK_DEF_START,'hh24:mi'), 'dd-mm-yyyy hh24:mi') + (sb.SHFTBRK_MINUTES+1)*.000694 = wd.WRKD_end_TIME)
)
group by
e.EMP_NAME,
ws.WRKS_WORK_DATE,
wd.WRKD_end_TIME,
wd.WRKD_START_TIME,
sb.SHFTBRK_DEF_START,
to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, 'hh24:mi'),
e.EMP_FULLNAME,
sb.SHFTBRK_MINUTES
Hi Despina,
It seems that you have 2 sets of start and end date/time fields: leave and break. If you want to find those occurrences where there is an intersection of the two time periods then you can use the following:
shift_brk_start BETWEEN leave_start_time AND leave_end_time
OR
leave_start_time BETWEEN shift_brk_start AND shift_brk_end
I’ve described the above in terms of the data concepts and not the underlying formulae. If the break details you have are only provided in terms of time with no date component then can you work out the break start using a formula of:
— get the start of the break for the leave date
to_date(to_char(wd.WRKD_START_TIME, ‘dd-mm-yyyy’) || ‘ ‘ || to_char(sb.SHFTBRK_DEF_START,’hh24:mi’), ‘dd-mm-yyyy hh24:mi’)
— if the break begins before the start of the leave date then move it to the next day
CASE WHEN (TO_NUMBER(shift_brk_start,’hh24mi’) < TO_NUMBER(leave_start_time,'hh24mi'))
THEN 1
END
Does this help you?
Mark
thankyou so much, i fainally got it working as follows:
and
(
(to_date(to_char(wd.WRKD_START_TIME, ‘dd.mm.yyyy’) || ” || to_char(sb.SHFTBRK_DEF_START, ‘hh24:mi’), ‘dd.mm.yyyy hh24:mi’) (wd.WRKD_start_TIME))—1
OR(to_date(to_char(wd.WRKD_START_TIME, ‘dd.mm.yyyy’) || ” || to_char(sb.SHFTBRK_DEF_START, ‘hh24:mi’), ‘dd.mm.yyyy hh24:mi’) =(wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, ‘dd.mm.yyyy’) || ” || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, ‘hh24:mi’), ‘dd.mm.yyyy hh24:mi’) = (wd.WRKD_end_TIME))–4
OR(to_date(to_char(wd.WRKD_START_TIME, ‘dd.mm.yyyy’) || ” || to_char(sb.SHFTBRK_DEF_START, ‘hh24:mi’), ‘dd.mm.yyyy hh24:mi’) =(wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, ‘dd.mm.yyyy’) || ” || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, ‘hh24:mi’), ‘dd.mm.yyyy hh24:mi’) > (wd.WRKD_end_TIME))—5
OR(to_date(to_char(wd.WRKD_START_TIME, ‘dd.mm.yyyy’) || ” || to_char(sb.SHFTBRK_DEF_START, ‘hh24:mi’), ‘dd.mm.yyyy hh24:mi’) =(wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, ‘dd.mm.yyyy’) || ” || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, ‘hh24:mi’), ‘dd.mm.yyyy hh24:mi’) (wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, ‘dd.mm.yyyy’) || ” || to_char(sb.SHFTBRK_DEF_START + (sb.SHFTBRK_MINUTES+1)*.000694, ‘hh24:mi’), ‘dd.mm.yyyy hh24:mi’) (wd.WRKD_START_TIME) and
to_date(to_char(wd.WRKD_START_TIME, ‘dd.mm.yyyy’) || ” || to_char(sb.SHFTBRK_DEF_START, ‘hh24:mi’), ‘dd.mm.yyyy hh24:mi’) (wd.WRKD_end_TIME))—2
)
Hii Everyone, i just read this discussion forum and it’s great, but can anyone tell me how to find out the date format of operating system. The date format of operating system is different from date format of database.
The date format of operating system can be found out by going to control_panel>Region and language>formats( which is actually the name of tab)>Long Date.
Now in the long date, you may see the date format which the operating system is showing.
So please give me any query via which the date format of operating system is shown??????
Hi Ankit,
You’re out of luck. Oracle doesn’t provide a facility to read the information you’re after. You can probably do this in Java and expose it via a Java stored procedure. The documentation has the details of how to do this kind of thing, see:
http://docs.oracle.com/cd/E16655_01/java.121/e17658/chthree.htm#CACJJHGI
However, I’m not sure why you need to do this. The OS date format is not something that would be changed on a production system so it’s static and your application shouldn’t need to continually read it. An external application could write to format to an application configuration table when the application is installed and that would be it. Even if it could be read via Java you will probably find that it does not perform very well and, depending on how often it is referenced, you may need to cache it locally in any case.
Mark