Locales

Sami, it's really not that bad.

There are, as you say, many variables to modify the behaviour of several programs. What you seem to have missed, though, is that there are really only four types of variables:

LANGUAGE
This is a GNU-specific extension which allows you to set fallbacks on different languages than "C" (which is locale-speak for "disable translation completely"). It somewhat overrides LC_ALL, but then at the same time it doesn't. Pretty strange thing, this variable. See "info gettext" and search for LANGUAGE if you want the ugly details.
LC_ALL
This variable exists to (temporarily) override any locale-related variable; for instance, when you want to file a bugreport in grep and you want to make sure you don't get any output that might be unintelligible for the developer, you could run LC_ALL=C grep --broken-parameter to temporarily disable locales. Using LC_ALL completely and utterly overrides anything else, so you probably don't want to set it in the general case.
LC_NUMERIC, LC_PAPER, LC_MESSAGES,...
These variable are meant to be used to divert from the defaults. For instance, as in your case, a user may want to have messages in en_US but have dates and papersizes etc be as is common in fi_FI. In that case, you'd set the default to fi_FI but set LC_MESSAGES (which specifies the language in which messages are set) to en_US. Or you might be a Dutch-speaking Belgian guy living in the US. You'd set the default to nl_BE.utf-8; but since A4 paper isn't easy to come by where you live, you'd set LC_PAPER to en_US.
LANG
This variable is used for "the default". If you haven't specified LC_ALL, nor the other relevant LC_* variable, then the value of LANG is used for whatever you're trying to do.

So what you really want to do is to set LANG to be fi_FI.utf-8, but have LC_MESSAGES be either en_US or, perhaps, C. This should give you english messages, but finnish conventions for date and number formats.

Do note, though, that this is only the theory. It may be the case that some software is broken and doesn't look at the correct LC_* variable. If that happens to be true for some software you've seen, just file a bug...