Today() is an impure function because its result is dependent upon something that you do not give it; specifically, the current system time. Therefore, its result is not deterministic when based only on the inputs provided at invocation.
A pure function would be int Add(int a, int b) {return a + b;}
. The function works solely with what it is given, and uses no other external state data. The natural result of this is that you can Add(2,2)
and get 4 from now until the end of time. In addition, because the function doesn't change any external state (it has no "side effects"), Add()ing 2 and 2 from now until the end of time won't change anything else in the system, unless you then assign the result of the function to a variable or otherwise use the value to update state (which is not an operation performed by the function itself). Virtually all classical mathematical operations are pure functions and can be implemented as such.
Today(), on the other hand, may produce the same value when called two times in a row, but not if called repeatedly for several days. This is because it is dependent on external state data which is not provided by you as a parameter to the function. As a result, it is impossible, within the boundaries of the program, to control the result of the Today() function. It will produce a given value on a given day, and will never produce that value on any other day, unless you change the system clock of the computer on which it is run (a change generally occurring outside the boundaries of the program).
An impure function is not necessarily a bad thing; impure functions are required, even in functional languages, to interact with anything outside the boundaries of the program, such as data stores, communication pipelines, UI displays, peripheral devices, etc. A program that does not do any of these things is a program that is sharply limited in its utility; I would even go so far as to call such a program trivial, as without any means to accept input or any avenue to inform you of its output, it might as well be doing nothing. Programs written in functional languages can have only the input provided by the runtime and produce an output reported to the runtime without any explicitly defined impure methods, but that's because the runtime is abstracting away all these impure details of working within an imperfect computer system, so that the program itself can be structured in terms of a nested set of mathematical expressions that the runtime then evaluates given initial input.
It is simply a Very Good Thing to know which of the functions you are using are pure and which ones are not, so that you can make good decisions about how they are used. Impure functions, because they do things or are dependent on things that are not apparent from their usage, may behave unpredictably given only knowledge of the usage. Further knowledge of the purpose of the function, and thus what it needs from or does to external state, is required in order to place a system that uses it in a consistent state and thus to expect a deterministic result.