Use time() instead of 0 for unknown last modified

Also split out caching logic into protected methods.