SqlDate.h File Reference

SqlDate. More...

Go to the source code of this file.

Enumerations

enum  SqlDateTimeType { SQLDATE, SQLTIME, SQLTIMESTAMP }

Functions

boost::posix_time::ptime const epoc (boost::gregorian::date(1970, 1, 1))
int FENNEL_CALCULATOR_EXPORT TimeToIsoString (char *dest, boost::posix_time::ptime t)
int FENNEL_CALCULATOR_EXPORT DateToIsoString (char *dest, boost::posix_time::ptime t)
int FENNEL_CALCULATOR_EXPORT TimestampToIsoString (char *dest, boost::posix_time::ptime t)
int64_t FENNEL_CALCULATOR_EXPORT IsoStringToTime (char const *const src, int len)
int64_t FENNEL_CALCULATOR_EXPORT IsoStringToDate (char const *const src, int len)
int64_t FENNEL_CALCULATOR_EXPORT IsoStringToTimestamp (char const *const src, int len)
template<int CodeUnitBytes, int MaxCodeUnitsPerCodePoint, SqlDateTimeType dateTimeType>
int SqlDateToStr (char *dest, int destStorageBytes, int64_t const d, bool fixed=false, int padchar= ' ')
template<int CodeUnitBytes, int MaxCodeUnitsPerCodePoint, SqlDateTimeType dateTimeType>
int64_t SqlStrToDate (char *src, int len)
int64_t FENNEL_CALCULATOR_EXPORT UniversalTime ()
 Returns time of day in UTC.
int64_t FENNEL_CALCULATOR_EXPORT UniversalTimestamp ()
 Returns timestamp in UTC.
int64_t FENNEL_CALCULATOR_EXPORT LocalTime (boost::local_time::time_zone_ptr tzPtr)
 Returns the time of day in the given time zone.
int64_t FENNEL_CALCULATOR_EXPORT LocalTimestamp (boost::local_time::time_zone_ptr tzPtr)
 Returns the timestamp in the given time zone.


Detailed Description

SqlDate.

Definition in file SqlDate.h.


Enumeration Type Documentation

enum SqlDateTimeType

Enumerator:
SQLDATE 
SQLTIME 
SQLTIMESTAMP 

Definition at line 53 of file SqlDate.h.

00053                      {
00054     SQLDATE,
00055     SQLTIME,
00056     SQLTIMESTAMP
00057 };


Function Documentation

int FENNEL_CALCULATOR_EXPORT DateToIsoString ( char *  dest,
boost::posix_time::ptime  t 
)

Definition at line 47 of file SqlDate.cpp.

Referenced by SqlDateToStr().

00048 {
00049     int y = t.date().year();
00050     int m =  t.date().month();
00051     int dy = t.date().day();
00052     return snprintf(dest,11, "%4d-%02d-%02d", y,m, dy);
00053 }

boost::posix_time::ptime const epoc ( boost::gregorian::  date(1970, 1, 1)  ) 

Referenced by IsoStringToDate(), IsoStringToTimestamp(), SqlDateToStr(), and UniversalTimestamp().

int64_t FENNEL_CALCULATOR_EXPORT IsoStringToDate ( char const *const  src,
int  len 
)

Definition at line 96 of file SqlDate.cpp.

References epoc(), milliseconds_per_day, and trimSpaces().

Referenced by SqlStrToDate(), and SqlDateTest::testSqlStrToDate_Ascii_Helper().

00097 {
00098     std::string s(src,len);
00099     trimSpaces(s);
00100 
00101     boost::regex dateExp("\\d+-\\d+-\\d+");
00102     if (boost::regex_match(s, dateExp)) {
00103         try {
00104             date_duration td = boost::gregorian::from_string(s) - epoc.date();
00105             return td.days() * milliseconds_per_day;
00106         } catch (...) {
00107             // Fall through to throw
00108         }
00109     }
00110 
00111     // Parse of date failed
00112     // SQL2003 Part 2 Section 6.12 General Rule 13 data
00113     // exception -- invalid datetime format
00114     throw "22007";
00115 }

