Support for optionally store timestamps in GMT.

This commit is contained in:
Vreixo Formoso 2008-01-27 14:23:59 +01:00
parent 9c43f17aea
commit b97121a0e9
9 changed files with 160 additions and 105 deletions

View File

@ -281,7 +281,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0);
iso_bb(rec->block, block, 4);
iso_bb(rec->length, len, 4);
iso_datetime_7(rec->recording_time, t->now);
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
rec->flags[0] = (node->type == ECMA119_DIR) ? 2 : 0;
iso_bb(rec->vol_seq_number, 1, 2);
rec->len_fi[0] = len_fi;
@ -352,9 +352,9 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37);
iso_datetime_17(vol.vol_creation_time, t->now);
iso_datetime_17(vol.vol_modification_time, t->now);
iso_datetime_17(vol.vol_effective_time, t->now);
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt);
vol.file_structure_version[0] = 1;
free(vol_id);
@ -823,6 +823,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->rockridge = opts->rockridge;
target->joliet = opts->joliet;
target->iso1999 = opts->iso1999;
target->always_gmt = opts->always_gmt;
target->ino = 0;
target->omit_version_numbers = opts->omit_version_numbers
| opts->max_37_char_filenames;
@ -1237,6 +1238,7 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->replace_uid = 1;
wopts->replace_gid = 1;
wopts->replace_timestamps = 1;
wopts->always_gmt = 1;
break;
default:
/* should never happen */
@ -1462,6 +1464,15 @@ int iso_write_opts_set_default_timestamp(IsoWriteOpts *opts, time_t timestamp)
return ISO_SUCCESS;
}
int iso_write_opts_set_always_gmt(IsoWriteOpts *opts, int gmt)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->always_gmt = gmt ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_output_charset(IsoWriteOpts *opts, const char *charset)
{
if (opts == NULL) {

View File

@ -30,6 +30,9 @@ struct iso_write_opts {
unsigned int joliet :1;
unsigned int iso1999 :1;
/* allways write timestamps in GMT */
unsigned int always_gmt :1;
/*
* Relaxed constraints. Setting any of these to 1 break the specifications,
* but it is supposed to work on most moderns systems. Use with caution.
@ -207,6 +210,9 @@ struct ecma119_image
unsigned int eltorito :1;
unsigned int iso1999 :1;
/* allways write timestamps in GMT */
unsigned int always_gmt :1;
/* relaxed constraints */
unsigned int omit_version_numbers :1;
unsigned int allow_deep_paths :1;

View File

@ -695,7 +695,7 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
rec->len_dr[0] = len_dr;
iso_bb(rec->block, block, 4);
iso_bb(rec->length, len, 4);
iso_datetime_7(rec->recording_time, t->now);
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
rec->flags[0] = (node->type == ISO1999_DIR) ? 2 : 0;
iso_bb(rec->vol_seq_number, 1, 2);
rec->len_fi[0] = len_fi;
@ -768,9 +768,9 @@ int iso1999_writer_write_vol_desc(IsoImageWriter *writer)
strncpy_pad((char*)vol.abstract_file_id, abstract_file_id, 37);
strncpy_pad((char*)vol.bibliographic_file_id, biblio_file_id, 37);
iso_datetime_17(vol.vol_creation_time, t->now);
iso_datetime_17(vol.vol_modification_time, t->now);
iso_datetime_17(vol.vol_effective_time, t->now);
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt);
vol.file_structure_version[0] = 1;
free(vol_id);

View File

@ -734,7 +734,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
rec->len_dr[0] = len_dr;
iso_bb(rec->block, block, 4);
iso_bb(rec->length, len, 4);
iso_datetime_7(rec->recording_time, t->now);
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
rec->flags[0] = (node->type == JOLIET_DIR) ? 2 : 0;
iso_bb(rec->vol_seq_number, 1, 2);
rec->len_fi[0] = len_fi;
@ -831,9 +831,9 @@ int joliet_writer_write_vol_desc(IsoImageWriter *writer)
ucsncpy_pad((uint16_t*)vol.abstract_file_id, abstract_file_id, 37);
ucsncpy_pad((uint16_t*)vol.bibliographic_file_id, biblio_file_id, 37);
iso_datetime_17(vol.vol_creation_time, t->now);
iso_datetime_17(vol.vol_modification_time, t->now);
iso_datetime_17(vol.vol_effective_time, t->now);
iso_datetime_17(vol.vol_creation_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_modification_time, t->now, t->always_gmt);
iso_datetime_17(vol.vol_effective_time, t->now, t->always_gmt);
vol.file_structure_version[0] = 1;
free(vol_id);

View File

@ -765,6 +765,17 @@ int iso_write_opts_set_replace_timestamps(IsoWriteOpts *opts, int replace);
*/
int iso_write_opts_set_default_timestamp(IsoWriteOpts *opts, time_t timestamp);
/**
* Whether to always record timestamps in GMT.
*
* By default, libisofs stores local time information on image. You can set
* this to always store timestamps in GMT. This is useful if you want to hide
* your timezone, or you live in a timezone that can't be represented in
* ECMA-119. These are timezones whose offset from GMT is greater than +13
* hours, lower than -12 hours, or not a multiple of 15 minutes.
*/
int iso_write_opts_set_always_gmt(IsoWriteOpts *opts, int gmt);
/**
* Set the charset to use for the RR names of the files that will be created
* on the image.

View File

@ -126,9 +126,12 @@ int rrip_add_TF(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
TF[4] = (1 << 1) | (1 << 2) | (1 << 3);
iso = n->node;
iso_datetime_7(&TF[5], t->replace_timestamps ? t->timestamp : iso->mtime);
iso_datetime_7(&TF[12], t->replace_timestamps ? t->timestamp : iso->atime);
iso_datetime_7(&TF[19], t->replace_timestamps ? t->timestamp : iso->ctime);
iso_datetime_7(&TF[5], t->replace_timestamps ? t->timestamp : iso->mtime,
t->always_gmt);
iso_datetime_7(&TF[12], t->replace_timestamps ? t->timestamp : iso->atime,
t->always_gmt);
iso_datetime_7(&TF[19], t->replace_timestamps ? t->timestamp : iso->ctime,
t->always_gmt);
return susp_append(t, susp, TF);
}

View File

@ -972,7 +972,7 @@ uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error)
return v1;
}
void iso_datetime_7(unsigned char *buf, time_t t)
void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
{
static int tzsetup = 0;
int tzoffset;
@ -984,15 +984,9 @@ void iso_datetime_7(unsigned char *buf, time_t t)
}
memset(&tm, 0, sizeof(tm));
tm.tm_isdst = -1;
tm.tm_isdst = -1; /* some Linuxes change tm_isdst only if it is -1 */
localtime_r(&t, &tm);
buf[0] = tm.tm_year;
buf[1] = tm.tm_mon + 1;
buf[2] = tm.tm_mday;
buf[3] = tm.tm_hour;
buf[4] = tm.tm_min;
buf[5] = tm.tm_sec;
#ifdef HAVE_TM_GMTOFF
tzoffset = tm.tm_gmtoff / 60 / 15;
#else
@ -1000,12 +994,22 @@ void iso_datetime_7(unsigned char *buf, time_t t)
tm.tm_isdst = 0;
tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst;
#endif
if (tzoffset > 52)
tzoffset -= 101;
if (tzoffset > 52 || tzoffset < -48 || always_gmt) {
/* absurd timezone offset, represent time in GMT */
gmtime_r(&t, &tm);
tzoffset = 0;
}
buf[0] = tm.tm_year;
buf[1] = tm.tm_mon + 1;
buf[2] = tm.tm_mday;
buf[3] = tm.tm_hour;
buf[4] = tm.tm_min;
buf[5] = tm.tm_sec;
buf[6] = tzoffset;
}
void iso_datetime_17(unsigned char *buf, time_t t)
void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
{
static int tzsetup = 0;
static int tzoffset;
@ -1015,30 +1019,43 @@ void iso_datetime_17(unsigned char *buf, time_t t)
/* unspecified time */
memset(buf, '0', 16);
buf[16] = 0;
} else {
if (!tzsetup) {
tzset();
tzsetup = 1;
}
localtime_r(&t, &tm);
sprintf((char*)&buf[0], "%04d", tm.tm_year + 1900);
sprintf((char*)&buf[4], "%02d", tm.tm_mon + 1);
sprintf((char*)&buf[6], "%02d", tm.tm_mday);
sprintf((char*)&buf[8], "%02d", tm.tm_hour);
sprintf((char*)&buf[10], "%02d", tm.tm_min);
sprintf((char*)&buf[12], "%02d", MIN(59, tm.tm_sec));
memcpy(&buf[14], "00", 2);
#ifdef HAVE_TM_GMTOFF
tzoffset = tm.tm_gmtoff / 60 / 15;
#else
tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst;
#endif
if (tzoffset > 52)
tzoffset -= 101;
buf[16] = tzoffset;
return;
}
if (!tzsetup) {
tzset();
tzsetup = 1;
}
memset(&tm, 0, sizeof(tm));
tm.tm_isdst = -1; /* some Linuxes change tm_isdst only if it is -1 */
localtime_r(&t, &tm);
localtime_r(&t, &tm);
#ifdef HAVE_TM_GMTOFF
tzoffset = tm.tm_gmtoff / 60 / 15;
#else
if (tm.tm_isdst < 0)
tm.tm_isdst = 0;
tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst;
#endif
if (tzoffset > 52 || tzoffset < -48 || always_gmt) {
/* absurd timezone offset, represent time in GMT */
gmtime_r(&t, &tm);
tzoffset = 0;
}
sprintf((char*)&buf[0], "%04d", tm.tm_year + 1900);
sprintf((char*)&buf[4], "%02d", tm.tm_mon + 1);
sprintf((char*)&buf[6], "%02d", tm.tm_mday);
sprintf((char*)&buf[8], "%02d", tm.tm_hour);
sprintf((char*)&buf[10], "%02d", tm.tm_min);
sprintf((char*)&buf[12], "%02d", MIN(59, tm.tm_sec));
memcpy(&buf[14], "00", 2);
buf[16] = tzoffset;
}
time_t iso_datetime_read_7(const uint8_t *buf)

