Malaja
|
|
« : 01-03-2004 15:20 » |
|
Gospoda! Perwoe - izwinjajus za shrift (u menja, po neshastju, tolko anglojazichnaja klawiatura ;-( ) Wtoroe - sobstwenno wopros : w C - programme neobhodimo rabotat s datami. T.e. sozdat 2 peremennie tipa time_t, preobrazowat s pomoshju localtime() w strukturu tm. A zatem wichislit raznitu megdu etimi dwumja datami w forme kolichestwa dnej. Naprimer : 01.03.2004 - 01.02.2004 = 29 W Microsoft C++ dlja etih zelej prekrasno ispolzuetsja COleDateTime, no w etom sluchae mne nugna programma, kotoraja odinakowo rabotala bi pod Microsoftom i Linuxom plus w swjazi so spezifikoj dolgna bit woobshe napisana na C, posemu i takaja problema. Budu ochen blagodarna za pomosh.
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
ysv_
Помогающий
Offline
|
|
« Ответ #1 : 01-03-2004 17:03 » |
|
У меня есть исходник на С++: H-файл -------------------------------------- #ifndef DATE_H #define DATE_H
#include <iosfwd> #include <string>
class Date { public: typedef unsigned char DAY; typedef unsigned char MONTH; typedef unsigned short YEAR; typedef int NDAYS;
struct YMD { YEAR y; MONTH m; DAY d; };
public: Date(NDAYS nd=0): nDays_(nd) {if (nd<0) nDays_=0;} Date(YEAR year, MONTH month, DAY day);
Date& operator=(const YMD ymd) {nDays_=ConvertToNDays(ymd);} Date operator+(NDAYS n) const; Date operator-(NDAYS n) const; NDAYS operator+(const Date d) const { return GetDaysNumber()+d.GetDaysNumber(); } NDAYS operator-(const Date d) const { return GetDaysNumber()-d.GetDaysNumber(); }
bool operator==(const Date& d) const {return nDays_==d.nDays_;}
bool Empty() {return nDays_==0;} operator Date::YMD() const; operator std::string() const; std::string GetFullString() const; NDAYS GetDaysNumber() const {return nDays_;} YEAR year() const {return 0;} MONTH month() const {return 0;} DAY day() const {return 0;}
static const char* GetMonthName(int i) {return months_[i-1];} static DAY LastMonthDay(YEAR y, MONTH m); static bool IsLeap(YEAR y) {return y%4==0 && (y%100!=0 || y%400==0);} static Date CurrentDate() {return Date();} static int ConvertToNDays(YMD ymd);
friend std::ostream& operator<<(std::ostream& os, const Date& d); friend std::istream& operator>>(std::istream& is, Date& d);
private: NDAYS nDays_; static char const * months_[12]; }; #endif ------------------------------------------------------------------------------------ СPP файл ------------------------------------------------------------------------------------ // (14-month)/12 = 1 для сiчня та лютого // year-flag - змiщуємо рiк таким чином, щоб останнiм мiсяцем року був лютий // 12*flag+month-3 - змiнюємо нумерацiю мiсяцiв: березень - 0, лютий - 11. // (153*mc+2)/5 - кiлькiсть днiв: // березень (0) - +0 липень (4) - +122 листопад (8) - +245 // квiтень (1) - +31 серпень (5) - +153 грудень (9) - +275 // травень (2) - +61 вересень (6) - +184 сiчень (10) - +306 // червень (3) - +92 жовтень (7) - +214 лютий (11) - +337 #include <iomanip> #include <sstream> #include "Date.h"
using namespace std;
const char* Date::months_[12]={"сiчня", "лютого", "березня", "квiтня", "травня", "червня", "липня", "серпня", "вересня", "жовтня", "листопада", "грудня"};
Date::Date(Date::YEAR year, Date::MONTH month, Date::DAY day) { YMD ymd={year, month, day}; nDays_=ConvertToNDays(ymd); }
int Date::ConvertToNDays(Date::YMD ymd) { if (ymd.d==0 || ymd.d>LastMonthDay(ymd.y, ymd.m)) return 0; YEAR yc; MONTH mc; char flag=(14-ymd.m)/12; yc=ymd.y-flag; mc=12*flag+ymd.m-3; return ymd.d+(153*mc+2)/5+365*yc+yc/4-yc/100+yc/400; }
static Date::DAY lmd[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
Date::DAY Date::LastMonthDay(Date::YEAR y, Date::MONTH m) { if (y>=10000 || y==0 || m>=13 || m==0) return 0; DAY md=lmd[m-1]; if (m==2) { md+=IsLeap(y); } return md; }
Date::operator std::string() const { ostringstream s; s<<*this; return s.str(); }
Date::operator Date::YMD() const { YMD ymd; NDAYS ndc, y100, nd100, y, nd, mc; ndc=nDays_-1; y100=(4*ndc+3)/146097; nd100=ndc-(146097*y100)/4; y=(4*nd100+3)/1461; nd=nd100-(1461*y)/4; mc=(5*nd+2)/153; ymd.d=nd-(153*mc+2)/5+1; char flag=mc/10; ymd.m=mc+3-12*flag; ymd.y=100*y100+y+flag; return ymd; }
Date Date::operator+(int n) const { return Date(nDays_+n); }
Date Date::operator-(int n) const { return Date(nDays_-n); }
std::string Date::GetFullString() const { if (GetDaysNumber()<=0) return ""; Date::YMD ymd(*this); std::ostringstream str; str<<int(ymd.d)<<' '<<GetMonthName(ymd.m)<<' '<<int(ymd.y)<<" року"; return str.str(); }
ostream& operator<<(ostream& os, const Date& d) { if (d.GetDaysNumber()<=0) return os<<" / / "; Date::YMD ymd=d; return os<<setfill('0')<<setw(2)<<int(ymd.d)<<'/'<<setw(2)<<int(ymd.m) <<'/'<<setw(4)<<int(ymd.y); }
std::istream& operator>>(std::istream& is, Date& d) { int y, m, day; is>>day; is.ignore(); is>>m; is.ignore(); is>>y; d=Date(y, m, day); return is; } ----------------------------------------------------------------------------------------- Если что не понятно - спрашивай.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #2 : 01-03-2004 21:05 » |
|
Malaja, а не проше ли сделать разницу между двумя time_t, чем struct tm ? А потом просто разделить на 86400 (секунд в сутках).
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Sashok
Молодой специалист
Offline
Пол:
|
|
« Ответ #3 : 02-03-2004 02:35 » |
|
RXL,
|
|
|
Записан
|
Если бы окружающие нас объекты содержали столько же ошибок, сколько программы, цивилизация обрушилась бы от первого порыва ветра...
|
|
|
wsem
Гость
|
|
« Ответ #4 : 12-03-2004 18:00 » |
|
Perwoe - wsem ogromnoe spasibo! Izwinjajus, chto ne otwetila srazu. Na rabote prosto, kak wsegda, segodnja wijasnjaetsja, chto proekt nado bilo sdat eshe pozawchera RLX, spasibo za podskazku - kogda prochitala, ponjala, chto mne uge w otpusk pora, t.k. ja ishu slognie puti wmesto normalnih (aha, normalnie geroi wsegda idut w obhod - eto pro menja ) Edinswennoe, chto ja hotela bi dobawit - poluchaemij rezultat neobhodimo umenshat na 1 (widimo, eto pogreshnosti okruglenija). Esli komu-to wse eto toge ponadobitsja, to kod wigljadit tak : ( - convertStrToDate() perewodit -char- w -time_t- - convertDateToStr() perewodit -tm- w -char- - checkDateInterval() rass'chitiwaet raznizu megdu dwumja dannimi tipa -date- ) //********************************************* // convert string to time_t //********************************************* bool CLicCheckApp::convertStrToDate(const char* buf, time_t* pTmpDT) { try { bool bIsOk = true; char strSep[5], *pStrTmp = NULL, strTmp[BUFFER_SIZE]; int nDate[3], i; tm* tmnow = NULL; time_t tmpDT; strcpy(strSep, "."); strcpy(strTmp, buf);
// razbiwaem String (napr. "22.01.2004") na chasti, ispolzuja razdelitel "." for (i = 0; i < 3; i++) { if (i == 0) { pStrTmp = strtok(strTmp, strSep); } else { if(pStrTmp != NULL) { pStrTmp = strtok(NULL, strSep); } }
if(pStrTmp != NULL) nDate[i] = atoi(pStrTmp); // [0] - d, [1] - m, [2] - y }
// init the struct time(&tmpDT); // perewodim w -tm- tmnow = localtime(&tmpDT);
// ustanawliwaem nashi znachenija tmnow->tm_mday = nDate[0]; tmnow->tm_mon = nDate[1] - 1; tmnow->tm_year = nDate[2] - 1900; // perewodim w -time_t- tmpDT = mktime(tmnow); *pTmpDT = tmpDT;
return bIsOk; } catch(...) { printf("error"); return false; } }
//********************************************* // convert tm to string //********************************************* void CLicCheckApp::convertDateToStr(char* buf, const tm* pTmpDT) { try { int d, m, y; char buf1[128];
strcpy(buf1, ""); if (buf) strcpy(buf, ""); else return;
d = pTmpDT->tm_mday; m = pTmpDT->tm_mon + 1; y = pTmpDT->tm_year + 1900;
sprintf(buf1, "%d", d); strcat(buf, buf1); strcat(buf, ".");
sprintf(buf1, "%d", m); strcat(buf, buf1); strcat(buf, ".");
sprintf(buf1, "%d", y); strcat(buf, buf1); return; } catch(...) { printf("error"); return; } }
//********************************************* // find interval between two time_t //********************************************* bool CLicCheckApp::checkDateInterval(const char* pStrNow_in, const char* pStrCreateDate_in, int& nDiff_out) { try { bool bIsOk = true; time_t tmpDT1, tmpDT2;
// perewodim string - Type w DateTime - Typ bIsOk = convertStrToDate(pStrNow_in, &tmpDT1); if (bIsOk) bIsOk = convertStrToDate(pStrCreateDate_in, &tmpDT2);
if (bIsOk) { // rass'chitiwaem raznizu nDiff_out = ( difftime(tmpDT1, tmpDT2) / (24*60*60) ) -1; if (nDiff_out < 0) { printf("nDiff_out < 0"); bIsOk = false; } }
return bIsOk; } catch(...) { printf("error"); return false; } }
|
|
« Последнее редактирование: 24-11-2007 14:13 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #5 : 12-03-2004 19:39 » |
|
Malaja, не перетруждайся - всех денег не заработаешь, а здоровие одно. С заданиями всегда так - "чтоб ко вчера было готово" Насчтет конверсии cahr<->date : я все же сторонник POSIX (там за нас давно уже многое продумали) и не уверен есть ли эти ф-ии в комплекте с VC++, но все же приведу: /* Преобразование времени в строку: */ char * asctime (const struct tm *BROKENTIME);
char * asctime_r (const struct tm *BROKENTIME, char *BUFFER);
char * ctime (const time_t *TIME);
char * ctime_r (const time_t *TIME, char *BUFFER);
size_t strftime (char *S, size_t SIZE, const char *TEMPLATE, const struct tm *BROKENTIME); /* это похоже на sprintf() */
size_t wcsftime (wchar_t *S, size_t SIZE, const wchar_t *TEMPLATE, const struct tm *BROKENTIME);
/* Разбор строки: */ char * strptime (const char *S, const char *FMT, struct tm *TP); /* похоже на sscanf() */
struct tm * getdate (const char *STRING);
int getdate_r (const char *STRING, struct tm *TP);
|
|
« Последнее редактирование: 24-11-2007 14:15 от Алексей1153++ »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Sashok
Молодой специалист
Offline
Пол:
|
|
« Ответ #6 : 14-03-2004 15:27 » |
|
RXL, если не ошибаюсь, в POSIX входит еще и localtime(...)
|
|
|
Записан
|
Если бы окружающие нас объекты содержали столько же ошибок, сколько программы, цивилизация обрушилась бы от первого порыва ветра...
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #7 : 14-03-2004 19:04 » |
|
Sashok, угу: struct tm * localtime(const time_t *TIME); Но какое это имеет отношение к переводу время<->строка? Или ты о другом?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Sashok
Молодой специалист
Offline
Пол:
|
|
« Ответ #8 : 15-03-2004 02:13 » |
|
RXL, имеет, хотя и не непосредственное. В общем, я бы сказал, что и gmtime() и localtime(), по-разному преобразовывая time_t в struct tm, в конечном итоге используются на пути вермя -> текст.
|
|
|
Записан
|
Если бы окружающие нас объекты содержали столько же ошибок, сколько программы, цивилизация обрушилась бы от первого порыва ветра...
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #9 : 15-03-2004 08:52 » |
|
Тогда капаем глубже: time.hКстати, не зря капнул - есть ф-ия для получения разницы времени double difftime(time_t time1, time_t time0). Смысл ее в том, что time_t не обязано быть равной int.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Anonymous
Гость
|
|
« Ответ #10 : 16-03-2004 07:53 » |
|
Malaja, не перетруждайся - всех денег не заработаешь, а здоровие одно. С заданиями всегда так - "чтоб ко вчера было готово" :
Spasibo za ponimanie - eto wsegda prijatno. Ja uge dawno starajus ne brat tjagelogo w ruki i durnogo w golowu, no inogda prihoditsja Po powodu funkzij - spasibo za informaziju. Ja zaodno posmotrela w MSDN, kakie iz nih podhodjat dlja Microsoftowskoj wersii C/C++. Okazalos, chto pochti wse , za iskljucheniem teh, kotorie prednaznacheni dlja razbora stroki. Ja hot teper znat budu, chto eto sushestwuet. Prawda, est odno obstojatelstwo, kotoroe mne neponjatno - w Wine i Linuxe sushestwuet <time.h>. Kak ge togda oni imejut w nalichii razlichnie funkzii??? Ili w Linuxe swoj uluch'shennij wariant? No po logike weshej eto bilo bi nekorrektno. Hotja inogda ih logika srodni genskoj logike char * asctime (const struct tm *BROKENTIME);
char * asctime_r (const struct tm *BROKENTIME, char *BUFFER);
char * ctime (const time_t *TIME);
char * ctime_r (const time_t *TIME, char *BUFFER);
size_t strftime (char *S, size_t SIZE, const char *TEMPLATE, const struct tm *BROKENTIME); /* это похоже на sprintf() */
size_t wcsftime (wchar_t *S, size_t SIZE, const wchar_t *TEMPLATE, const struct tm *BROKENTIME);
/* Разбор строки: */ char * strptime (const char *S, const char *FMT, struct tm *TP); /* похоже на sscanf() */
struct tm * getdate (const char *STRING);
int getdate_r (const char *STRING, struct tm *TP);
|
|
« Последнее редактирование: 24-11-2007 14:17 от Алексей1153++ »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #11 : 16-03-2004 10:17 » |
|
Malaja, дело, imho, так: в Linux-е реализовано несколько стандартов (в основном POSIX, ISO b GNU), а заголовки MSVC++ базируются на сравнительно старых ISO стандартах и собственных расширениях MS. Им,видимо, не хочется равняться на стандарты, а самим быть стандартом.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Malaja
|
|
« Ответ #12 : 16-03-2004 11:04 » |
|
RXL, spasibo za otwet. Delo w tom, chto ja rabotaju s Microsoft - wersiej c++, linux ne znaju w prinzipe (nu tak slogilos ) A poslednee wremja mne nado pisat programmi, kotorie rabotali bi na obeih paltformah. Wot i nachalos weselje - ispolzowat tolko standartnie c/c++ wozmognosti, plus tam, gde ne poluchaetsja, nado imet 2 warianta koda (ne dalee, kak wchera razwleklas s sinhronisaziej prozessow pri dostupe k fajlu ) Da, i eshe paru slow o wishepriwedennih funkzijah dlja preobrazowanija time w char: ja posmotrela, oni wse widajut rezultat w formate : den_nedeli mesjaz chislo wremja god A eto wesma neudobno, esli nugna tolko data w formate "den.mesjaz.god", posemu wse rawno nado preobrazowiwat samomu. Primer : (zdes ja preobrazuju tekushuju datu, no s tem ge uspehom mogno ispolzowat rezultati kakih-to funkzij, wozwrashajushih time_t) void getCurDate(char* buf) { try { // get Now time_t pTmpDT = NULL; tm* pTmpDTTm = NULL; time(&pTmpDT); pTmpDTTm = localtime(&pTmpDT); // convert to char convertDateToStr(buf, pTmpDTTm); return; } catch(...) { printf("Internes Fehler"); return; } }
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #13 : 16-03-2004 12:24 » |
|
Malaja, если надо делать вывод по своему, я перевожу в struct tm и вывожу через printf() и аналогичные. struct tm t*;
t=localtime(time(0)); printf("%d.%02d.%d",tm->tm_mday,tm->tm_mon+1,tm->tm_year+1900);
Проблему совместимости API обычно решают написав несовместимые участки кода индивидуально для каждого случая и разделив их директивами условной компиляции. #ifdef WIN32 // код для Win32 #else // код для Linux #endif
|
|
« Последнее редактирование: 24-11-2007 14:19 от Алексей1153++ »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Malaja
|
|
« Ответ #14 : 16-03-2004 13:01 » |
|
RXL, wse prawilno, ja prosto hotela skazat, chto eti funkzii ne wsegda spasajut - wse zawisit ot togo, chto dolgno bit na wihode, posemu inogda nado wse rawno ispolzowat eshe i promegutochnuju strukturu.
S direktiwami kak raz ne tak slogno, problema zakljuchaetsja w razlichnih nazwanijah funkzij dlja win i linux. Naprimer, po powodudu sinhronizazii prozessow wijasnilos, chto pod win mutex prekrasno spasaet, a pod linuxom - net, tam nugno ispolzowat semafor. Wtoroj milij primer - poluchenie dati poslednego obnowlenija fajla. Problema woznikaet togda, kogda rech idet ob API - funkzijah.
|
|
|
Записан
|
холоднокровней, Маня, Ви не на работе --------------------------------------- четкое определение сущности бытия: - А мы в прошлом или в будущем?- спросила Алиса. - Мы в жопе, - ответил кролик. - А "жопа" - это настоящее? - спросила Алиса. - А "жопа" - это у нас символ вечности.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #15 : 16-03-2004 13:49 » |
|
Короче, тяжкий труд.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|