Add basic timezone support
Allthough most dive computers always use local time and don't support timezones at all, there are a few exceptions. There are two different sources of timezone information: - Some of the newer Uwatec/Scubapro devices use UTC internally and also support a timezone setting. This UTC offset is currently taken into account to obtain the dive date/time, but the UTC offset itself is lost. - Uwatec/Scubapro and Reefnet devices rely on the clock of the host system to synchronize the internal device clock and calculate the dive date/time. The consequence is that the resulting date/time is always in the timezone of the host system. In order to preserve this timezone information, the dc_datetime_t structure is extended with a new "timezone" field, containing the UTC offset in seconds. Devices without timezone support will set the field to the special value DC_TIMEZONE_NONE. The dc_datetime_localtime() and dc_datetime_gmtime() functions will automatically populate the new field with respectively the local timezone offset and zero. The dc_datetime_mktime() function will take into account the new timezone field for the conversion to UTC. The special value DC_TIMEZONE_NONE is interpreted as zero.
This commit is contained in:
parent
838f730fb2
commit
156f54302d
@ -158,9 +158,14 @@ AC_CHECK_HEADERS([sys/param.h])
|
|||||||
# Checks for global variable declarations.
|
# Checks for global variable declarations.
|
||||||
AC_CHECK_DECLS([optreset])
|
AC_CHECK_DECLS([optreset])
|
||||||
|
|
||||||
|
# Checks for structures.
|
||||||
|
AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[
|
||||||
|
#include <time.h>
|
||||||
|
])
|
||||||
|
|
||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
AC_FUNC_STRERROR_R
|
AC_FUNC_STRERROR_R
|
||||||
AC_CHECK_FUNCS([localtime_r gmtime_r])
|
AC_CHECK_FUNCS([localtime_r gmtime_r timegm _mkgmtime])
|
||||||
AC_CHECK_FUNCS([getopt_long])
|
AC_CHECK_FUNCS([getopt_long])
|
||||||
|
|
||||||
# Versioning.
|
# Versioning.
|
||||||
|
|||||||
@ -230,9 +230,16 @@ dctool_xml_output_write (dctool_output_t *abstract, dc_parser_t *parser, const u
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (output->ostream, "<datetime>%04i-%02i-%02i %02i:%02i:%02i</datetime>\n",
|
if (dt.timezone == DC_TIMEZONE_NONE) {
|
||||||
dt.year, dt.month, dt.day,
|
fprintf (output->ostream, "<datetime>%04i-%02i-%02i %02i:%02i:%02i</datetime>\n",
|
||||||
dt.hour, dt.minute, dt.second);
|
dt.year, dt.month, dt.day,
|
||||||
|
dt.hour, dt.minute, dt.second);
|
||||||
|
} else {
|
||||||
|
fprintf (output->ostream, "<datetime>%04i-%02i-%02i %02i:%02i:%02i %+03i:%02i</datetime>\n",
|
||||||
|
dt.year, dt.month, dt.day,
|
||||||
|
dt.hour, dt.minute, dt.second,
|
||||||
|
dt.timezone / 3600, (dt.timezone % 3600) / 60);
|
||||||
|
}
|
||||||
|
|
||||||
// Parse the divetime.
|
// Parse the divetime.
|
||||||
message ("Parsing the divetime.\n");
|
message ("Parsing the divetime.\n");
|
||||||
|
|||||||
@ -26,6 +26,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#define DC_TIMEZONE_NONE 0x80000000
|
||||||
|
|
||||||
#if defined (_WIN32) && !defined (__GNUC__)
|
#if defined (_WIN32) && !defined (__GNUC__)
|
||||||
typedef __int64 dc_ticks_t;
|
typedef __int64 dc_ticks_t;
|
||||||
#else
|
#else
|
||||||
@ -39,6 +41,7 @@ typedef struct dc_datetime_t {
|
|||||||
int hour;
|
int hour;
|
||||||
int minute;
|
int minute;
|
||||||
int second;
|
int second;
|
||||||
|
int timezone;
|
||||||
} dc_datetime_t;
|
} dc_datetime_t;
|
||||||
|
|
||||||
dc_ticks_t
|
dc_ticks_t
|
||||||
|
|||||||
@ -122,6 +122,7 @@ atomics_cobalt_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dateti
|
|||||||
datetime->hour = p[0x18];
|
datetime->hour = p[0x18];
|
||||||
datetime->minute = p[0x19];
|
datetime->minute = p[0x19];
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -95,6 +95,7 @@ citizen_aqualand_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *date
|
|||||||
datetime->hour = bcd2dec(p[0x0A]);
|
datetime->hour = bcd2dec(p[0x0A]);
|
||||||
datetime->minute = bcd2dec(p[0x0B]);
|
datetime->minute = bcd2dec(p[0x0B]);
|
||||||
datetime->second = bcd2dec(p[0x0C]);
|
datetime->second = bcd2dec(p[0x0C]);
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -435,6 +435,7 @@ cochran_commander_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dat
|
|||||||
datetime->day = data[layout->datetime + 2];
|
datetime->day = data[layout->datetime + 2];
|
||||||
datetime->month = data[layout->datetime + 5];
|
datetime->month = data[layout->datetime + 5];
|
||||||
datetime->year = data[layout->datetime + 4] + (data[layout->datetime + 4] > 91 ? 1900 : 2000);
|
datetime->year = data[layout->datetime + 4] + (data[layout->datetime + 4] > 91 ? 1900 : 2000);
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
break;
|
break;
|
||||||
case DATE_ENCODING_SMHDMY:
|
case DATE_ENCODING_SMHDMY:
|
||||||
datetime->second = data[layout->datetime + 0];
|
datetime->second = data[layout->datetime + 0];
|
||||||
@ -443,6 +444,7 @@ cochran_commander_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dat
|
|||||||
datetime->day = data[layout->datetime + 3];
|
datetime->day = data[layout->datetime + 3];
|
||||||
datetime->month = data[layout->datetime + 4];
|
datetime->month = data[layout->datetime + 4];
|
||||||
datetime->year = data[layout->datetime + 5] + (data[layout->datetime + 5] > 91 ? 1900 : 2000);
|
datetime->year = data[layout->datetime + 5] + (data[layout->datetime + 5] > 91 ? 1900 : 2000);
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
break;
|
break;
|
||||||
case DATE_ENCODING_TICKS:
|
case DATE_ENCODING_TICKS:
|
||||||
ts = array_uint32_le(data + layout->datetime) + COCHRAN_EPOCH;
|
ts = array_uint32_le(data + layout->datetime) + COCHRAN_EPOCH;
|
||||||
|
|||||||
@ -115,6 +115,7 @@ cressi_edy_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
|||||||
datetime->hour = bcd2dec (p[14]);
|
datetime->hour = bcd2dec (p[14]);
|
||||||
datetime->minute = bcd2dec (p[15]);
|
datetime->minute = bcd2dec (p[15]);
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -100,6 +100,7 @@ cressi_leonardo_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datet
|
|||||||
datetime->hour = p[11];
|
datetime->hour = p[11];
|
||||||
datetime->minute = p[12];
|
datetime->minute = p[12];
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -61,6 +61,47 @@ dc_gmtime_r (const time_t *t, struct tm *tm)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static time_t
|
||||||
|
dc_timegm (struct tm *tm)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_TIMEGM)
|
||||||
|
return timegm (tm);
|
||||||
|
#elif defined (HAVE__MKGMTIME)
|
||||||
|
return _mkgmtime (tm);
|
||||||
|
#else
|
||||||
|
static const unsigned int mdays[] = {
|
||||||
|
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
|
||||||
|
};
|
||||||
|
|
||||||
|
if (tm == NULL ||
|
||||||
|
tm->tm_mon < 0 || tm->tm_mon > 11 ||
|
||||||
|
tm->tm_mday < 1 || tm->tm_mday > 31 ||
|
||||||
|
tm->tm_hour < 0 || tm->tm_hour > 23 ||
|
||||||
|
tm->tm_min < 0 || tm->tm_min > 59 ||
|
||||||
|
tm->tm_sec < 0 || tm->tm_sec > 60)
|
||||||
|
return (time_t) -1;
|
||||||
|
|
||||||
|
/* Number of leap days since 1970-01-01. */
|
||||||
|
int year = tm->tm_year + 1900 - (tm->tm_mon < 2);
|
||||||
|
int leapdays =
|
||||||
|
((year / 4) - (year / 100) + (year / 400)) -
|
||||||
|
((1969 / 4) - (1969 / 100) + (1969 / 400));
|
||||||
|
|
||||||
|
time_t result = 0;
|
||||||
|
result += (tm->tm_year - 70) * 365;
|
||||||
|
result += leapdays;
|
||||||
|
result += mdays[tm->tm_mon];
|
||||||
|
result += tm->tm_mday - 1;
|
||||||
|
result *= 24;
|
||||||
|
result += tm->tm_hour;
|
||||||
|
result *= 60;
|
||||||
|
result += tm->tm_min;
|
||||||
|
result *= 60;
|
||||||
|
result += tm->tm_sec;
|
||||||
|
return result;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
dc_ticks_t
|
dc_ticks_t
|
||||||
dc_datetime_now (void)
|
dc_datetime_now (void)
|
||||||
{
|
{
|
||||||
@ -72,11 +113,23 @@ dc_datetime_localtime (dc_datetime_t *result,
|
|||||||
dc_ticks_t ticks)
|
dc_ticks_t ticks)
|
||||||
{
|
{
|
||||||
time_t t = ticks;
|
time_t t = ticks;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
if (dc_localtime_r (&t, &tm) == NULL)
|
if (dc_localtime_r (&t, &tm) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
|
||||||
|
offset = tm.tm_gmtoff;
|
||||||
|
#else
|
||||||
|
struct tm tmp = tm;
|
||||||
|
time_t t_local = dc_timegm (&tmp);
|
||||||
|
if (t_local == (time_t) -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
offset = t_local - t;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
result->year = tm.tm_year + 1900;
|
result->year = tm.tm_year + 1900;
|
||||||
result->month = tm.tm_mon + 1;
|
result->month = tm.tm_mon + 1;
|
||||||
@ -84,6 +137,7 @@ dc_datetime_localtime (dc_datetime_t *result,
|
|||||||
result->hour = tm.tm_hour;
|
result->hour = tm.tm_hour;
|
||||||
result->minute = tm.tm_min;
|
result->minute = tm.tm_min;
|
||||||
result->second = tm.tm_sec;
|
result->second = tm.tm_sec;
|
||||||
|
result->timezone = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -106,6 +160,7 @@ dc_datetime_gmtime (dc_datetime_t *result,
|
|||||||
result->hour = tm.tm_hour;
|
result->hour = tm.tm_hour;
|
||||||
result->minute = tm.tm_min;
|
result->minute = tm.tm_min;
|
||||||
result->second = tm.tm_sec;
|
result->second = tm.tm_sec;
|
||||||
|
result->timezone = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -124,7 +179,15 @@ dc_datetime_mktime (const dc_datetime_t *dt)
|
|||||||
tm.tm_hour = dt->hour;
|
tm.tm_hour = dt->hour;
|
||||||
tm.tm_min = dt->minute;
|
tm.tm_min = dt->minute;
|
||||||
tm.tm_sec = dt->second;
|
tm.tm_sec = dt->second;
|
||||||
tm.tm_isdst = -1;
|
tm.tm_isdst = 0;
|
||||||
|
|
||||||
return mktime (&tm);
|
time_t t = dc_timegm (&tm);
|
||||||
|
if (t == (time_t) -1)
|
||||||
|
return t;
|
||||||
|
|
||||||
|
if (dt->timezone != DC_TIMEZONE_NONE) {
|
||||||
|
t -= dt->timezone;
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,6 +118,7 @@ diverite_nitekq_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datet
|
|||||||
datetime->hour = p[3];
|
datetime->hour = p[3];
|
||||||
datetime->minute = p[4];
|
datetime->minute = p[4];
|
||||||
datetime->second = p[5];
|
datetime->second = p[5];
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -394,6 +394,7 @@ hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
|||||||
dt.hour = p[3];
|
dt.hour = p[3];
|
||||||
dt.minute = p[4];
|
dt.minute = p[4];
|
||||||
dt.second = 0;
|
dt.second = 0;
|
||||||
|
dt.timezone = DC_TIMEZONE_NONE;
|
||||||
|
|
||||||
if (version == 0x24) {
|
if (version == 0x24) {
|
||||||
if (datetime)
|
if (datetime)
|
||||||
@ -405,8 +406,10 @@ hw_ostc_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
|||||||
|
|
||||||
ticks -= divetime;
|
ticks -= divetime;
|
||||||
|
|
||||||
if (!dc_datetime_localtime (datetime, ticks))
|
if (!dc_datetime_gmtime (datetime, ticks))
|
||||||
return DC_STATUS_DATAFORMAT;
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -118,6 +118,7 @@ mares_darwin_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime
|
|||||||
datetime->hour = p[4];
|
datetime->hour = p[4];
|
||||||
datetime->minute = p[5];
|
datetime->minute = p[5];
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -329,6 +329,7 @@ mares_iconhd_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime
|
|||||||
datetime->day = array_uint16_le (p + 4);
|
datetime->day = array_uint16_le (p + 4);
|
||||||
datetime->month = array_uint16_le (p + 6) + 1;
|
datetime->month = array_uint16_le (p + 6) + 1;
|
||||||
datetime->year = array_uint16_le (p + 8) + 1900;
|
datetime->year = array_uint16_le (p + 8) + 1900;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -200,6 +200,7 @@ mares_nemo_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
|||||||
datetime->hour = p[3];
|
datetime->hour = p[3];
|
||||||
datetime->minute = p[4];
|
datetime->minute = p[4];
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -324,6 +324,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
|
|
||||||
// Convert to a 24-hour clock.
|
// Convert to a 24-hour clock.
|
||||||
datetime->hour %= 12;
|
datetime->hour %= 12;
|
||||||
|
|||||||
@ -121,6 +121,7 @@ oceanic_veo250_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *dateti
|
|||||||
datetime->hour = p[3];
|
datetime->hour = p[3];
|
||||||
datetime->minute = p[2];
|
datetime->minute = p[2];
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
|
|
||||||
if (parser->model == VEO200 || parser->model == VEO250)
|
if (parser->model == VEO200 || parser->model == VEO250)
|
||||||
datetime->year += 3;
|
datetime->year += 3;
|
||||||
|
|||||||
@ -135,6 +135,7 @@ oceanic_vtpro_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
|
|||||||
}
|
}
|
||||||
datetime->minute = bcd2dec (p[0]);
|
datetime->minute = bcd2dec (p[0]);
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
|
|
||||||
// Convert to a 24-hour clock.
|
// Convert to a 24-hour clock.
|
||||||
datetime->hour %= 12;
|
datetime->hour %= 12;
|
||||||
|
|||||||
@ -202,6 +202,8 @@ shearwater_predator_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *d
|
|||||||
if (!dc_datetime_gmtime (datetime, ticks))
|
if (!dc_datetime_gmtime (datetime, ticks))
|
||||||
return DC_STATUS_DATAFORMAT;
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -317,6 +317,7 @@ suunto_d9_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
|||||||
datetime->month = p[5];
|
datetime->month = p[5];
|
||||||
datetime->day = p[6];
|
datetime->day = p[6];
|
||||||
}
|
}
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -178,6 +178,7 @@ suunto_eon_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
|||||||
datetime->minute = bcd2dec (p[4]);
|
datetime->minute = bcd2dec (p[4]);
|
||||||
}
|
}
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -1114,7 +1114,11 @@ suunto_eonsteel_parser_get_datetime(dc_parser_t *parser, dc_datetime_t *datetime
|
|||||||
if (parser->size < 4)
|
if (parser->size < 4)
|
||||||
return DC_STATUS_UNSUPPORTED;
|
return DC_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
dc_datetime_gmtime(datetime, array_uint32_le(parser->data));
|
if (!dc_datetime_gmtime(datetime, array_uint32_le(parser->data)))
|
||||||
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -223,6 +223,7 @@ suunto_vyper_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime
|
|||||||
datetime->hour = p[3];
|
datetime->hour = p[3];
|
||||||
datetime->minute = p[4];
|
datetime->minute = p[4];
|
||||||
datetime->second = 0;
|
datetime->second = 0;
|
||||||
|
datetime->timezone = DC_TIMEZONE_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DC_STATUS_SUCCESS;
|
return DC_STATUS_SUCCESS;
|
||||||
|
|||||||
@ -710,6 +710,8 @@ uwatec_smart_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime
|
|||||||
|
|
||||||
if (!dc_datetime_gmtime (datetime, ticks))
|
if (!dc_datetime_gmtime (datetime, ticks))
|
||||||
return DC_STATUS_DATAFORMAT;
|
return DC_STATUS_DATAFORMAT;
|
||||||
|
|
||||||
|
datetime->timezone = utc_offset * 900;
|
||||||
} else {
|
} else {
|
||||||
// For devices without timezone support, the current timezone of
|
// For devices without timezone support, the current timezone of
|
||||||
// the host system is used.
|
// the host system is used.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user