View File

@ -213,11 +213,20 @@ uint32_t iso_read_msb(const uint8_t *buf, int bytes);
*/
uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error);
/** Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5) */
void iso_datetime_7(uint8_t *buf, time_t t);
/**
* Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5)
*
* @param buf
* Buffer where the date will be written
* @param t
* The time to be written
* @param always_gmt
* Always write the date in GMT and not in local time.
*/
void iso_datetime_7(uint8_t *buf, time_t t, int always_gmt);
/** Records the date/time into a 17 byte buffer (ECMA-119, 8.4.26.1) */
void iso_datetime_17(uint8_t *buf, time_t t);
void iso_datetime_17(uint8_t *buf, time_t t, int always_gmt);
time_t iso_datetime_read_7(const uint8_t *buf);
time_t iso_datetime_read_17(const uint8_t *buf);

View File

@ -169,7 +169,7 @@ static void test_iso_datetime_7()
setenv("TZ", "Europe/Madrid", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 3); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -182,7 +182,7 @@ static void test_iso_datetime_7()
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
CU_ASSERT_EQUAL(buf[0], 107); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 7); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -198,7 +198,7 @@ static void test_iso_datetime_7()
setenv("TZ", "Europe/London", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 3); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -211,7 +211,7 @@ static void test_iso_datetime_7()
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
CU_ASSERT_EQUAL(buf[0], 107); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 7); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -228,7 +228,7 @@ static void test_iso_datetime_7()
setenv("TZ", "America/New_York", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 3); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -245,7 +245,7 @@ static void test_iso_datetime_7()
setenv("TZ", "Asia/Hong_Kong", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 3); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -271,7 +271,7 @@ static void test_iso_datetime_7()
setenv("TZ", "Africa/Luanda", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 3); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -284,7 +284,7 @@ static void test_iso_datetime_7()
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
CU_ASSERT_EQUAL(buf[0], 107); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 7); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -303,7 +303,7 @@ static void test_iso_datetime_7()
setenv("TZ", "Australia/Broken_Hill", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 3); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -316,7 +316,7 @@ static void test_iso_datetime_7()
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
CU_ASSERT_EQUAL(buf[0], 107); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 7); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -335,7 +335,7 @@ static void test_iso_datetime_7()
setenv("TZ", "Pacific/Tongatapu", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 3); /* month */
CU_ASSERT_EQUAL(buf[2], 2); /* day */
@ -352,7 +352,7 @@ static void test_iso_datetime_7()
setenv("TZ", "Pacific/Pago_Pago", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
CU_ASSERT_EQUAL(buf[0], 76); /* year since 1900 */
CU_ASSERT_EQUAL(buf[1], 3); /* month */
CU_ASSERT_EQUAL(buf[2], 1); /* day */
@ -366,149 +366,147 @@ static void test_iso_datetime_7()
CU_ASSERT_EQUAL(tr, t1);
/* --- and now test from several zones, just for write/read compatibilty */
/*
setenv("TZ", "Pacific/Kiritimati", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 1); /* this needs GMT */
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
*/
setenv("TZ", "America/Argentina/La_Rioja", 1);
tzset();
iso_datetime_7(buf, t1);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "America/Argentina/La_Rioja", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "America/Argentina/La_Rioja", 1);
tzset();
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "America/Caracas", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Asia/Bangkok", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Asia/Tehran", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Pacific/Pitcairn", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Antarctica/McMurdo", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "EET", 1); /* Eastern European Time */
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Europe/Moscow", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Asia/Novosibirsk", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Asia/Vladivostok", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Asia/Anadyr", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Atlantic/Canary", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "Indian/Mauritius", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);
setenv("TZ", "America/Los_Angeles", 1);
tzset();
iso_datetime_7(buf, t1);
iso_datetime_7(buf, t1, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t1);
iso_datetime_7(buf, t2);
iso_datetime_7(buf, t2, 0);
tr = iso_datetime_read_7(buf);
CU_ASSERT_EQUAL(tr, t2);