By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,212 Members | 1,110 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,212 IT Pros & Developers. It's quick & easy.

parsing time string, getting timezone

P: n/a
Hi all,

I have some trouble with the following:

I'm getting a time string, in YYYY-MM-DD HH:mm:ss format, which I
need to translate into a string with DD-Mon-YYYY HH:mm:ss +HHMM,
where the last part is the timezone offset.

I've tried to do it with the following function. This works for me,
I get +0200 for the timezone part, which makes sense, because we're
on daylight savings time at the moment here in the Netherlands.
However, another user of the same code is located in Australia, he
gets +1100 as timezone offset. It's winter out there now, and at the
moment he's really at +1000. All his other software does it in the
right way. So... what am I doing wrong?

char *date_sql2imap(const char *sqldate)
{
char *last_char;
struct tm tm_localtime, tm_sqldate;
time_t td;

/* we need to get the localtime to get the current timezone */
if (time(&td) == -1) {
trace(TRACE_ERROR, "%s,%s: error getting time()",
__FILE__, __func__);
return IMAP_STANDARD_DATE;
}
tm_localtime = *localtime(&td);
/* parse sqldate */
last_char = strptime(sqldate, "%Y-%m-%d %T", &tm_sqldate);
if (*last_char != '\0') {
trace(TRACE_DEBUG, "%s,%s, error parsing date [%s]",
__FILE__, __func__, sqldate);
strcpy(_imapdate, IMAP_STANDARD_DATE);
return _imapdate;
}
tm_sqldate.tm_gmtoff = tm_localtime.tm_gmtoff;
(void) strftime(_imapdate, IMAP_INTERNALDATE_LEN,
"%d-%b-%Y %T %z", &tm_sqldate);
return _imapdate;
}

Thanks for your time,
Ilja Booij

--
Ilja Booij
IC&S B.V.
Nov 14 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a


Ilja Booij wrote:
Hi all,
Hi,

I have some trouble with the following:

I'm getting a time string, in YYYY-MM-DD HH:mm:ss format, which I
need to translate into a string with DD-Mon-YYYY HH:mm:ss +HHMM,
where the last part is the timezone offset.

I've tried to do it with the following function. This works for me,
I get +0200 for the timezone part, which makes sense, because we're
on daylight savings time at the moment here in the Netherlands.
However, another user of the same code is located in Australia, he
gets +1100 as timezone offset. It's winter out there now, and at the
moment he's really at +1000. All his other software does it in the
right way. So... what am I doing wrong?

