Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: time_t  (Прочитано 18515 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« : 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_
Помогающий

ua
Offline 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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 01-03-2004 21:05 » 

Malaja, а не проше ли сделать разницу между двумя time_t, чем struct tm ? А потом просто разделить на 86400 (секунд в сутках).
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sashok
Молодой специалист

us
Offline 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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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
Молодой специалист

us
Offline Offline
Пол: Мужской

« Ответ #6 : 14-03-2004 15:27 » 

RXL, если не ошибаюсь, в POSIX входит еще и localtime(...)
Записан

Если бы окружающие нас объекты содержали столько же ошибок, сколько программы, цивилизация обрушилась бы от первого порыва ветра...
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 14-03-2004 19:04 » 

Sashok, угу: struct tm * localtime(const time_t *TIME);
Но какое это имеет отношение к переводу время<->строка? Или ты о другом?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sashok
Молодой специалист

us
Offline Offline
Пол: Мужской

« Ответ #8 : 15-03-2004 02:13 » 

RXL, имеет, хотя и не непосредственное. В общем, я бы сказал, что и gmtime() и localtime(), по-разному преобразовывая time_t в struct tm, в конечном итоге используются на пути вермя -> текст.
Записан

Если бы окружающие нас объекты содержали столько же ошибок, сколько программы, цивилизация обрушилась бы от первого порыва ветра...
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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 » 

Цитата: RXL
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  Ага

Цитата: RXL
Код:
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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 16-03-2004 10:17 » 

Malaja, дело, imho, так: в Linux-е реализовано несколько стандартов (в основном POSIX, ISO b GNU), а заголовки MSVC++ базируются на сравнительно старых ISO стандартах и собственных расширениях MS. Им,видимо, не хочется равняться на стандарты, а самим быть стандартом.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #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
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #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
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 16-03-2004 13:49 » 

Короче, тяжкий труд.  Здесь была моя ладья...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines