/*================================================================= Copyright (C) 2000-2013 BizStation Corp All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. =================================================================*/ #include <bzs/env/compiler.h> #include <bzs/env/tstring.h> #include "btrDate.h" #include <bzs/rtl/datetime.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #ifdef LINUX #include <bzs/env/mbcswchrLinux.h> #if __clang__ #include <pthread.h> #endif #endif #pragma package(smart_init) #undef USETLS #if ((defined(_WIN32) && _MSC_VER) || (__APPLE__ && !defined(__BCPLUSPLUS__))) #define USETLS #endif #ifdef USETLS extern tls_key g_tlsiID_SC2; #else __THREAD _TCHAR __THREAD_BCB g_date2[45]; #endif inline _TCHAR* databuf() { #ifdef USETLS _TCHAR* p = (_TCHAR*)tls_getspecific(g_tlsiID_SC2); if (p == NULL) { p = (_TCHAR*)new wchar_t[45]; tls_setspecific(g_tlsiID_SC2, p); } return p; #else return g_date2; #endif } namespace bzs { using namespace rtl; namespace db { namespace protocol { namespace tdap { #define dateToi64(p) (((__int64)JDate2Num(p) - 1721426) * 86400) + _timezone #define timeToi64(t) t.ss + t.nn * 60 + t.hh * 3600 __int64 btrTimeStamp::getDateTimeInt(int& time) { // seconds from 0000-01-01 00:00:00 __int64 sec = i64 / 10000000 - _timezone; time = sec % 86400; // 1721426 days differs from JDate2Num. __int64 days = sec / 86400 + 1721426; return days; } btrTimeStamp::btrTimeStamp(unsigned __int64 i) : i64(i){}; btrTimeStamp::btrTimeStamp(const char* p) { fromString(p); } btrTimeStamp::btrTimeStamp(btrDate d, btrTime t) : i64(0) { i64 += timeToi64(t); i64 += dateToi64(btrdtoa(d, (_TCHAR*)NULL)); i64 *= 10000000; } #ifdef _WIN32 btrTimeStamp::btrTimeStamp(const wchar_t* p) { fromString(p); } wchar_t* btrTimeStamp::toString(wchar_t* p) { int time; int v = (int)getDateTimeInt(time); #ifdef _UNICODE swprintf_s(p, 20, _T("%s %02d:%02d:%02d"), JNum2Date(v), time / 3600, time % 3600 / 60, time % 3600 % 60); return p; #else char buf[30]; sprintf_s(buf, 30, _T("%s %02d:%02d:%02d"), JNum2Date(v), time / 3600, time % 3600 / 60, time % 3600 % 60); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buf, -1, p, 20); return p; #endif } void btrTimeStamp::fromString(const wchar_t* p) { i64 = 0; const wchar_t* p2 = wcsstr(p, L" "); if (p2) { btrTime t = atobtrt(p2 + 1); i64 += timeToi64(t); } i64 += dateToi64(p); i64 *= 10000000; } #endif //_WIN32 char* btrTimeStamp::toString(char* p) { int time; int v = (int)getDateTimeInt(time); #ifndef _UNICODE sprintf_s(p, 20, _T("%s %02d:%02d:%02d"), JNum2Date(v), time / 3600, time % 3600 / 60, time % 3600 % 60); return p; #else wchar_t buf[30]; swprintf_s(buf, 30, _T("%s %02d:%02d:%02d"), JNum2Date(v), time / 3600, time % 3600 / 60, time % 3600 % 60); wtoa(p, buf, 20); return p; #endif } void btrTimeStamp::fromString(const char* p) { i64 = 0; const char* p2 = strstr(p, " "); if (p2) { btrTime t = atobtrt(p2 + 1); i64 += timeToi64(t); } i64 += dateToi64(p); i64 *= 10000000; } bdate::bdate(int date) { m_date.i = date; } bdate::bdate(const _TCHAR* date) { btrDate bt; bt.yy = (short)GetYear(date, false); bt.mm = (char)GetMonth(date, false); bt.dd = (char)bzs::rtl::GetDate(date); m_date = bt; } const _TCHAR* bdate::year_str() { _TCHAR* p = databuf(); _stprintf_s(p, 30, _T("%d"), (int)m_date.yy); return p; } const _TCHAR* bdate::month_str() { _TCHAR* p = databuf(); _stprintf_s(p, 30, _T("%d"), (int)m_date.mm); return p; } const _TCHAR* bdate::date_str() { _TCHAR* p = databuf(); _stprintf_s(p, 30, _T("%d"), (int)m_date.dd); return p; } const _TCHAR* bdate::c_str() { return btrdtoa(m_date, (_TCHAR*)NULL); } const char* dateFormatString(const char*) { return "%04d/%02d/%02d"; } const wchar_t* dateFormatString(const wchar_t*) { return L"%04d/%02d/%02d"; } const char* dateFormatString_h(const char*) { return "%04d-%02d-%02d"; } const wchar_t* dateFormatString_h(const wchar_t*) { return L"%04d-%02d-%02d"; } const char* timeFormatString(const char*) { return "%02d:%02d:%02d"; } const wchar_t* timeFormatString(const wchar_t*) { return L"%02d:%02d:%02d"; } const char* timeFormatString_h(const char*) { return "%02d-%02d-%02d"; } const wchar_t* timeFormatString_h(const wchar_t*) { return L"%02d-%02d-%02d"; } template <class T> size_t _tcslen_(const T* p); template <> size_t _tcslen_(const char* p) { return strlen(p); } template <> size_t _tcslen_(const wchar_t* p) { return wcslen(p); } template <class T> int _ttoi_(const T* p); template <> int _ttoi_(const char* p) { return atoi(p); } template <> int _ttoi_(const wchar_t* p) { return _wtoi(p); } template <class T> T* formatDate(T* p, const btrDate& d, bool type_vb); template <> char* formatDate(char* p, const btrDate& d, bool type_vb) { if (type_vb) sprintf_s(p, 20, dateFormatString_h(p), d.yy, d.mm, d.dd); else sprintf_s(p, 20, dateFormatString(p), d.yy, d.mm, d.dd); return p; } template <> wchar_t* formatDate(wchar_t* p, const btrDate& d, bool type_vb) { if (type_vb) swprintf_s(p, 20, dateFormatString_h(p), d.yy, d.mm, d.dd); else swprintf_s(p, 20, dateFormatString(p), d.yy, d.mm, d.dd); return p; } template <class T> T* formatTime(T* p, const btrTime& d, bool type_vb); template <> char* formatTime(char* p, const btrTime& t, bool type_vb) { if (type_vb) sprintf_s(p, 20, timeFormatString_h(p), t.hh, t.nn, t.ss); else sprintf_s(p, 20, timeFormatString(p), t.hh, t.nn, t.ss); return p; } template <> wchar_t* formatTime(wchar_t* p, const btrTime& t, bool type_vb) { if (type_vb) swprintf_s(p, 20, timeFormatString_h(p), t.hh, t.nn, t.ss); else swprintf_s(p, 20, timeFormatString(p), t.hh, t.nn, t.ss); return p; } template <class T> btrDate atobtrd(const T* date) { btrDate bt; bt.i = 0; if (date && ((_tcslen_(date) == 10) || ((_tcslen_(date) > 10) && (date[10] == 'T' || date[10] == ' ')))) { bt.yy = (short)_ttoi_(date); bt.mm = (char)_ttoi_(date + 5); bt.dd = (char)_ttoi_(date + 8); } return bt; } template <class T> const T* btrdtoa(const btrDate& d, T* retbuf, bool type_vb) { T* p = retbuf; if (p == NULL) p = (T*)databuf(); return formatDate(p, d, type_vb); } template <class T> const T* btrttoa(const btrTime& t, T* retbuf, bool type_vb) { T* p = retbuf; if (p == NULL) p = (T*)databuf(); return formatTime(p, t, type_vb); } template <class T> btrTime atobtrt(const T* p) { btrTime retVal; retVal.i = 0; if (p && (_tcslen_(p) == 8)) { retVal.hh = (char)_ttoi_(p); retVal.nn = (char)_ttoi_(p + 3); retVal.ss = (char)_ttoi_(p + 6); } else retVal.i = 0; return retVal; } btrDate atobtrd(const char* p) { return atobtrd<char>(p); } const char* btrdtoa(const btrDate& d, char* retbuf, bool type_vb) { return btrdtoa<char>(d, retbuf, type_vb); } const char* btrttoa(const btrTime& t, char* retbuf, bool type_vb) { return btrttoa<char>(t, retbuf, type_vb); } btrTime atobtrt(const char* p) { return atobtrt<char>(p); } #ifdef _WIN32 const wchar_t* btrdtoa(const btrDate& d, wchar_t* retbuf, bool type_vb) { return btrdtoa<wchar_t>(d, retbuf, type_vb); } const wchar_t* btrttoa(const btrTime& t, wchar_t* retbuf, bool type_vb) { return btrttoa<wchar_t>(t, retbuf, type_vb); } btrDate atobtrd(const wchar_t* p) { return atobtrd<wchar_t>(p); } btrTime atobtrt(const wchar_t* p) { return atobtrt<wchar_t>(p); } #endif const _TCHAR* btrstoa(const btrDateTime& s, _TCHAR* retbuf, bool type_vb) { _TCHAR* p = retbuf; const btrDate& d = s.date; const btrTime& t = s.time; if (p == NULL) p = databuf(); ; if (type_vb) _stprintf_s(p, 21, _T("%04d-%02d-%02dT%02d:%02d:%02d"), d.yy, d.mm, d.dd, t.hh, t.nn, t.ss); else _stprintf_s(p, 21, _T("%04d/%02d/%02d %02d:%02d:%02d"), d.yy, d.mm, d.dd, t.hh, t.nn, t.ss); return p; } btrDateTime atobtrs(const _TCHAR* p) { btrDateTime s; s.i64 = 0; s.date = atobtrd(p); const _TCHAR* tmp = _tcsstr(p, _T("T")); if (tmp) s.time = atobtrt(tmp + 1); else if ((tmp = _tcsstr(p, _T(" "))) != NULL) s.time = atobtrt(tmp + 1); return s; } int getNowDate() { btrDate dtb; #ifdef _WIN32 SYSTEMTIME pst; GetLocalTime(&pst); dtb.yy = (short)pst.wYear; dtb.mm = (char)(pst.wMonth); dtb.dd = (char)pst.wDay; #else // not _WIN32 struct tm* date; time_t now; time(&now); struct tm tmp; date = &tmp; localtime_x(date, &now); dtb.yy = (short)date->tm_year + 1900; dtb.mm = (char)date->tm_mon + 1; dtb.dd = (char)date->tm_mday; #endif // NOT _WIN32 return dtb.i; } int getNowTime() { btrTime tmb; #ifdef _WIN32 tmb.i = 0; SYSTEMTIME pst; GetLocalTime(&pst); tmb.hh = (char)pst.wHour; tmb.nn = (char)pst.wMinute; tmb.ss = (char)pst.wSecond; tmb.uu = (char)(pst.wMilliseconds / 10); #else struct tm* date; time_t now; time(&now); struct tm tmp; date = &tmp; localtime_x(date, &now); tmb.hh = (char)date->tm_hour; tmb.nn = (char)date->tm_min; tmb.ss = (char)date->tm_sec; tmb.uu = 00; #endif return tmb.i; } } // namespace tdap } // namespace protocol } // namespace db } // namespace bzs