int64_t FENNEL_CALCULATOR_EXPORT IsoStringToTime ( char const *const  src,
int  len 
)

Definition at line 117 of file SqlDate.cpp.

References min(), and trimSpaces().

Referenced by SqlStrToDate(), and SqlDateTest::testSqlStrToDate_Ascii_Helper().

00118 {
00119     std::string s(src, len);
00120     trimSpaces(s);
00121 
00122     // TODO: Boost library doesn't catch invalid hour, min, sec
00123     // TODO: Try updated boost library to see if we can get
00124     // TODO: rid of this tiresome check
00125     boost::cmatch what;
00126     boost::regex timeExp("(\\d+):(\\d+):(\\d+)(\\.\\d+)?");
00127     if (boost::regex_match(s.c_str(), what, timeExp)) {
00128         try {
00129             int hour = atoi(what[1].first);
00130             int min = atoi(what[2].first);
00131             int sec = atoi(what[3].first);
00132 
00133             if ((hour >= 0) && (hour < 24) &&
00134                 (min >= 0) && (min < 60) &&
00135                 (sec >= 0) && (sec < 60)) {
00136                 time_duration td = duration_from_string(s);
00137                 return td.total_milliseconds();
00138             }
00139         } catch (...) {
00140             // Fall through to throw
00141         }
00142     }
00143 
00144     // Parse of time failed
00145     // SQL2003 Part 2 Section 6.12 General Rule 15,16 data
00146     // exception -- invalid datetime format
00147     throw "22007";
00148 }

int64_t FENNEL_CALCULATOR_EXPORT IsoStringToTimestamp ( char const *const  src,
int  len 
)

Definition at line 150 of file SqlDate.cpp.

References epoc(), min(), and trimSpaces().

Referenced by SqlStrToDate(), and SqlDateTest::testSqlStrToDate_Ascii_Helper().

00151 {
00152     std::string s(src, len);
00153     trimSpaces(s);
00154 
00155     // TODO: Boost library doesn't catch invalid hour, min, sec
00156     // TODO: Try updated boost library to see if we can get
00157     // TODO: rid of this tiresome check
00158     boost::cmatch what;
00159     boost::regex timestampExp("\\d+-\\d+-\\d+ +"
00160                        "(\\d+):(\\d+):(\\d+)(\\.\\d+)?");
00161     if (boost::regex_match(s.c_str(), what, timestampExp)) {
00162         try {
00163             int hour = atoi(what[1].first);
00164             int min = atoi(what[2].first);
00165             int sec = atoi(what[3].first);
00166 
00167             if ((hour >= 0) && (hour < 24) &&
00168                 (min >= 0) && (min < 60) &&
00169                 (sec >= 0) && (sec < 60)) {
00170                 ptime p(time_from_string(s));
00171                 time_duration td = p - epoc;
00172                 return td.total_milliseconds();
00173             }
00174         } catch (...) {
00175             // Fall through to throw
00176         }
00177     }
00178 
00179     // Parse of timestamp failed
00180     // SQL2003 Part 2 Section 6.12 General Rule 17,18 data
00181     // exception -- invalid datetime format
00182     throw "22007";
00183 }

int64_t FENNEL_CALCULATOR_EXPORT LocalTime ( boost::local_time::time_zone_ptr  tzPtr  ) 

Returns the time of day in the given time zone.

Definition at line 203 of file SqlDate.cpp.

00204 {
00205     local_date_time plocal = local_microsec_clock::local_time(tzPtr);
00206     return plocal.local_time().time_of_day().total_milliseconds();
00207 }

int64_t FENNEL_CALCULATOR_EXPORT LocalTimestamp ( boost::local_time::time_zone_ptr  tzPtr  ) 

Returns the timestamp in the given time zone.

Definition at line 209 of file SqlDate.cpp.

