In either case, you are potentially looking at a datatype conversion, so if the 2nd one works better for you, then by all means use it.
In (1), even if TMP has the correct datatype, then the insert-select will invoke a data conversion as data is loaded into TMP, eg insert into (date_col) select string_col from ..., does a conversion even if you havent explicitly coded the TO_DATE function.
The same of course applies in (2), just the the data conversion is now explicit in the SELECT, but the net effect will be similar.
If there is lots of duplicated date, then you might get some benefit with scalar query caching, eg
SQL> create table t1 ( x date );
Table created.
SQL> create table t2 ( s varchar2(20));
Table created.
SQL>
SQL> insert /*+ APPEND */ into t2
2 select '2016-01-01' from
3 ( select 1 from dual connect by level <= 1000 ),
4 ( select 1 from dual connect by level <= 10000 );
10000000 rows created.
SQL>
SQL> commit;
Commit complete.
SQL>
SQL> set timing on
SQL> insert /*+ APPEND */ into t1 select to_date(s,'yyyy-mm-dd') from t2;
10000000 rows created.
Elapsed: 00:00:19.18
SQL> commit;
Commit complete.
SQL> drop table t1 purge;
Table dropped.
SQL> create table t1 ( x date );
Table created.
SQL> set timing on
SQL> insert /*+ APPEND */ into t1 select
2 ( select to_date(s,'yyyy-mm-dd') from dual )
3 from t2;
10000000 rows created.
Elapsed: 00:00:09.28
SQL> commit;
Commit complete.
SQL>
SQL>