mirror of
https://github.com/gnustep/libs-sqlclient.git
synced 2025-02-14 15:40:59 +00:00
Fix timestamps without timezone to use local time zone
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@36655 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
5b64b5c3bf
commit
0469ba48fb
3 changed files with 431 additions and 296 deletions
233
ECPG.pgm
233
ECPG.pgm
|
@ -946,9 +946,13 @@ static unsigned int trim(char *str)
|
||||||
|
|
||||||
- (NSDate*) dbToDateFromBuffer: (char*)b length: (int)l
|
- (NSDate*) dbToDateFromBuffer: (char*)b length: (int)l
|
||||||
{
|
{
|
||||||
char buf[l+32]; /* Allow space to expend buffer. */
|
char buf[l+32]; /* Allow space to expand buffer. */
|
||||||
NSString *s;
|
NSCalendarDate *d;
|
||||||
int i;
|
BOOL milliseconds = NO;
|
||||||
|
BOOL timezone = NO;
|
||||||
|
NSString *s;
|
||||||
|
int i;
|
||||||
|
int e;
|
||||||
|
|
||||||
memcpy(buf, b, l);
|
memcpy(buf, b, l);
|
||||||
b = buf;
|
b = buf;
|
||||||
|
@ -971,98 +975,153 @@ static unsigned int trim(char *str)
|
||||||
|
|
||||||
if (l == 10)
|
if (l == 10)
|
||||||
{
|
{
|
||||||
s = [self dbToStringFromBuffer: b length: l];
|
s = [NSString stringWithUTF8String: b];
|
||||||
return [NSCalendarDate dateWithString: s
|
return [NSCalendarDate dateWithString: s
|
||||||
calendarFormat: @"%Y-%m-%d"
|
calendarFormat: @"%Y-%m-%d"
|
||||||
locale: nil];
|
locale: nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = l;
|
||||||
|
|
||||||
|
/* Convert +/-HH:SS timezone to +/-HHSS
|
||||||
|
*/
|
||||||
|
if (i > 5 && b[i-3] == ':' && (b[i-6] == '+' || b[i-6] == '-'))
|
||||||
|
{
|
||||||
|
b[i-3] = b[i-2];
|
||||||
|
b[i-2] = b[i-1];
|
||||||
|
b[--i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i-- > 0)
|
||||||
|
{
|
||||||
|
if (b[i] == '+' || b[i] == '-')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (b[i] == ':' || b[i] == ' ')
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
break; /* No time zone found */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
e = l;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i = l;
|
timezone = YES;
|
||||||
while (i-- > 0)
|
e = i;
|
||||||
{
|
if (isdigit(b[i-1]))
|
||||||
if (b[i] == '+' || b[i] == '-')
|
{
|
||||||
{
|
/*
|
||||||
break;
|
* Make space between seconds and timezone.
|
||||||
}
|
*/
|
||||||
if (b[i] == ':' || b[i] == ' ')
|
memmove(&b[i+1], &b[i], l - i);
|
||||||
{
|
b[i++] = ' ';
|
||||||
i = 0;
|
b[++l] = '\0';
|
||||||
break; /* No time zone found */
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
int e = i;
|
|
||||||
|
|
||||||
if (isdigit(b[i-1]))
|
/*
|
||||||
{
|
* Ensure we have a four digit timezone value.
|
||||||
/*
|
*/
|
||||||
* Make space between seconds and timezone.
|
if (isdigit(b[i+1]) && isdigit(b[i+2]))
|
||||||
*/
|
{
|
||||||
memmove(&b[i+1], &b[i], l - i);
|
if (b[i+3] == '\0')
|
||||||
b[i++] = ' ';
|
{
|
||||||
b[++l] = '\0';
|
// Two digit time zone ... append zero minutes
|
||||||
}
|
b[l++] = '0';
|
||||||
|
b[l++] = '0';
|
||||||
if (isdigit(b[i+1]) && isdigit(b[i+2]))
|
b[l] = '\0';
|
||||||
{
|
}
|
||||||
if (b[i+3] == '\0')
|
else if (b[i+3] == ':')
|
||||||
{
|
{
|
||||||
// Two digit time zone
|
// Zone with colon before minutes ... remove it
|
||||||
b[l++] = '0';
|
b[i+3] = b[i+4];
|
||||||
b[l++] = '0';
|
b[i+4] = b[i+5];
|
||||||
b[l] = '\0';
|
b[--l] = '\0';
|
||||||
}
|
}
|
||||||
else if (b[i+3] == ':')
|
}
|
||||||
{
|
|
||||||
// Zone with colon before minutes
|
|
||||||
b[i+3] = b[i+4];
|
|
||||||
b[i+5] = b[i+5];
|
|
||||||
b[--l] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME ... horrible kludge for postgres returning timestamps with
|
|
||||||
fractional second information. */
|
|
||||||
while (i-- > 0)
|
|
||||||
{
|
|
||||||
if (b[i] == '.')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
memmove(&b[i], &b[e], l - e);
|
|
||||||
l -= (e - i);
|
|
||||||
b[l] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (l == 19)
|
|
||||||
{
|
|
||||||
/* A date and time without a timezone ... assume gmt */
|
|
||||||
strcat(b, " +0000");
|
|
||||||
l += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If it's a simple date (YYYY-MM-DD) append time for start of day. */
|
|
||||||
if (l == 10)
|
|
||||||
{
|
|
||||||
strcat(b, " 00:00:00 +0000");
|
|
||||||
l += 15;
|
|
||||||
}
|
|
||||||
if (l == 0)
|
|
||||||
{
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = [self dbToStringFromBuffer: b length: l];
|
|
||||||
return [NSCalendarDate dateWithString: s
|
|
||||||
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"
|
|
||||||
locale: nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* kludge for timestamps with fractional second information.
|
||||||
|
* Force it to 3 digit millisecond */
|
||||||
|
while (i-- > 0)
|
||||||
|
{
|
||||||
|
if (b[i] == '.')
|
||||||
|
{
|
||||||
|
milliseconds = YES;
|
||||||
|
i++;
|
||||||
|
if (!isdigit(b[i]))
|
||||||
|
{
|
||||||
|
memmove(&b[i+3], &b[i], e-i);
|
||||||
|
l += 3;
|
||||||
|
memcpy(&b[i], "000", 3);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (!isdigit(b[i]))
|
||||||
|
{
|
||||||
|
memmove(&b[i+2], &b[i], e-i);
|
||||||
|
l += 2;
|
||||||
|
memcpy(&b[i], "00", 2);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (!isdigit(b[i]))
|
||||||
|
{
|
||||||
|
memmove(&b[i+1], &b[i], e-i);
|
||||||
|
l += 1;
|
||||||
|
memcpy(&b[i], "0", 1);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i > 0 && i < e)
|
||||||
|
{
|
||||||
|
memmove(&b[i], &b[e], l - e);
|
||||||
|
l -= (e - i);
|
||||||
|
}
|
||||||
|
b[l] = '\0';
|
||||||
|
if (l == 0)
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = [NSString stringWithUTF8String: b];
|
||||||
|
|
||||||
|
if (YES == timezone)
|
||||||
|
{
|
||||||
|
if (milliseconds == YES)
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S.%F %z"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (milliseconds == YES)
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S.%F"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[d setCalendarFormat: @"%Y-%m-%d %H:%M:%S %z"];
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*) dbToStringFromBuffer: (char*)b length: (int)l
|
- (NSString*) dbToStringFromBuffer: (char*)b length: (int)l
|
||||||
|
|
236
Oracle.pm
236
Oracle.pm
|
@ -899,14 +899,15 @@ static unsigned int trim(char *str)
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert from a database character buffer to an NSDate.
|
|
||||||
*/
|
|
||||||
- (NSDate*) dbToDateFromBuffer: (char*)b length: (int)l
|
- (NSDate*) dbToDateFromBuffer: (char*)b length: (int)l
|
||||||
{
|
{
|
||||||
char buf[l+32]; /* Allow space to expend buffer. */
|
char buf[l+32]; /* Allow space to expand buffer. */
|
||||||
NSString *s;
|
NSCalendarDate *d;
|
||||||
int i;
|
BOOL milliseconds = NO;
|
||||||
|
BOOL timezone = NO;
|
||||||
|
NSString *s;
|
||||||
|
int i;
|
||||||
|
int e;
|
||||||
|
|
||||||
memcpy(buf, b, l);
|
memcpy(buf, b, l);
|
||||||
b = buf;
|
b = buf;
|
||||||
|
@ -929,98 +930,153 @@ static unsigned int trim(char *str)
|
||||||
|
|
||||||
if (l == 10)
|
if (l == 10)
|
||||||
{
|
{
|
||||||
s = [self dbToStringFromBuffer: b length: l];
|
s = [NSString stringWithUTF8String: b];
|
||||||
return [NSCalendarDate dateWithString: s
|
return [NSCalendarDate dateWithString: s
|
||||||
calendarFormat: @"%Y-%m-%d"
|
calendarFormat: @"%Y-%m-%d"
|
||||||
locale: nil];
|
locale: nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = l;
|
||||||
|
|
||||||
|
/* Convert +/-HH:SS timezone to +/-HHSS
|
||||||
|
*/
|
||||||
|
if (i > 5 && b[i-3] == ':' && (b[i-6] == '+' || b[i-6] == '-'))
|
||||||
|
{
|
||||||
|
b[i-3] = b[i-2];
|
||||||
|
b[i-2] = b[i-1];
|
||||||
|
b[--i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i-- > 0)
|
||||||
|
{
|
||||||
|
if (b[i] == '+' || b[i] == '-')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (b[i] == ':' || b[i] == ' ')
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
break; /* No time zone found */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
e = l;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i = l;
|
timezone = YES;
|
||||||
while (i-- > 0)
|
e = i;
|
||||||
{
|
if (isdigit(b[i-1]))
|
||||||
if (b[i] == '+' || b[i] == '-')
|
{
|
||||||
{
|
/*
|
||||||
break;
|
* Make space between seconds and timezone.
|
||||||
}
|
*/
|
||||||
if (b[i] == ':' || b[i] == ' ')
|
memmove(&b[i+1], &b[i], l - i);
|
||||||
{
|
b[i++] = ' ';
|
||||||
i = 0;
|
b[++l] = '\0';
|
||||||
break; /* No time zone found */
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
int e = i;
|
|
||||||
|
|
||||||
if (isdigit(b[i-1]))
|
/*
|
||||||
{
|
* Ensure we have a four digit timezone value.
|
||||||
/*
|
*/
|
||||||
* Make space between seconds and timezone.
|
if (isdigit(b[i+1]) && isdigit(b[i+2]))
|
||||||
*/
|
{
|
||||||
memmove(&b[i+1], &b[i], l - i);
|
if (b[i+3] == '\0')
|
||||||
b[i++] = ' ';
|
{
|
||||||
b[++l] = '\0';
|
// Two digit time zone ... append zero minutes
|
||||||
}
|
b[l++] = '0';
|
||||||
|
b[l++] = '0';
|
||||||
if (isdigit(b[i+1]) && isdigit(b[i+2]))
|
b[l] = '\0';
|
||||||
{
|
}
|
||||||
if (b[i+3] == '\0')
|
else if (b[i+3] == ':')
|
||||||
{
|
{
|
||||||
// Two digit time zone
|
// Zone with colon before minutes ... remove it
|
||||||
b[l++] = '0';
|
b[i+3] = b[i+4];
|
||||||
b[l++] = '0';
|
b[i+4] = b[i+5];
|
||||||
b[l] = '\0';
|
b[--l] = '\0';
|
||||||
}
|
}
|
||||||
else if (b[i+3] == ':')
|
}
|
||||||
{
|
|
||||||
// Zone with colon before minutes
|
|
||||||
b[i+3] = b[i+4];
|
|
||||||
b[i+5] = b[i+5];
|
|
||||||
b[--l] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME ... horrible kludge for postgres returning timestamps with
|
|
||||||
fractional second information. */
|
|
||||||
while (i-- > 0)
|
|
||||||
{
|
|
||||||
if (b[i] == '.')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
memmove(&b[i], &b[e], l - e);
|
|
||||||
l -= (e - i);
|
|
||||||
b[l] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (l == 19)
|
|
||||||
{
|
|
||||||
/* A date and time without a timezone ... assume gmt */
|
|
||||||
strcat(b, " +0000");
|
|
||||||
l += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If it's a simple date (YYYY-MM-DD) append time for start of day. */
|
|
||||||
if (l == 10)
|
|
||||||
{
|
|
||||||
strcat(b, " 00:00:00 +0000");
|
|
||||||
l += 15;
|
|
||||||
}
|
|
||||||
if (l == 0)
|
|
||||||
{
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = [self dbToStringFromBuffer: b length: l];
|
|
||||||
return [NSCalendarDate dateWithString: s
|
|
||||||
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"
|
|
||||||
locale: nil];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* kludge for timestamps with fractional second information.
|
||||||
|
* Force it to 3 digit millisecond */
|
||||||
|
while (i-- > 0)
|
||||||
|
{
|
||||||
|
if (b[i] == '.')
|
||||||
|
{
|
||||||
|
milliseconds = YES;
|
||||||
|
i++;
|
||||||
|
if (!isdigit(b[i]))
|
||||||
|
{
|
||||||
|
memmove(&b[i+3], &b[i], e-i);
|
||||||
|
l += 3;
|
||||||
|
memcpy(&b[i], "000", 3);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (!isdigit(b[i]))
|
||||||
|
{
|
||||||
|
memmove(&b[i+2], &b[i], e-i);
|
||||||
|
l += 2;
|
||||||
|
memcpy(&b[i], "00", 2);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (!isdigit(b[i]))
|
||||||
|
{
|
||||||
|
memmove(&b[i+1], &b[i], e-i);
|
||||||
|
l += 1;
|
||||||
|
memcpy(&b[i], "0", 1);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i > 0 && i < e)
|
||||||
|
{
|
||||||
|
memmove(&b[i], &b[e], l - e);
|
||||||
|
l -= (e - i);
|
||||||
|
}
|
||||||
|
b[l] = '\0';
|
||||||
|
if (l == 0)
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = [NSString stringWithUTF8String: b];
|
||||||
|
|
||||||
|
if (YES == timezone)
|
||||||
|
{
|
||||||
|
if (milliseconds == YES)
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S.%F %z"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (milliseconds == YES)
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S.%F"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[d setCalendarFormat: @"%Y-%m-%d %H:%M:%S %z"];
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
258
Postgres.m
258
Postgres.m
|
@ -835,11 +835,13 @@ static unsigned int trim(char *str)
|
||||||
|
|
||||||
- (NSDate*) dbToDateFromBuffer: (char*)b length: (int)l
|
- (NSDate*) dbToDateFromBuffer: (char*)b length: (int)l
|
||||||
{
|
{
|
||||||
char buf[l+32]; /* Allow space to expand buffer. */
|
char buf[l+32]; /* Allow space to expand buffer. */
|
||||||
NSDate *d;
|
NSCalendarDate *d;
|
||||||
BOOL milliseconds = NO;
|
BOOL milliseconds = NO;
|
||||||
NSString *s;
|
BOOL timezone = NO;
|
||||||
int i;
|
NSString *s;
|
||||||
|
int i;
|
||||||
|
int e;
|
||||||
|
|
||||||
memcpy(buf, b, l);
|
memcpy(buf, b, l);
|
||||||
b = buf;
|
b = buf;
|
||||||
|
@ -867,130 +869,148 @@ static unsigned int trim(char *str)
|
||||||
calendarFormat: @"%Y-%m-%d"
|
calendarFormat: @"%Y-%m-%d"
|
||||||
locale: nil];
|
locale: nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = l;
|
||||||
|
|
||||||
|
/* Convert +/-HH:SS timezone to +/-HHSS
|
||||||
|
*/
|
||||||
|
if (i > 5 && b[i-3] == ':' && (b[i-6] == '+' || b[i-6] == '-'))
|
||||||
|
{
|
||||||
|
b[i-3] = b[i-2];
|
||||||
|
b[i-2] = b[i-1];
|
||||||
|
b[--i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i-- > 0)
|
||||||
|
{
|
||||||
|
if (b[i] == '+' || b[i] == '-')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (b[i] == ':' || b[i] == ' ')
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
break; /* No time zone found */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
e = l;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int e;
|
timezone = YES;
|
||||||
|
|
||||||
i = l;
|
|
||||||
/* Convert +/-HH:SS timezone to +/-HHSS
|
|
||||||
*/
|
|
||||||
if (i > 5 && b[i-3] == ':' && (b[i-6] == '+' || b[i-6] == '-'))
|
|
||||||
{
|
|
||||||
b[i-3] = b[i-2];
|
|
||||||
b[i-2] = b[i-1];
|
|
||||||
b[--i] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
while (i-- > 0)
|
|
||||||
{
|
|
||||||
if (b[i] == '+' || b[i] == '-')
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (b[i] == ':' || b[i] == ' ')
|
|
||||||
{
|
|
||||||
i = 0;
|
|
||||||
break; /* No time zone found */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i == 0)
|
|
||||||
{
|
|
||||||
/* A date and time without a timezone ... assume gmt */
|
|
||||||
strcpy(b + l, " +0000");
|
|
||||||
i = l + 1;
|
|
||||||
l += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
e = i;
|
e = i;
|
||||||
if (isdigit(b[i-1]))
|
if (isdigit(b[i-1]))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Make space between seconds and timezone.
|
* Make space between seconds and timezone.
|
||||||
*/
|
*/
|
||||||
memmove(&b[i+1], &b[i], l - i);
|
memmove(&b[i+1], &b[i], l - i);
|
||||||
b[i++] = ' ';
|
b[i++] = ' ';
|
||||||
b[++l] = '\0';
|
b[++l] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensure we have a four digit timezone value.
|
* Ensure we have a four digit timezone value.
|
||||||
*/
|
*/
|
||||||
if (isdigit(b[i+1]) && isdigit(b[i+2]))
|
if (isdigit(b[i+1]) && isdigit(b[i+2]))
|
||||||
{
|
{
|
||||||
if (b[i+3] == '\0')
|
if (b[i+3] == '\0')
|
||||||
{
|
{
|
||||||
// Two digit time zone ... append zero minutes
|
// Two digit time zone ... append zero minutes
|
||||||
b[l++] = '0';
|
b[l++] = '0';
|
||||||
b[l++] = '0';
|
b[l++] = '0';
|
||||||
b[l] = '\0';
|
b[l] = '\0';
|
||||||
}
|
}
|
||||||
else if (b[i+3] == ':')
|
else if (b[i+3] == ':')
|
||||||
{
|
{
|
||||||
// Zone with colon before minutes ... remove it
|
// Zone with colon before minutes ... remove it
|
||||||
b[i+3] = b[i+4];
|
b[i+3] = b[i+4];
|
||||||
b[i+4] = b[i+5];
|
b[i+4] = b[i+5];
|
||||||
b[--l] = '\0';
|
b[--l] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME ... horrible kludge for postgres returning timestamps with
|
|
||||||
fractional second information. Force it to 3 digit millisecond */
|
|
||||||
while (i-- > 0)
|
|
||||||
{
|
|
||||||
if (b[i] == '.')
|
|
||||||
{
|
|
||||||
milliseconds = YES;
|
|
||||||
i++;
|
|
||||||
if (!isdigit(b[i]))
|
|
||||||
{
|
|
||||||
memmove(&b[i+3], &b[i], e-i);
|
|
||||||
l += 3;
|
|
||||||
memcpy(&b[i], "000", 3);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
if (!isdigit(b[i]))
|
|
||||||
{
|
|
||||||
memmove(&b[i+2], &b[i], e-i);
|
|
||||||
l += 2;
|
|
||||||
memcpy(&b[i], "00", 2);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
if (!isdigit(b[i]))
|
|
||||||
{
|
|
||||||
memmove(&b[i+1], &b[i], e-i);
|
|
||||||
l += 1;
|
|
||||||
memcpy(&b[i], "0", 1);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i > 0 && i < e)
|
|
||||||
{
|
|
||||||
memmove(&b[i], &b[e], l - e);
|
|
||||||
l -= (e - i);
|
|
||||||
}
|
|
||||||
b[l] = '\0';
|
|
||||||
if (l == 0)
|
|
||||||
{
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = [NSString stringWithUTF8String: b];
|
|
||||||
if (milliseconds == YES)
|
|
||||||
{
|
|
||||||
d = [NSCalendarDate dateWithString: s
|
|
||||||
calendarFormat: @"%Y-%m-%d %H:%M:%S.%F %z"
|
|
||||||
locale: nil];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
d = [NSCalendarDate dateWithString: s
|
|
||||||
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"
|
|
||||||
locale: nil];
|
|
||||||
}
|
|
||||||
return d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* kludge for timestamps with fractional second information.
|
||||||
|
* Force it to 3 digit millisecond */
|
||||||
|
while (i-- > 0)
|
||||||
|
{
|
||||||
|
if (b[i] == '.')
|
||||||
|
{
|
||||||
|
milliseconds = YES;
|
||||||
|
i++;
|
||||||
|
if (!isdigit(b[i]))
|
||||||
|
{
|
||||||
|
memmove(&b[i+3], &b[i], e-i);
|
||||||
|
l += 3;
|
||||||
|
memcpy(&b[i], "000", 3);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (!isdigit(b[i]))
|
||||||
|
{
|
||||||
|
memmove(&b[i+2], &b[i], e-i);
|
||||||
|
l += 2;
|
||||||
|
memcpy(&b[i], "00", 2);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
if (!isdigit(b[i]))
|
||||||
|
{
|
||||||
|
memmove(&b[i+1], &b[i], e-i);
|
||||||
|
l += 1;
|
||||||
|
memcpy(&b[i], "0", 1);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i > 0 && i < e)
|
||||||
|
{
|
||||||
|
memmove(&b[i], &b[e], l - e);
|
||||||
|
l -= (e - i);
|
||||||
|
}
|
||||||
|
b[l] = '\0';
|
||||||
|
if (l == 0)
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = [NSString stringWithUTF8String: b];
|
||||||
|
|
||||||
|
if (YES == timezone)
|
||||||
|
{
|
||||||
|
if (milliseconds == YES)
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S.%F %z"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (milliseconds == YES)
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S.%F"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d = [NSCalendarDate dateWithString: s
|
||||||
|
calendarFormat: @"%Y-%m-%d %H:%M:%S"
|
||||||
|
locale: nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[d setCalendarFormat: @"%Y-%m-%d %H:%M:%S %z"];
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
|
|
Loading…
Reference in a new issue