00210 {
00211     // Create a local epoch. For PST, for example, the epoch is 1970/1/1 PST,
00212     // which occurred 8 hrs after the UTC epoch.
00213     date d(1970, 1, 1);
00214     time_duration td(0, 0, 0);
00215     local_date_time local_epoc(
00216         d, td, tzPtr, local_date_time::NOT_DATE_TIME_ON_ERROR);
00217 
00218     local_date_time plocal = local_microsec_clock::local_time(tzPtr);
00219     time_duration diff = plocal - local_epoc;
00220 
00221     // Adjust the difference if we are now in DST and the epoch is not, or vice
00222     // versa.
00223     if (plocal.is_dst()) {
00224         if (local_epoc.is_dst()) {
00225             // same offset: nothing to do
00226         } else {
00227             diff += tzPtr->dst_offset();
00228         }
00229     } else {
00230         if (local_epoc.is_dst()) {
00231             diff -= tzPtr->dst_offset();
00232         } else {
00233             // same offset: nothing to do
00234         }
00235     }
00236     return diff.total_milliseconds();
00237 }

template<int CodeUnitBytes, int MaxCodeUnitsPerCodePoint, SqlDateTimeType dateTimeType>
int SqlDateToStr ( char *  dest,
int  destStorageBytes,
int64_t const  d,
bool  fixed = false,
int  padchar = ' ' 
)

Definition at line 80 of file SqlDate.h.

References DateToIsoString(), epoc(), fixed, SQLDATE, SQLTIME, SQLTIMESTAMP, TimestampToIsoString(), and TimeToIsoString().

00086 {
00087     using namespace boost::posix_time;
00088     using namespace boost::gregorian;
00089 
00090     typedef boost::date_time::c_local_adjustor<boost::posix_time::ptime>
00091         local_adj;
00092     if (CodeUnitBytes == MaxCodeUnitsPerCodePoint) {
00093         if (CodeUnitBytes == 1) {
00094             // ASCII
00095 
00096             // from_time_t isn't in the version of boost we're using. sigh.
00097             // FIXME: jhyde: No longer true. Let's use it.
00098             //   boost::posix_time::ptime t = boost::posix_time::from_time_t(d);
00099 
00100             // we could use the millisecond() duration constructor,
00101             // instead of time_duration(...), but the time_duration was
00102             // the only way i could find didn't use an explicit long
00103             // parameter, instead of the type parameter, since
00104             // int64_t == (long long) on (fc1) linux.
00105             boost::posix_time::ptime t = epoc + time_duration(0,0,0,d);
00106 
00107             int len;
00108             char buf[20];
00109             switch (dateTimeType) {
00110             case SQLDATE:
00111                 len = DateToIsoString(buf, t);
00112                 if (len > destStorageBytes) {
00113                     // SQL99 Part 2 Section 6.22 General Rule 9.a.iii =>
00114                     // exception SQL99 22.1 22-001 "String Data Right
00115                     // truncation"
00116                     throw "22001";
00117                 }
00118                 memcpy(dest,buf,len);
00119                 break;
00120             case SQLTIME:
00121                 len = TimeToIsoString(buf, t);
00122                 if (len > destStorageBytes) {
00123                     // SQL99 Part 2 Section 6.22 General Rule 9.a.iii =>
00124                     // exception SQL99 22.1 22-001 "String Data Right
00125                     // truncation"
00126                     throw "22001";
00127                 }
00128                 memcpy(dest,buf,len);
00129                 break;
00130             case SQLTIMESTAMP:
00131                 len = TimestampToIsoString(buf, t);
00132                 if (len > destStorageBytes) {
00133                     // SQL99 Part 2 Section 6.22 General Rule 9.a.iii =>
00134                     // exception SQL99 22.1 22-001 "String Data Right
00135                     // truncation"
00136                     throw "22001";
00137                 }
00138                 memcpy(dest,buf,len);
00139                 break;
00140             default:
00141                 throw std::logic_error("bad dateTimeType" + dateTimeType);
00142             }
00143 
00144             if (fixed) {
00145                 memset(dest + len, padchar, destStorageBytes - len);
00146                 return destStorageBytes;
00147             } else {
00148                 return len;
00149             }
00150         } else if (CodeUnitBytes == 2) {
00151             // TODO: Add UCS2 here
00152             throw std::logic_error("no UCS2");
00153         } else {
00154             throw std::logic_error("no such encoding");
00155         }
00156     } else {
00157         throw std::logic_error("no UTF8/16/32");
00158     }
00159 
00160 }

