No, there's no systematic, built-in mechanism to do a two string swap as you describe. It's really not needed since you can do it using standard regex/replacement semantics.
For instance:
:s/^hello\(.*\)today$/goodbye\1tomorrow
Obviously, this only works if the two strings are at the start and end of the string. In other cases, you'll need to modify the regex but the same idea of using capture-group(s) and \#
in the replacement will usually be applicable.
Now if you want to replace multiple occurrences of the two strings you're really better off running two substitutions. You can put them on the same line...
:s/today/tomorrow/g | :s/hello/goodbye/g
This actually could be done in a single substitution using a sub-replace expression but a general solution would be relatively complex and won't buy you much, really, compared to the simple pair of substitutions, above. (Note that a lot of people find sub-replace expressions hard to understand.) That being said, take a look at the link in the comment from @Rich for examples and I have a modestly well-received :) answer with a relatively deep dive into them, too.
And, of course, you could implement this functionality using a custom function (vimscript). But that wasn't your question. :)
Update: If you're willing to install a plugin you can get precisely the functionality you described with Tim Pope's vim-abolish. For your example the solution would look like this:
:S/{hello,today}/{goodbye,tomorrow}/gw
Thanks to @PeterRincker for this suggestion. He also recommends a vimcast episode to learn more about the plugin.