Shortcodes output in the wrong order

the_time() is the problem here. It echoes its output. Shortcodes, effectively, happen in this order:

  1. The text containing shortcodes is parsed to find shortcodes.
  2. Each shortcode is executed and its output stored.
  3. Each shortcode is replaced with its output.

The problem is that if you echo inside a shortcode, its output will be printed to the screen at step 2, rather than at the proper place in step 3.

So what’s happening is:

  1. The text, [c][year] is parsed. The [c] and [year] shortcodes are found.
  2. [c] is executed, and © is stored for later replacement.
  3. [year] is executed, the output of the_time() is printed to the screen, and then null is stored for later replacement.
  4. © is printed to the screen where [c] was.
  5. [year] is replaced with nothing, because the shortcode callback returned nothing.

So you can see that the year is output before the copyright symbol because it was output as part of executing the shortcode in step 3, before the copyright symbol was output in step 4.

You need to replace the_time() with get_the_time() so that the year is returned to the $year variable, not printed.