date.php shows all posts. how to fix it?

Take a very good look at the Template Hierarchy.

You should not need to be creating new queries for these pages. As near as I can WordPress, has already done the work. You are just doing it over again. That is inefficient.

The only thing that I see that you might need to adjust is the posts_per_page argument. You can do that with pre_get_posts.

add_action(
  'pre_get_posts',
  function($qry) {
    if($qry->is_main_query() && ($qry->is_date() || $qry->is_category())) {
      $qry->set('posts_per_page',3);
    }
  }
);

I am also not sure why you need a function for this. The templates themselves should be sufficient. To reuse your formatting code put everything inside the while into another file and load it with get_template_part. Your templates would then look something like this:

if(have_posts()) {
  print ('<div class="row">'); 
  while (have_posts()) {
    the_post();
    get_template_part('datecatformat'); // loads datecatformat.php
  }
}

By reworking things this way, you fix your problem by allowing WordPress to do what it already does pretty well instead of clobbering its queries with your own.