Is there a way to determine which user changed a custom field (and when)?

By default, no. When WP Core saves postmeta (i.e. custom fields) in the database, it associates it to the parent post – not the current revision, and the database does not store a timestamp for when postmeta was stored.

If you want to keep track of future postmeta changes, you can add code to version it. This will associate the postmeta to the corresponding revision ID, instead of the parent post ID. Then, if you come across a page with postmeta you want to track down, you can check in the database, revision by revision: search for the postmeta where the meta_key corresponds to that piece of data (this will be the name of your custom field) and where the post_id equals the ID of the revision you’re checking. Once you find the oldest revision ID where that postmeta was set, you can then check in the revision history to see who the author was of that revision, which is the person who changed the postmeta to that value.