template<int CodeUnitBytes, int MaxCodeUnitsPerCodePoint, SqlDateTimeType dateTimeType>
int64_t SqlStrToDate ( char *  src,
int  len 
)

Definition at line 167 of file SqlDate.h.

References IsoStringToDate(), IsoStringToTime(), IsoStringToTimestamp(), SQLDATE, SQLTIME, and SQLTIMESTAMP.

00168 {
00169     using namespace boost::posix_time;
00170     using namespace boost::gregorian;
00171 
00172     if (CodeUnitBytes == MaxCodeUnitsPerCodePoint) {
00173         if (CodeUnitBytes == 1) {
00174             // ASCII
00175 
00176             switch (dateTimeType) {
00177             case SQLDATE:
00178                 return IsoStringToDate(src,len);
00179             case SQLTIME:
00180                 return IsoStringToTime(src,len);
00181             case SQLTIMESTAMP:
00182                 return IsoStringToTimestamp(src,len);
00183             }
00184         } else if (CodeUnitBytes == 2) {
00185             // TODO: Add UCS2 here
00186             throw std::logic_error("no UCS2");
00187         } else {
00188             throw std::logic_error("no such encoding");
00189         }
00190     } else {
00191         throw std::logic_error("no UTF8/16/32");
00192     }
00193 }

int FENNEL_CALCULATOR_EXPORT TimestampToIsoString ( char *  dest,
boost::posix_time::ptime  t 
)

Definition at line 65 of file SqlDate.cpp.

References min().

Referenced by SqlDateToStr().

00066 {
00067     time_duration td = t.time_of_day();
00068     int h   = td.hours();
00069     int min = td.minutes();
00070     int s   = td.seconds();
00071 
00072     int y   = t.date().year();
00073     int mon = t.date().month();
00074     int dy  = t.date().day();
00075     return snprintf(
00076         dest, 20, "%4d-%02d-%02d %02d:%02d:%02d", y,mon, dy, h, min, s);
00077 }

int FENNEL_CALCULATOR_EXPORT TimeToIsoString ( char *  dest,
boost::posix_time::ptime  t 
)

Definition at line 56 of file SqlDate.cpp.

Referenced by SqlDateToStr().

00057 {
00058     time_duration td = t.time_of_day();
00059     int h = td.hours();
00060     int m = td.minutes();
00061     int s = td.seconds();
00062     return snprintf(dest,9, "%02d:%02d:%02d", h, m, s);
00063 }

int64_t FENNEL_CALCULATOR_EXPORT UniversalTime (  ) 

Returns time of day in UTC.

(This function used to be called CurrentTime, but as FNL-77 points out, that is misleading, because CurrentTime's result is in the local timezone.)

Definition at line 185 of file SqlDate.cpp.

Referenced by CurrentTime(), and SqlDateTest::testUniversalTime().

00186 {
00187     ptime p = second_clock::universal_time();
00188     return p.time_of_day().total_milliseconds();
00189 }

int64_t FENNEL_CALCULATOR_EXPORT UniversalTimestamp (  ) 

Returns timestamp in UTC.

That is, milliseconds since 1970-1-1 00:00:00 UTC.

(This function used to be called CurrentTimestamp, but as FNL-77 points out, that is misleading, because CurrentTimestamp's result is in the local timezone.)

Definition at line 191 of file SqlDate.cpp.

References epoc().

Referenced by CurrentTimestamp(), and SqlDateTest::testUniversalTime().

00192 {
00193     // REVIEW: SWZ: 4/30/2006: In practice, we should return the micro
00194     // second delta (or as much precision as we can muster) and let
00195     // the instruction (which may have been given an explicit
00196     // precision) truncate the fractional seconds.  For now, returning
00197     // millis causes Fennel Calc to behave like the Java Calc for
00198     // CURRENT_TIME[STAMP].
00199     ptime p = microsec_clock::universal_time();
00200     return (p - epoc).total_milliseconds();
00201 }


Generated on Mon Jun 22 04:00:22 2009 for Fennel by  doxygen 1.5.1