> time() unnecessarily takes a pointer argument to write to
Minor cosmetic issue.
> strftime() has to write to a string of a fixed length it can not dynamically allocate (This is less legacy than it is bad design)
This is often a good way to structure string functions in C. The fact that TFA repeated the constant 40 instead of using sizeof() immediately signals that they are unfamiliar with the idioms. A "you problem".
Doing heap allocation where it is not required could be a problem for some use cases.
> localtime() needs the pointer to a time_t value even though it does not change it because of register size concerns on PDP-11’s
Also minor and cosmetic.
> sleep() cannot sleep for sub-second amounts of time, usleep() is deprecated and it’s alternative nanosleep() requires you to define variables
sleep(3) is not really a "time function" in the sense of the others mentioned, it is a thread scheduler function. As such it kind of exists in a different universe. This is also shown by the fact that it's part of POSIX and not the C standard, like time(2) is.