Here is a more convenient workaround. After executing this code once any calls to toLocaleString/toLocaleTimeString/toLocaleDateString behave as if "de-DE" was passed explicitly. It should not be executed twice.
It might be considered bad practice to change the prototype of built-in objects and functions. One negative side effect of this work-around is the fact that .toLocaleString() does not behave like .toLocaleString(navigator.language) anymore.
// Hooks Number's and Date's .toLocale...() to use "de-DE" in case no language is passed expliclitly.
(function(defaultLocale) {
function hookObjectFunction(obj, name, hook) {
const orig = obj[name];
obj[name] = function(...args) { return hook.call(this, orig, args); }
}
function defaultLocaleHook(orig, args) {
args[0] = args[0] || defaultLocale;
return orig.apply(this, args);
}
hookObjectFunction(Date.prototype, "toLocaleDateString", defaultLocaleHook);
hookObjectFunction(Date.prototype, "toLocaleTimeString", defaultLocaleHook);
hookObjectFunction(Date.prototype, "toLocaleString", defaultLocaleHook);
hookObjectFunction(Number.prototype, "toLocaleString", defaultLocaleHook);
})("de-DE");
EDIT: Fixed a bug (orig.call() changed to orig.apply())