Hi Pat
Sorry for the delay getting back to you, we have had problems here on toolset.com and the forums (hopefully this reply will reach you okay).
I spent a good while digging into this yesterday.
To recap, the problem is that when you enter a value for a Types date field (either in the back end or via a front-end CRED form) that gets saved in the database in a timestamp format in the local time (based on the site settings) without first converting it to UTC. (Timestamps, by definition, should be UTC.)
Ordinarily this doesn't affect most users, but it does affect you if you retrieve the date field value directly from wp_postmeta for some purpose and expect the date to be UTC-based.
My instinct was to intervene so that when the field is saved it is first converted to UTC, but it becomes too complicated trying to anticipate the various ways the value might be retrieved, when it would also need to be manipulated to restore the value back to the local time.
So I changed tack and decided that the best solution is to live with it being stored as a false timestamp (not UTC), and provide a generic solution to convert the field value to UTC after you have retrieved the value, so that you then know what you are dealing with.
Here's a function that should do that for you (it makes the adjustment based on the site timezone setting, although you can pass a value for the timezone if you want to use something else for some reason):
/**
* Types date fields are stored as "timestamps" without first converting to UTC
* Pass the stored value of a types date field through this function to convert to a UTC-based timestamp
* based on the site timezone setting (or a specified timezone setting such as "Europe/Paris")
*
* Usage e.g.
* $value = get_postmeta( $id, 'wpcf-custom-date', true );
* $valueUTC = types_date_to_utc( $value );
*
*/
function types_date_to_utc( int $timestamp, $timezone = "" ){
if ( $timestamp ) {
if ( empty ($timezone) ) {
// get the site timezone
$timezone = get_option("timezone_string");
if ( empty($timezone) ){
// use the offset instead
$offset = get_option("gmt_offset");
$timezone = sprintf("%+03d:00", $offset);
}
}
$timezone_object = new DateTimeZone($timezone);
$datetime = DateTime::createFromFormat('U', $timestamp);
$offset = $timezone_object->getOffset($datetime);
$timestamp = $timestamp - $offset;
}
return $timestamp;
}
It adjusts for what the time differential is at the point in time of the date. That is, if you passed a time from yesterday, it would know the differential then was 2 hours, but if you passed a date in November it would know that the differential then is 1 hour.
Is that something you can work with?