Why does DBMS_JOB.SUBMIT execute immediately when NEXT_DATE is in the future?
Setting the job to "unbroken" reschedules it: 

    SQL&gt; DECLARE
  2    X NUMBER;
  3  BEGIN
  4    SYS.DBMS_JOB.SUBMIT
  5    ( job       =&gt; X
  6     ,what      =&gt; 'BEGIN  NULL;  END;'
  7     ,next_date =&gt; to_date('24/04/2012 12:00:00','dd/mm/yyyy hh24:mi:ss')
  8     ,interval  =&gt; 'TRUNC(SYSDATE+1)+12/24'
  9     ,no_parse  =&gt; FALSE
 10    );
 11    SYS.DBMS_OUTPUT.PUT_LINE('Job Number is: ' || to_char(x));
 12
 13  COMMIT;
END;
 14   15  /
Job Number is: 5

PL/SQL procedure successfully completed.


SQL&gt; alter session set nls_date_format='DDMMYYYY HH24:MI:SS';

Session altered.

SQL&gt; select job,last_date,next_date,broken from dba_jobs where job=5;

       JOB LAST_DATE         NEXT_DATE         B
---------- ----------------- ----------------- -
         5                   24042012 12:00:00 N

SQL&gt; BEGIN
  2  SYS.DBMS_JOB.BROKEN(job=&gt;5,broken=&gt;FALSE);
  3  END;
  4  /

PL/SQL procedure successfully completed.

SQL&gt; select job,last_date,next_date,broken from dba_jobs where job=5;

       JOB LAST_DATE         NEXT_DATE         B
---------- ----------------- ----------------- -
         5                   23042012 21:55:49 N

SQL&gt;


Once you hit commit, the job scheduler sees the job and executes it:

SQL&gt; select job,last_date,next_date,broken from dba_jobs where job=5;

       JOB LAST_DATE         NEXT_DATE         B
---------- ----------------- ----------------- -
         5                   23042012 21:55:49 N

SQL&gt; commit;

Commit complete.

SQL&gt;  select job,last_date,next_date,broken from dba_jobs where job=5;

       JOB LAST_DATE         NEXT_DATE         B
---------- ----------------- ----------------- -
         5 23042012 21:59:06 24042012 12:00:00 N

SQL&gt;


Moral of the story: If creating a new job, don't include a call to DBMS_JOB.BROKEN().