Q:

na.fill for date showing the unexpected results

I tried to replace an NA na value in a date vector with another value using zoo::na.fill, but it replaced my NA value with "1970-01-02" rather than the value I specified:
library(zoo)
a <- as.Date(c(NA, '2018-01-01'))

na.fill(a, as.Date('2018-01-02'))
[1] "1970-01-02" "2018-01-01"

Why did it happen? Is it a bug or I need to specify something so that it can work as expected
  Note: I know that we can use a[is.na(a)] <- as.Date('2018-01-02') but this question is about na.fill in zoo

A:

the beloved zoo::na.* functions
The zoo package is a wonderful source of functions for handling NA values, and they are widely used on non-zoo objects all the time, but they were written for time series with numeric values with an index. The behaviour of the zoo::na.* sometimes works as expected on non-numeric vectors, but sometimes not, as in the case of zoo::na.fill and a few others. 
overview of their behaviour on Date vectors
Some sample data. We use zoo::as.Date so I don't have to give an origin each time.
(a <- zoo::as.Date(c(10000, NA, 10002)))
#> [1] "1997-05-19" NA           "1997-05-21"
(b <- zoo::as.Date(10001))
#> [1] "1997-05-20"

zoo::na.aggregate(a) # As expected
#> [1] "1997-05-19" "1997-05-20" "1997-05-21"
zoo::na.approx(a) # Converts to numeric
#> [1] 10000 10001 10002
zoo::as.Date(zoo::na.approx(a)) # Workaround
#> [1] "1997-05-19" "1997-05-20" "1997-05-21"
zoo::na.fill(a, b) # Coerces b to logical TRUE then to numeric - see below
#> [1] "1997-05-19" "1970-01-02" "1997-05-21"
zoo::as.Date(zoo::na.fill(as.numeric(a), as.numeric(b))) # Workaround
#> [1] "1997-05-19" "1997-05-20" "1997-05-21"
zoo::na.locf(a) # As expected
#> [1] "1997-05-19" "1997-05-19" "1997-05-21"
zoo::na.spline(a) # Converts to numeric
#> [1] 10000 10001 10002
zoo::as.Date(zoo::na.spline(a)) # Workaround
#> [1] "1997-05-19" "1997-05-20" "1997-05-21"
zoo::na.trim(c(NA, NA, a, NA, NA)) # Converts to numeric
#> [1] 10000    NA 10002
zoo::as.Date(zoo::na.trim(c(NA, NA, a, NA, NA))) # Workaround
#> [1] "1997-05-19" NA           "1997-05-21"

details of zoo::na.fill on Date vectors
In the source code for na.fill.zoo (which eventually does the work) there is this:
as.cls <- if (is.integer(coredata(object))) {
      as.integer
    }
    else if (is.numeric(coredata(object))) {
      as.numeric
    }
    else if (is.character(coredata(object))) {
      as.character
    }
    else {
      as.logical
    }

And class(coredata(object)) is the same as class(a) which is Date. Since there is no Date option, as.cls defaults to as.logical. 
The next thing that happens is the fill argument (essentially) has as.cls applied to it. In this case fill is a non-zero Date, which is coerced to the number 1 which is used to fill in the NA.
Then at the end the return value is coerced to the class of object which is date. And of course as.Date(1) is 1970-01-02.

