The question you are asking is at the wrong level. In Posix (generally, in Unix land), a file system object (file, directory, ...) has the three time stamps you mentioned. The Posix standard sets exact rules on the effect which file system operations have on those three time stamps. For example: creating a file (with the creat() call) sets the ctime; writing to a file with the write() call sets the mtime, and reading from a file with the read() call sets the atime. Furthermore, the utimes() system call allows a program to modify the atime and the mtime. While the rules for files seem simple at this level, it gets exceedingly complicated when taking account the times on more complex objects (directories, soft links), and for other operations (such as chmod or stat). While I have worked on implementing file systems, I do not claim that I can remember these rules by heart, so you'll just have to read the posix standard documents yourself.
The reason your questions are at the wrong level: the rules for file stamps apply to system calls. But the operations you are talking about (copy, move, download) are much more complex than individual system calls, and can be built many different ways. For example: are you using cp, scp, rsync, tar, dump, ... to perform the copy? Most of these programs have the habit of transferring file "attributes" too, and updating the resulting file to have the "correct" attributes. So knowing about the effect of individual read() and write() operations is pointless, since those type of programs will call utimes() at the end anyhow, and wipe all that stuff out.
Now, once you add Windows-style file systems into the mix, it gets seriously crazy. All three file systems you mention (fat, exfat, ntfs) come from Windows, and Windows implements some of these times differently. In particular, the creation time of a Windows file has very different semantics from the ctime of a Unix file; I know that some file systems implement that by keeping four time stamps for each object, and using complicated tricks to differentiate between the two versions of the ctime. When using windows file systems in a Unix environment, some compromises have to be made, and those compromises will be different for different file systems on different Unix implementation.
To make matters worse: atime updates can be turned off, and in many production environments are (to help with performance). And the granularity of these time stamps is different on various file systems. AFAIK, most native Unix file systems keep them with at least 1-second granularity and update them correctly, but some of the Windows file systems aren't even capable of storing them at that granularity (if I remember, right, atime is only stored with 1-day granularity on FAT), and some Windows file systems are guaranteed to have better granularity (I think NTFS inherited its time-stamp accuracy from Digital's VMS, and it is milliseconds).
And if you think you understand it now, you're still wrong: Most Unix machines are configured with the system clock running in UTC, and individual processes running in time zones. In that case, the time stamp stored in the file system is in UTC, and is being converted to local time when it is displayed. But most old-style Windows file systems (definitely fat) don't have a concept of time zone, and most real-world file systems are set in local time, so time zone becomes a mount concept rather than a process concept. This tends to lead to hilarity, like mounting the SD card from your digital camera on Unix and discovering that you've been taking lots of pictures at 3am.
So far, I haven't answered the question in the slightest. And as explained above, it is not possible to give a simple, coherent answer. I could give you an answer that is simple but wrong: If the file systems you are talking about were real Unix file systems, and if the copy/move/download operation were implemented trivially (by calling open() on the source file, creat() on the target file, and then a sequence of read() on the source and write() on the target, followed by two close() calls), then the ctime of the target file would be when it was created, and mtime and atime would be when the last byte was written to it, independent of what the source file was. But this example is pretty unrealistic.
Please restate your question more concretely: What is your real problem?