char *date_sql2imap(const char *sqldate)
{
char *last_char;
struct tm tm_localtime, tm_sqldate;
Since most of time functions ask for pointers to struct tm, I would have
used struct tm * variables instead.
time_t td;

/* we need to get the localtime to get the current timezone */
if (time(&td) == -1) {
trace(TRACE_ERROR, "%s,%s: error getting time()",
__FILE__, __func__);
return IMAP_STANDARD_DATE;
}
tm_localtime = *localtime(&td);
IMHO, what I said above could have led in perhaps more readable code
with tm_localtime = localtime(&td); /* assuming struct tm* tm_localtime */
/* parse sqldate */
last_char = strptime(sqldate, "%Y-%m-%d %T", &tm_sqldate);
strptime is not part of C standard functions, it's a POSIX/Unix one.
According to the documentation I found on the Internet (
http://www.opengroup.org/onlinepubs/.../strptime.html ),
strptime returns a null pointer in case of failure. It would have been
more readable to test with NULL below.
if (*last_char != '\0') { if (last_char == NULL) {
trace(TRACE_DEBUG, "%s,%s, error parsing date [%s]",
__FILE__, __func__, sqldate);
strcpy(_imapdate, IMAP_STANDARD_DATE);
return _imapdate;
}
tm_sqldate.tm_gmtoff = tm_localtime.tm_gmtoff;
I didn't see a such member (tm_gmtoff) in a tm structure (C or POSIX).
What I know is that there is a required flag for daylight, a tm member
named tm_isdst. tm_isdst (int)is positive if daylight is used, zero if
daylight is'nt used or negative if this information isn't available. My
advice would be to use tm_isdst (and check its value) instead of
tm_gmtoff, knowing that tm_isdst isn't modified by strptime. Time and
date handling is very implementation dependent thus my last advice is to
keep your code compliant with the C Standard as much as possible.
Personally, in your date_sql2imap function, the only non C standard
stuff that I would have used is strptime.
(void) strftime(_imapdate, IMAP_INTERNALDATE_LEN,
"%d-%b-%Y %T %z", &tm_sqldate);
return _imapdate;
}


Finally, here is the code of a little program that you can share with
your australian collegue to compare values:

___________________________________

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main(void)
{
time_t time_Calendar;
struct tm * time_Local;
char bufferLocalTime[100];
size_t nbWrittenChars;

if (time(&time_Calendar) == (time_t)-1)
{
fprintf(stderr, "Couldn't retrieve the calendar time\n");
exit(EXIT_FAILURE);
}

time_Local = localtime(&time_Calendar);
if (time_Local == NULL)
{
fprintf(stderr, "Couldn't retrieve the local time\n");
exit(EXIT_FAILURE);
}

memset(bufferLocalTime, 0, sizeof bufferLocalTime);
nbWrittenChars = strftime(bufferLocalTime,
sizeof bufferLocalTime,
"%d-%b-%Y %T",
time_Local);

/* Check the daylight flag */
if (time_Local->tm_isdst > 0)
{
printf("The daylight flag is used, time_Local->tm_isdst = %d\n",
time_Local->tm_isdst);
}
else
{
if (time_Local->tm_isdst == 0)
{
printf("The daylight flag is NOT used, time_Local->tm_isdst=%d\n",
time_Local->tm_isdst);
}
else
{
printf("Daylight information is unavailable,"
"time_Local->tm_isdst=%d\n",
time_Local->tm_isdst);
}
}

if (nbWrittenChars > 0)
{
puts(bufferLocalTime);
}
else
{
fprintf(stderr, "strftime failed to write the local time\n");
exit(EXIT_FAILURE);
}

return EXIT_SUCCESS;

}

Cheers,

Regis

Nov 14 '05 #2

P: n/a


Targeur fou wrote:

Erratum,

memset(bufferLocalTime, 0, sizeof bufferLocalTime);
nbWrittenChars = strftime(bufferLocalTime,
sizeof bufferLocalTime,
"%d-%b-%Y %T",
time_Local);


[snipped]

nbWrittenChars = strftime(bufferLocalTime,
sizeof bufferLocalTime,
"%d-%b-%Y %T %z",
time_Local);

[snipped]

By the way, have a look to the tzset() POSIX function and its associated
external variables to handle timezone informations in a "quite" portable
manner.
http://www.opengroup.org/onlinepubs/...ons/tzset.html

Nov 14 '05 #3

P: n/a
In article <ch**********@news-reader1.wanadoo.fr>, Targeur fou wrote:


Targeur fou wrote:


<snip code>

By the way, have a look to the tzset() POSIX function and its associated
external variables to handle timezone informations in a "quite" portable
manner.
http://www.opengroup.org/onlinepubs/...ons/tzset.html


first of all, thanks for your answer!

tm_gmtoff is a BSD & GNU extension, so definetly not ISO or POSIX
C.

Anyway. I've tried to use your recommendations for changing the function, but
I cannot see how I should do it.

Can you shed some light on how I should change this function to return a string
with the right timezone? Using tm_isdst I can see whether it's daylight savings
time or not, but I wouldn't know how to use that information in the string..

I know, I should be able to figure this out by myself.. I've been ill the last
2 days, and my brain hasn't been fully reconnected yet I guess..

Thanks
Ilja
Nov 14 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.