Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Работа с датой


Автор: kulikoff 12.5.2006, 09:16
Есть такая ситуация, мне надо, чтоб прога делала из БД выборку записей в пределах текущего месяца. Номер месяца я определяю из функции DecodeDate, а как мне написать, чтоб прога знала, что в мае 31 день, а в июне - 30? Ну и чтоб отслеживала высокосный и нет года?
Совсем что-то понять не могу... 

Автор: comtat 12.5.2006, 09:22
написано на C++

но конверитация займет минут 5

Код

// функция определения високосного года 
inline 
bool is_leap_year(const int year) 
{ 
   return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0); 
} 

// сделано на основе MATLAB: datenummx.c 
double DateToNum(int year, int month, int day, int hour, int minute, int second) 
{ 
   // count day in month 
   static cdm[] = {0,31,59,90,120,151,181,212,243,273,304,334}; 

    if (month < 1) 
        month = 1; 
   else if (month > 12) 
   { 
        year += (month-1)/12; 
        month = ((month-1) % 12) + 1; 
    } 

   // convert [y, mo, d] -> num 
   const double d_year = year; 
   double num = 365 * year + ceil(d_year / 4) - ceil(d_year / 100) + 
               ceil(d_year / 400) + cdm[month - 1] + day; 

   if (month > 2 && is_leap_year(year)) 
      ++num; 

   // add to num: [h, mi, s] -> num 
   num += double(hour * 3600 + minute * 60 + second) / 86400; 

   return num; 
} 

// сделано на основе datevecmx.c 
void NumToDate(double num, // in 
          int& year, int& month, int& day, int& hour, int& minute, int& second) // out 
{ 
   // дни по месяцам: 
   // для не високосного года 
   static const int cdm0[] = {0,31,59,90,120,151,181,212,243,273,304,334,365}; 
   // для високосного года 
   static const int cdm1[] = {0,31,60,91,121,152,182,213,244,274,305,335,366}; 

   // break apart: [year, month, day] and [hour, minute, second] 
   const double p1 = floor(num); 
   const double p2 = num - p1; 

   // take first part 
   num = p1; 

   year = floor(num / 365.2425); 

   double ts = num - (year * 365 + ceil(year * 0.25) - ceil(year * 0.01) + ceil(year * 0.0025)); 
   if (!(ts > 0)) // ts <= 0 
   { 
      --year; 
      num -= (year * 365 + ceil(year * 0.25) - ceil(year * 0.01) + ceil(year * 0.0025)); 
   } 
   else 
      num = ts; 

   const int* cdm = is_leap_year(year)? cdm1: cdm0; 

   month = (int)num / 29 - 1; 

   if (num > cdm[month + 1]) 
      ++month; 

   num -= cdm[month]; 
   ++month; 

   day = floor(num); 

   // take second part 
   num = CDouble::Round(p2 * 86400); // translate to seconds 

   ts = num; 
   num = floor(num / 60.0); 
   second = ts - num * 60.0; // seconds 

   ts = num; 
   num = floor(num / 60); 
   minute = ts - num * 60; // minutes 

   ts = num; 
   num = floor(num / 24); 
   hour = ts - num * 24; // hours 
}
 

Автор: Snowy 12.5.2006, 10:03
В DateUtils полно функций по работе с датами.
Тебе нужны:
DaysInAMonth - дней в месяце (на входе месяц и год)
DaysInYear - дней в году (на входе год)
IsLeapYear - говорит високосный год или нет (на входе год)
DayOfTheMonth - возвращает день из TDateTime
и т.д.
 

Автор: Демо 12.5.2006, 10:05
kulikoff, 

Простейший метод - использовать DaysInAMonth, либо см. реализацию этих функций в модуле DateUtils.pas 

Автор: kulikoff 12.5.2006, 10:49
спасибо, всё сделал 

Автор: Dynamic 12.5.2006, 13:14
Цитата(kulikoff @  12.5.2006,  09:16 Найти цитируемый пост)
мне надо, чтоб прога делала из БД выборку записей в пределах текущего месяца

а что за БД? может запросом?
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)