к текущему мес. прибавлялось число

Тема в разделе "WASM.BEGINNERS", создана пользователем zxcc, 9 фев 2007.

  1. zxcc

    zxcc New Member

    Публикаций:
    0
    Регистрация:
    21 окт 2006
    Сообщения:
    172
    При получении даты нужно чтобы к текущему мес. прибавлялось число.К примеру к Month прибавить число "3".
    .data
    DatYear db "%02d",0
    DatMonth db "%02d",0
    DatDay db "%02d",0

    invoke GetLocalTime ,ADDR DATA
    MOVZX EAX,DATA.wYear
    invoke wsprintfA,ADDR Year,ADDR DatYear,eax
    PUSH EAX
    MOVZX EAX,DATA.wMonth

    invoke wsprintfA,ADDR Month,ADDR DatMonth,eax

    PUSH EAX
    MOVZX EAX,DATA.wDay
    invoke wsprintfA,ADDR Day,ADDR DatDay,eax
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Код (Text):
    1. mov ax, Data.wMonth
    2. inc ax
    3. mov Data.wMonth, ax
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    n0name
    Круто ;) А как называется 13-й месяц года ? ;)))
     
  4. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    SystemTimeToFileTime, FileTimeToSystemTime?
    если руками, то хз где найти алгоритм, не самому же писать
     
  5. CodeTao

    CodeTao Евгений

    Публикаций:
    0
    Регистрация:
    31 окт 2006
    Сообщения:
    177
    Адрес:
    штаты
    Иногда приходиться...( А на счет SystemTimeToFileTime- FileTimeToSystemTime, при увеличения на несколько месяцов текущей даты какое число дней будешь умножать на число месяцев, 30-31-28? А если тупо добавлять к числу месяцев, без преобразования даты к сотням нс и без учета дней, то можно получить 31 день в феврале...(кто пытался скормить такую дату в базу данных смеяться не будет...) Проблема с этим алгоритмом дествительно неприятная, красивой реализации скорее всего нет...( У кого-нибудь есть какие-либо идеи?
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    ?! В общем случае да, а конкретно для прибавки месяцев достаточно проверки результата на > 12 с коррекцией месяца и года.
    ... Хотя в общем случае это верно только для дат <= 28, а для вариаций 31-30-28 вроде как сама задача прибавления месяцев получается бессмысленно-неоднозначной
     
  7. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Такой пример есть, только на дельфях и не знаю, работает ли :)
    Код (Text):
    1. function DateSer(y,m,d: Integer): TDateTime;
    2. const
    3.     mj: array[1..12] of Integer=(31,28,31,30,31,30,31,31,30,31,30,31);
    4. var
    5.     add: Integer;
    6. begin
    7.     while(true) do begin
    8.         y:=y+(m-1) div 12;
    9.         m:= (m-1) mod 12 +1;
    10.         if m<=0 then begin
    11.             Inc(m,12);
    12.             Dec(y);
    13.         end;
    14.         if  ((y mod 4 = 0) and ((y mod 100<>0) or (y mod 400=0))) and (m=2) then
    15.             add:=1 //дополнительный день в феврале
    16.         else
    17.             add:=0;
    18.         if (d>0) and (d<=(mj[m]+add)) then break;
    19.         if d>0 then
    20.         begin
    21.             Dec(d,mj[m]+add);
    22.             Inc(m);
    23.         end
    24.         else
    25.         begin
    26.             Inc(d,mj[m]+add);
    27.             Dec(m);
    28.         end;
    29.     end;
    30.     Result:=EncodeDate(y,m,d);
    31. end;
    Используется как:
    Код (Text):
    1. DecodeDate(Date,y,m,d);
    2. NewDate:=DateSer(y-4,m+254,d+1234);
     
  8. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    вообще-то..
    правда, а что требуется?
    прибавить опредленное число дней (ex. 2 месяца~60 дней), или именно месяцев без учета числа дней в каждом?
    если второе, то в чем вопрос?
     
  9. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    В постановке задачи не было такого, чтобы прибавлять корректно :P Просто прибавить число =)
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Nouzui
    В том, что речь идет не просто о месяце, а о дате, т.е. год-месяц-число. Если текущая дата <= 28, то вопросов нет, т.к. она существует в любом месяце любого года. А вот если к 29 января или к 31 мая добавить 1 месяц, то получится ерунда, т.к. 29 февраля существует только в високосном году, а 31 июня - только в известном фильме ;)) Об этом собс-но уже сказал CodeTao
     
  11. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    торможу, бывает..
    впрчем, нужно просто разобраться, что именно требуется, ведь общепринятого стандарта на то как "увеличить число месяцев" не существует
     
  12. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    leo
    Не совсем, существуют также различные отклонения вроде банковского месяца и суток, когда в месяце 30 дней и сутки длятся с 00:00 по 24:00 включительно. Но здесь вряд ли речь об этом :)
     
  13. CodeTao

    CodeTao Евгений

    Публикаций:
    0
    Регистрация:
    31 окт 2006
    Сообщения:
    177
    Адрес:
    штаты
    В этом случае и год равен 360 дням, интересно как они переводят астрономическую дату в банковскую...
    Я смотрю не у кого нет готовой реализации subj(алгоритм rmn должен работать, но delphi!, слишком общий случай и никакой оптимизации), посему выкладываю на суд присяжных следующий алгоритм, в нем сохраняется позиция дня от конца месяца(при небольшой модификации можно получить наоборот)
    Код (Text):
    1. const int DayInMonth[2][13]={{31,31,28,31,30,31,30,31,31,30,31,30,31},{31,31,29,31,30,31,30,31,31,30,31,30,31}};
    2. int main(...)
    3. {
    4.     int iDay,iMonth,iYear,iNumberOfMonth,iLeapYear,iDayInOldMonth;
    5.     printf("Current date(mm/dd/year):");
    6.     scanf("%d%*[/]%d%*[/]%d",&iMonth,&iDay,&iYear);
    7.     printf("Enter how many month to add to current date:");
    8.     scanf("%d",&iNumberOfMonth);
    9.     if(iYear%4) iLeapYear=0;//не высокосный год - при равномерном распределении он будет выподать чаще, а поэтому желательно что бы при этом было как можно меньше сравнений
    10.     else if(!(iYear%100))  iLeapYear=1;//высокосный год, делится на 4 без остатка, но не делится на 100
    11.     else if(iYear%400) iLeapYear=1;//высокосный год, делится на 400 без остатка
    12.     else iLeapYear=0; //не высокосный год, который делится на 100
    13.     iDayInOldMonth=DayInMonth[iLeapYear][iMonth];
    14.     if(iNumberOfMonth) iMonth+=(iNumberOfMonth-1);
    15.     iYear+=iMonth/12;
    16.     iMonth=iMonth%12+1;
    17.     if(iYear%4) iLeapYear=0;
    18.     else if(!(iYear%100))  iLeapYear=1;
    19.     else if(iYear%400) iLeapYear=1;
    20.     else iLeapYear=0;
    21.     iDay=iDay+DayInMonth[iLeapYear][iMonth]-iDayInOldMonth;
    22.     if(iDay<1) iDay=1;
    23.     printf("Result date(mm/dd/yyyy):%d/%d/%d",iMonth,iDay,iYear);
    24.     return 0;
    25. }
    А теперь вопрос, если усложнить задачу, добавив прибавление еще дней и часов(минут, секунд...) то как себя должен вести себя алгоритм в октябре и в марте если добавляемый интервал включает переход с летнего времени на зимнее и обратно? И отражает ли следующий нюанс SystemTimeToFileTime- FileTimeToSystemTime?
     
  14. CodeTao

    CodeTao Евгений

    Публикаций:
    0
    Регистрация:
    31 окт 2006
    Сообщения:
    177
    Адрес:
    штаты
    Ссори, алгоритм rmn будет все же выдовать ошибку :
    NewDate:=DateSer(2000,1+1,31) выдаст уже не февраль а март.
     
  15. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    CodeTao
    это не мой алгоритм, я взял его в примерах по delphi. И на счет его работоспособности я тоже сказал, что не проверял.

    так, в принципе, и должен март выдать. Там же учитывается не только месяц, но и день. Эти 2 (3) дня как раз и добавляют еще один месяц.
     
  16. CodeTao

    CodeTao Евгений

    Публикаций:
    0
    Регистрация:
    31 окт 2006
    Сообщения:
    177
    Адрес:
    штаты
    rmnЯ не знал как назвать алгоритм, а поэтому слинковал с твоим именем(без обид, если что извини) На счет "так, в принципе, и должен март выдать." как раз нет, представь твою зарплату задержат в критический момент на 3 дня - согласись, не очень приятно.
     
  17. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    с ума с вами сойдешь
    надо сначало определиться, как должно быть, а потом просто написать! например, если нужно, чтобы месяц не перескакивал:
    Код (Text):
    1. void AddMonth(LPSYSTEMTIME IN OUT lpTime, int IN nMonth)
    2. {
    3.   int nMaxDay;
    4.   lpTime->wMonth+= nMonth;
    5.   lpTime->wYear+= (lpTime->wMonth-1)/12;
    6.   lpTime->wMonth= (lpTime->wMonth-1)%12 + 1;
    7.   switch(lpTime->wMonth)
    8.   {
    9.     case 1, 3, 5, 7, 8, 10, 12:
    10.       nMaxDay= 31;
    11.       break;
    12.     case 4, 6, 9, 11:
    13.       nMaxDay= 30;
    14.       break;
    15.     case 2:
    16.       nMaxDay= (lpTime->wYear%4 || (lpTime->wYear%100 && !(lpTime->wYear%400)))?28:29;
    17.       break;
    18.   }
    19.   if(lpTime->wDay>nMaxDay)
    20.     lpTime= wDay>nMaxDay;
    21. }
    че то вроде того
     
  18. GaryMiller

    GaryMiller New Member

    Публикаций:
    0
    Регистрация:
    2 окт 2007
    Сообщения:
    4
    Есть еще фунция DataAdd.
    http://office.microsoft.com/ru-ru/access/HA012288101049.aspx?pid=CH100728911049

    DateAdd PROTO pszInterval:PTR BYTE, plNumber:PTR SDWORD, pdt1:PTR FILETIME, pdt2:PTR FILETIME

    Пример:

    Код (Text):
    1. include \masm32\include\DateTime.inc
    2. includelib \masm32\lib\DateTime.lib
    3.  
    4. .data
    5. d dw ?
    6. delta dd ?
    7. ft1 FILETIME<>
    8. ft2 FILETIME<>
    9. .code
    10. fn DateAdd,addr d,addr delta,addr ft1,addr ft2
    где:
    d - символ, чего будем менять. Доступны такие: "s" - секунды, "m" - минуты, "h" - часы, "d" - дни
    delta - вобщем, сколько хотим добавить или, если отрицательное число, отнять.
    ft1 - передаем дату в формате FILETIME
    ft2 - сюда получаем дату в формате FILETIME
     
  19. xchg

    xchg New Member

    Публикаций:
    0
    Регистрация:
    10 апр 2006
    Сообщения:
    34
    Адрес:
    Russia
    http://mc-black.narod.ru/dzp.htm
    Здесь есть пример календаря. там в одной процедуре рассчитывается разница между двумя датами. немного переделать (вместо вычитания сложение).
     
  20. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    ну это уже совсем
    Код (Text):
    1. mov ax, SysTime.dwMonth
    2. add ax, 3
    3. mov cl, 12
    4. div cl
    5. movzx eax, al
    все. выводим число из eax. будет на 3 мес больше.