1 /* typecast_mxdatetime.c - date and time typecasting functions to mx types
3 * Copyright (C) 2001-2003 Federico Di Gregorio <fog@debian.org>
5 * This file is part of the psycopg module.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "mxDateTime.h"
24 /* the pointer to the mxDateTime API is initialized by the module init code,
25 we just need to grab it */
26 extern mxDateTimeModule_APIObject *mxDateTimeP;
28 /** DATE - cast a date into mx.DateTime python object **/
31 typecast_MXDATE_cast(char *str, int len, PyObject *curs)
34 int hh=0, mm=0, ss=0, us=0, tz=0;
37 if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
39 Dprintf("typecast_MXDATE_cast: s = %s", str);
41 /* check for infinity */
42 if (!strcmp(str, "infinity") || !strcmp(str, "-infinity")) {
44 return mxDateTimeP->DateTime_FromDateAndTime(-999998,1,1, 0,0,0);
47 return mxDateTimeP->DateTime_FromDateAndTime(999999,12,31, 0,0,0);
51 n = typecast_parse_date(str, &tp, &len, &y, &m, &d);
52 Dprintf("typecast_MXDATE_cast: tp = %p n = %d, len = %d, "
53 "y = %d, m = %d, d = %d", tp, n, len, y, m, d);
55 PyErr_SetString(DataError, "unable to parse date");
59 n = typecast_parse_time(tp, NULL, &len, &hh, &mm, &ss, &us, &tz);
60 Dprintf("typecast_MXDATE_cast: n = %d, len = %d, "
61 "hh = %d, mm = %d, ss = %d, us = %d, tz = %d",
62 n, len, hh, mm, ss, us, tz);
64 PyErr_SetString(DataError, "unable to parse time");
68 Dprintf("typecast_MXDATE_cast: fractionary seconds: %lf",
69 (double)ss + (double)us/(double)1000000.0);
70 return mxDateTimeP->DateTime_FromDateAndTime(y, m, d, hh, mm,
71 (double)ss + (double)us/(double)1000000.0);
74 /** TIME - parse time into an mx.DateTime object **/
77 typecast_MXTIME_cast(char *str, int len, PyObject *curs)
79 int n, hh=0, mm=0, ss=0, us=0, tz=0;
81 if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
83 Dprintf("typecast_MXTIME_cast: s = %s", str);
85 n = typecast_parse_time(str, NULL, &len, &hh, &mm, &ss, &us, &tz);
86 Dprintf("typecast_MXTIME_cast: time parsed, %d components", n);
87 Dprintf("typecast_MXTIME_cast: hh = %d, mm = %d, ss = %d, us = %d",
91 PyErr_SetString(DataError, "unable to parse time");
95 Dprintf("typecast_MXTIME_cast: fractionary seconds: %lf",
96 (double)ss + (double)us/(double)1000000.0);
97 return mxDateTimeP->DateTimeDelta_FromTime(hh, mm,
98 (double)ss + (double)us/(double)1000000.0);
101 /** INTERVAL - parse an interval into an mx.DateTimeDelta **/
104 typecast_MXINTERVAL_cast(char *str, int len, PyObject *curs)
106 long years = 0, months = 0, days = 0, denominator = 1;
107 double hours = 0.0, minutes = 0.0, seconds = 0.0, hundredths = 0.0;
108 double v = 0.0, sign = 1.0;
111 if (str == NULL) {Py_INCREF(Py_None); return Py_None;}
113 Dprintf("typecast_MXINTERVAL_cast: s = %s", str);
122 case '0': case '1': case '2': case '3': case '4':
123 case '5': case '6': case '7': case '8': case '9':
124 v = v*10 + (double)*str - (double)'0';
125 Dprintf("typecast_MXINTERVAL_cast: v = %f", v);
128 Dprintf("typecast_MXINTERVAL_cast: denominator = %ld",
135 years = (long)(v*sign);
136 str = skip_until_space(str);
137 Dprintf("typecast_MXINTERVAL_cast: years = %ld, rest = %s",
139 v = 0.0; sign = 1.0; part = 1;
145 months = (long)(v*sign);
146 str = skip_until_space(str);
147 Dprintf("typecast_MXINTERVAL_cast: months = %ld, rest = %s",
149 v = 0.0; sign = 1.0; part = 2;
155 days = (long)(v*sign);
156 str = skip_until_space(str);
157 Dprintf("typecast_MXINTERVAL_cast: days = %ld, rest = %s",
159 v = 0.0; sign = 1.0; part = 3;
166 Dprintf("typecast_MXINTERVAL_cast: hours = %f", hours);
169 else if (part == 4) {
171 Dprintf("typecast_MXINTERVAL_cast: minutes = %f", minutes);
179 Dprintf("typecast_MXINTERVAL_cast: seconds = %f", seconds);
191 /* manage last value, be it minutes or seconds or hundredths of a second */
194 Dprintf("typecast_MXINTERVAL_cast: minutes = %f", minutes);
196 else if (part == 5) {
198 Dprintf("typecast_MXINTERVAL_cast: seconds = %f", seconds);
200 else if (part == 6) {
202 Dprintf("typecast_MXINTERVAL_cast: hundredths = %f", hundredths);
203 hundredths = hundredths/denominator;
204 Dprintf("typecast_MXINTERVAL_cast: fractions = %.20f", hundredths);
207 /* calculates seconds */
209 seconds = - (hundredths + seconds + minutes*60 + hours*3600);
212 seconds += hundredths + minutes*60 + hours*3600;
215 /* calculates days */
216 days += years*365 + months*30;
218 Dprintf("typecast_MXINTERVAL_cast: days = %ld, seconds = %f",
220 return mxDateTimeP->DateTimeDelta_FromDaysAndSeconds(days, seconds);
223 /* psycopg defaults to using mx types */
225 #ifdef PSYCOPG_DEFAULT_MXDATETIME
226 #define typecast_DATE_cast typecast_MXDATE_cast
227 #define typecast_TIME_cast typecast_MXTIME_cast
228 #define typecast_INTERVAL_cast typecast_MXINTERVAL_cast
229 #define typecast_DATETIME_cast typecast_MXDATE_cast