Julian Day Number

Тема в разделе "WASM.A&O", создана пользователем Intro, 7 окт 2023.

  1. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    Ещё одна версия для вычисления номера юлианской даты. В этой версии можно вычислять разность дат. Например
    Код (Text):
    1. JD 24.02.2022 7.10.2023
    Должно получится 590, это время прошедших полных суток.
    Аверы? Агрятся только четыре, думают что там троян, очень тупые аверы!!!
    Непосредственно код.
    Код (ASM):
    1.  
    2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    3. ;;  Julian Day Number       v0.04
    4. ;;  (c) NanoBot
    5. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    6. .386
    7. .model flat, stdcall
    8. option casemap:none
    9. include msvcrt.inc
    10. include macros.asm
    11. SDate struct
    12.     day             dword ? ;1..31
    13.     mon             dword ? ;1..12
    14.     year            dword ?
    15. SDate ends
    16. .const
    17. LengthMON       sdword 31,28,31,30,31,30,31,31,30,31,30,31
    18. .code
    19. int_div MACRO a:req, b:req
    20. IFDIFI <a>, <eax>
    21.     mov     eax, a
    22. ENDIF
    23.     mov     ecx, b
    24.     cdq
    25.     idiv    ecx
    26. ENDM
    27. int_div$ MACRO a:req, b:req
    28.     int_div a, b
    29.     EXITM   <eax>
    30. ENDM
    31. align_proc
    32. GetJDN proc (dword) uses esi edi ebx date:ptr SDate
    33.     mov     edx, date
    34.     ASSUME  edx:ptr SDate
    35.     mov     esi, [edx].day  ;JDN
    36.     mov     ebx, [edx].mon  ;mon    //1..12
    37.     mov     edi, [edx].year ;year
    38.     ASSUME  edx:nothing
    39.     ;/* Новый год 1 марта! */
    40.     sub     ebx, 2+1
    41.     sbb     eax, eax    ;k = mon=-2+1<0 ? -1 : 0;
    42.     ;year += 4800+k;
    43.     lea     edi, [edi+eax+4800]
    44.     ;mon += k & 12;
    45.     and     eax, 12
    46.     add     ebx, eax
    47.     ;JDN += mon*30+(mon%5+1)/2+mon/5*3;
    48.     imul    eax, ebx, 30
    49.     add     esi, eax
    50.     int_div ebx, 5
    51.     lea     eax, [eax*2+eax]    ;*=3
    52.     add     esi, eax
    53.     lea     eax, [edx+1]
    54.     cdq
    55.     sub     eax, edx
    56.     sar     eax, 1;/=2
    57.     add     esi, eax
    58.     ;JDN += year*365+year/4+year/400-year/100-32045;
    59.     imul    eax, edi, 365
    60.     add     esi, eax
    61.     add     esi, int_div$(edi, 4)
    62.     add     esi, int_div$(edi, 400)
    63.     sub     esi, int_div$(edi, 100)
    64.     lea     eax, [esi-32045]
    65.     ret
    66. GetJDN endp
    67. ;GetMJD("17.11.1858")
    68. align_proc
    69. GetDDpMMpYYYY proc (byte) uses esi edi ebx strDate:ptr byte, date:ptr SDate
    70. local strEnd:ptr byte, leap:sdword
    71.     ;day:esi, mon:edi, year:ebx
    72.     ASSUME  ecx:ptr byte, edx:ptr SDate
    73.     mov     esi, strtol(strDate, &strEnd, 10)
    74.     mov     ecx, strEnd
    75.     .if ([ecx]=='.')
    76.         inc     ecx
    77.         mov     edi, strtol(ecx, &strEnd, 10)
    78.         mov     ecx, strEnd
    79.         .if ([ecx]=='.')
    80.             inc     ecx
    81.             mov     ebx, strtol(ecx, &strEnd, 10)
    82.             mov     ecx, strEnd
    83.             .if ([ecx]==0)
    84.                 dec     edi
    85.                 .if (edi<12)
    86.                     and     leap, 0
    87.                     .if (edi==2-1)
    88.                         int_div ebx, 4
    89.                         .if (edx==0)
    90.                             int_div ebx, 400
    91.                             .if (edx!=0)
    92.                                 inc     leap
    93.                             .endif
    94.                         .endif
    95.                     .endif
    96.                     mov     ecx, LengthMON[edi*4]
    97.                     add     ecx, leap
    98.                     .if (sdword ptr esi>=1 && sdword ptr esi<=ecx)
    99.                         mov     edx, date
    100.                         inc     edi
    101.                         mov     [edx].day, esi
    102.                         mov     [edx].mon, edi
    103.                         mov     [edx].year, ebx
    104.                         mov     al, true
    105.                         jmp     EXIT
    106.                     .endif
    107.                 .endif
    108.             .endif
    109.         .endif
    110.     .endif
    111.     ASSUME  ecx:nothing, edx:nothing
    112.     printf("Date format error: '%s'\n", strDate)    ;Ошибка формата даты
    113.     mov     al, false
    114. EXIT:
    115.     ret
    116. GetDDpMMpYYYY endp
    117. align_proc
    118. main proc C argc:sdword, argv:ptr ptr, envp:ptr ptr
    119. local date1:SDate, date2:SDate
    120.     .repeat
    121.         .if (argc<2)
    122.             printf("Usage: JD DD.MM.YYYY [DD.MM.YYYY]\n")
    123.         .else
    124.             mov     esi, argv
    125.             .if (argc==2)
    126.                 .break .if (GetDDpMMpYYYY([esi+1*4], &date1)==false)
    127.                 GetJDN(&date1)
    128.                 printf("%d.%02d.%d, JD = %ld\n", date1.day, date1.mon, date1.year, eax)
    129.             .else
    130.                 .break .if (GetDDpMMpYYYY([esi+2*4], &date2)==false)
    131.                 mov     ebx, GetJDN(&date2)
    132.                 .break .if (GetDDpMMpYYYY([esi+1*4], &date1)==false)
    133.                 sub     ebx, GetJDN(&date1)
    134.                 printf("%d.%02d.%d - %d.%02d.%d = %ld\n", date1.day, date1.mon, date1.year, date2.day, date2.mon, date2.year, ebx)
    135.             .endif
    136.         .endif
    137.     .until true
    138.     xor     eax, eax
    139.     ret
    140. main endp
    141. main_startup3_END
    142.  
    ЗЫ
    5 аверов агрятся!!!

    Версия на С/С++.
    Код (C++):
    1. ////////////////////////////////////////////////////////////////////
    2. //  Julian Day Number       v0.051
    3. //  (c) NanoBot
    4. ////////////////////////////////////////////////////////////////////
    5. #include <stdio.h>
    6. #include <stdlib.h>
    7. struct SDate
    8. {
    9.     int day;    //1..31
    10.     int mon;    //1..12
    11.     int year;
    12. };
    13. const int   LengthMON[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    14. long    GetJDN(SDate *date)
    15. {
    16.     long JDN = date->day;
    17.     int mon = date->mon-1;  //1..12
    18.     int year = date->year;
    19.     mon-=2; /* Новый год 1 марта! */
    20.     int k = mon<0 ? -1 : 0;
    21.     year += 4800+k;
    22.     mon += k & 12;
    23.     JDN += mon*30+(mon%5+1)/2+mon/5*3;
    24.     JDN += year*365+year/4+year/400-year/100-32045;
    25.     return JDN;
    26. }
    27. void    GetDate(long JDN, SDate *date)
    28. {
    29.     int     j400,j100,j4,j1,year,mon;
    30.     int     m5,m2,m1;
    31.     const int   days400year = 400*365+97;
    32.     const int   days100year = 100*365+24;
    33.     const int   days4year   = 4*365+1;
    34.     const int   days1year   = 1*365;
    35.     const int   days5mon    = 5*30+3;
    36.     const int   days2mon    = 2*30+1;
    37.     const int   days1mon    = 1*30+1;
    38.     long    day = JDN+32045-1;
    39.     j400 = day/days400year; day %= days400year;
    40.     j100 = day/days100year; day %= days100year;
    41.     j4   = day/days4year;   day %= days4year;
    42.     j1   = day/days1year;   day %= days1year;
    43.     if (j1==4){//високосный день
    44.         j1--;
    45.         day = 365;
    46.     }
    47.     year = j400*400+j100*100+j4*4+j1-4800;
    48.     m5 = day/days5mon; day %= days5mon;
    49.     m2 = day/days2mon; day %= days2mon;
    50.     m1 = day/days1mon; day %= days1mon;
    51.     mon = m5*5+m2*2+m1+3;
    52.     if (mon > 12){
    53.         mon -= 12;
    54.         year++;
    55.     }
    56.     date->day = day + 1;
    57.     date->mon = mon;
    58.     date->year = year;
    59. }
    60. bool    GetDDpMMpYYYY(const char *strDate, SDate *date)
    61. {
    62.     char    *strEnd;
    63.     int day = strtol(strDate, &strEnd, 10);
    64.     if (strEnd[0]=='.'){
    65.         int mon = strtol(strEnd+1, &strEnd, 10);
    66.         if (strEnd[0]=='.'){
    67.             int year = strtol(strEnd+1, &strEnd, 10);
    68.             if (strEnd[0]==0){
    69.                 if (mon>=1 && mon<=12){
    70.                     int lenMon = LengthMON[mon-1];
    71.                     if (mon==2 && year%4==0 && year%100!=0 || year%400==0)
    72.                         lenMon++;
    73.                     if (day>=1 && day<=lenMon){
    74.                         date->day = day;
    75.                         date->mon = mon;
    76.                         date->year = year;
    77.                         return true;
    78.                     }
    79.                 }
    80.             }
    81.         }
    82.     }
    83.     printf("Date format error: '%s'\n", strDate);   //Ошибка формата даты
    84.     return false;
    85. }
    86. int main(int argc, const char *argv[])
    87. {
    88.     SDate   date1, date2;
    89.     char    *strEnd;
    90.     if (argc<2)
    91.         printf("Usage: JD DD.MM.YYYY [DD.MM.YYYY]\n");
    92.     else {
    93.         long    JDN;
    94.         if (argc==2){
    95.             JDN = strtol(argv[1], &strEnd, 10);
    96.             if (strEnd[0]==0){
    97.                 GetDate(JDN, &date1);
    98.                 printf("%ld = %d.%02d.%d\n", JDN, date1.day, date1.mon, date1.year);
    99.             } else {
    100.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    101.                 JDN = GetJDN(&date1);
    102.                 printf("%d.%02d.%d = %ld\n", date1.day, date1.mon, date1.year, JDN);
    103.             }
    104.         } else {
    105.             JDN = strtol(argv[2], &strEnd, 10);
    106.             if (strEnd[0]==0){
    107.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    108.                 JDN += GetJDN(&date1);
    109.                 GetDate(JDN, &date2);
    110.                 printf("%d.%02d.%d + %s = %d.%02d.%d\n", date1.day, date1.mon, date1.year, argv[2], date2.day, date2.mon, date2.year);
    111.             } else {
    112.                 if (GetDDpMMpYYYY(argv[2], &date2)==false) return 0;
    113.                 JDN = GetJDN(&date2);
    114.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    115.                 JDN = JDN - GetJDN(&date1);
    116.                 printf("%d.%02d.%d - %d.%02d.%d = %ld\n", date1.day, date1.mon, date1.year, date2.day, date2.mon, date2.year, JDN);
    117.             }
    118.         }
    119.     }
    120.     return 0;
    121. }
     

    Вложения:

    • JD(v0.04).rar
      Размер файла:
      2,6 КБ
      Просмотров:
      171
    Последнее редактирование: 15 окт 2023
    mantissa нравится это.
  2. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    110
  3. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    110
  4. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.186
    Адрес:
    подполье
  5. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    Исправил ошибку определения високосного года в GetDDpMMpYYYY
    Добавил возможность номер дня переводить в дату. Из даты вычитать/прибавлять количество дней. В общем, новые возможности можно посмотреть в батнике тест.
    И программа на С/С++, на чистом С должна откомпилироваться, на новых редакциях точно.
    Код (C++):
    1. ////////////////////////////////////////////////////////////////////
    2. //  Julian Day Number       v0.05
    3. //  (c) NanoBot
    4. ////////////////////////////////////////////////////////////////////
    5. #include <stdio.h>
    6. #include <stdlib.h>
    7. struct SData
    8. {
    9.     int day;    //1..31
    10.     int mon;    //1..12
    11.     int year;
    12. };
    13. const int   LengthMON[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    14. int     GetJDN(SData *date)
    15. {
    16.     int JDN = date->day;
    17.     int mon = date->mon-1;  //1..12
    18.     int year = date->year;
    19.     mon-=2; /* Новый год 1 марта! */
    20.     int k = mon<0 ? -1 : 0;
    21.     year += 4800+k;
    22.     mon += k & 12;
    23.     JDN += mon*30+(mon%5+1)/2+mon/5*3;
    24.     JDN += year*365+year/4+year/400-year/100-32045;
    25.     return JDN;
    26. }
    27. void    GetData(int JDN, SData *data)
    28. {
    29.     int     j400,j100,j4,j1,year,mon,day;
    30.     int     m5,m2,m1;
    31.     const int   days400year = 400*365+97;
    32.     const int   days100year = 100*365+24;
    33.     const int   days4year   = 4*365+1;
    34.     const int   days1year   = 1*365;
    35.     const int   days5mon    = 5*30+3;
    36.     const int   days2mon    = 2*30+1;
    37.     const int   days1mon    = 1*30+1;
    38.     day = JDN+32045-1;
    39.     j400 = day/days400year; day %= days400year;
    40.     j100 = day/days100year; day %= days100year;
    41.     j4   = day/days4year;   day %= days4year;
    42.     j1   = day/days1year;   day %= days1year;
    43.     if (j1==4){//високосный день
    44.         j1--;
    45.         day = 365;
    46.     }
    47.     year = j400*400+j100*100+j4*4+j1-4800;
    48.     m5 = day/days5mon; day %= days5mon;
    49.     m2 = day/days2mon; day %= days2mon;
    50.     m1 = day/days1mon; day %= days1mon;
    51.     mon = m5*5+m2*2+m1+3;
    52.     if (mon > 12){
    53.         mon -= 12;
    54.         year++;
    55.     }
    56.     data->day = day + 1;
    57.     data->mon = mon;
    58.     data->year = year;
    59. }
    60. bool    GetDDpMMpYYYY(const char *strDate, SData *date)
    61. {
    62.     char    *strEnd;
    63.     int day = strtol(strDate, &strEnd, 10);
    64.     if (strEnd[0]=='.'){
    65.         int mon = strtol(strEnd+1, &strEnd, 10);
    66.         if (strEnd[0]=='.'){
    67.             int year = strtol(strEnd+1, &strEnd, 10);
    68.             if (strEnd[0]==0){
    69.                 if (mon>=1 && mon<=12){
    70.                     int lenMon = LengthMON[mon-1];
    71.                     if (mon==2 && year%4==0 && year%100!=0 || year%400==0)
    72.                         lenMon++;
    73.                     if (day>=1 && day<=lenMon){
    74.                         date->day = day;
    75.                         date->mon = mon;
    76.                         date->year = year;
    77.                         return true;
    78.                     }
    79.                 }
    80.             }
    81.         }
    82.     }
    83.     printf("Date format error: '%s'\n", strDate);   //Ошибка формата даты
    84.     return false;
    85. }
    86. int main(int argc, const char *argv[])
    87. {
    88.     SData   date1, date2;
    89.     char    *strEnd;
    90.     if (argc<2)
    91.         printf("Usage: JD DD.MM.YYYY [DD.MM.YYYY]\n");
    92.     else {
    93.         int JDN;
    94.         if (argc==2){
    95.             JDN = strtol(argv[1], &strEnd, 10);
    96.             if (strEnd[0]==0){
    97.                 GetData(JDN, &date1);
    98.                 printf("%ld = %d.%02d.%d\n", JDN, date1.day, date1.mon, date1.year);
    99.             } else {
    100.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    101.                 JDN = GetJDN(&date1);
    102.                 printf("%d.%02d.%d = %ld\n", date1.day, date1.mon, date1.year, JDN);
    103.             }
    104.         } else {
    105.             JDN = strtol(argv[2], &strEnd, 10);
    106.             if (strEnd[0]==0){
    107.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    108.                 JDN += GetJDN(&date1);
    109.                 GetData(JDN, &date2);
    110.                 printf("%d.%02d.%d + %s = %d.%02d.%d\n", date1.day, date1.mon, date1.year, argv[2], date2.day, date2.mon, date2.year);
    111.             } else {
    112.                 if (GetDDpMMpYYYY(argv[2], &date2)==false) return 0;
    113.                 JDN = GetJDN(&date2);
    114.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    115.                 JDN = JDN - GetJDN(&date1);
    116.                 printf("%d.%02d.%d - %d.%02d.%d = %ld\n", date1.day, date1.mon, date1.year, date2.day, date2.mon, date2.year, JDN);
    117.             }
    118.         }
    119.     }
    120.     return 0;
    121. }
     

    Вложения:

    • JD(v0.05).rar
      Размер файла:
      3,3 КБ
      Просмотров:
      129
    Application нравится это.
  6. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    15 окт 2022
    Сообщения:
    110
    Взлетает если использовать стиль тигра:

     
  7. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    Некоторые типы не совсем правильно определил, для локальных JDN и day в GetData надо long. Иначе если у вас всё ещё АТ/286 и турбоСи 3, программка может и не работать. В прочим, сейчас int сто пудово 32-битный тип.
    --- Сообщение объединено, 15 окт 2023 ---
    Код (C++):
    1. ////////////////////////////////////////////////////////////////////
    2. //  Julian Day Number       v0.051
    3. //  (c) NanoBot
    4. ////////////////////////////////////////////////////////////////////
    5. #include <stdio.h>
    6. #include <stdlib.h>
    7. struct SData
    8. {
    9.     int day;    //1..31
    10.     int mon;    //1..12
    11.     int year;
    12. };
    13. const int   LengthMON[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    14. long    GetJDN(SData *data)
    15. {
    16.     long JDN = data->day;
    17.     int mon = data->mon-1;  //1..12
    18.     int year = data->year;
    19.     mon-=2; /* Новый год 1 марта! */
    20.     int k = mon<0 ? -1 : 0;
    21.     year += 4800+k;
    22.     mon += k & 12;
    23.     JDN += mon*30+(mon%5+1)/2+mon/5*3;
    24.     JDN += year*365+year/4+year/400-year/100-32045;
    25.     return JDN;
    26. }
    27. void    GetData(long JDN, SData *data)
    28. {
    29.     int     j400,j100,j4,j1,year,mon;
    30.     int     m5,m2,m1;
    31.     const int   days400year = 400*365+97;
    32.     const int   days100year = 100*365+24;
    33.     const int   days4year   = 4*365+1;
    34.     const int   days1year   = 1*365;
    35.     const int   days5mon    = 5*30+3;
    36.     const int   days2mon    = 2*30+1;
    37.     const int   days1mon    = 1*30+1;
    38.     long    day = JDN+32045-1;
    39.     j400 = day/days400year; day %= days400year;
    40.     j100 = day/days100year; day %= days100year;
    41.     j4   = day/days4year;   day %= days4year;
    42.     j1   = day/days1year;   day %= days1year;
    43.     if (j1==4){//високосный день
    44.         j1--;
    45.         day = 365;
    46.     }
    47.     year = j400*400+j100*100+j4*4+j1-4800;
    48.     m5 = day/days5mon; day %= days5mon;
    49.     m2 = day/days2mon; day %= days2mon;
    50.     m1 = day/days1mon; day %= days1mon;
    51.     mon = m5*5+m2*2+m1+3;
    52.     if (mon > 12){
    53.         mon -= 12;
    54.         year++;
    55.     }
    56.     data->day = day + 1;
    57.     data->mon = mon;
    58.     data->year = year;
    59. }
    60. bool    GetDDpMMpYYYY(const char *strDate, SData *data)
    61. {
    62.     char    *strEnd;
    63.     int day = strtol(strDate, &strEnd, 10);
    64.     if (strEnd[0]=='.'){
    65.         int mon = strtol(strEnd+1, &strEnd, 10);
    66.         if (strEnd[0]=='.'){
    67.             int year = strtol(strEnd+1, &strEnd, 10);
    68.             if (strEnd[0]==0){
    69.                 if (mon>=1 && mon<=12){
    70.                     int lenMon = LengthMON[mon-1];
    71.                     if (mon==2 && year%4==0 && year%100!=0 || year%400==0)
    72.                         lenMon++;
    73.                     if (day>=1 && day<=lenMon){
    74.                         data->day = day;
    75.                         data->mon = mon;
    76.                         data->year = year;
    77.                         return true;
    78.                     }
    79.                 }
    80.             }
    81.         }
    82.     }
    83.     printf("Date format error: '%s'\n", strDate);   //Ошибка формата даты
    84.     return false;
    85. }
    86. int main(int argc, const char *argv[])
    87. {
    88.     SData   date1, date2;
    89.     char    *strEnd;
    90.     if (argc<2)
    91.         printf("Usage: JD DD.MM.YYYY [DD.MM.YYYY]\n");
    92.     else {
    93.         long    JDN;
    94.         if (argc==2){
    95.             JDN = strtol(argv[1], &strEnd, 10);
    96.             if (strEnd[0]==0){
    97.                 GetData(JDN, &date1);
    98.                 printf("%ld = %d.%02d.%d\n", JDN, date1.day, date1.mon, date1.year);
    99.             } else {
    100.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    101.                 JDN = GetJDN(&date1);
    102.                 printf("%d.%02d.%d = %ld\n", date1.day, date1.mon, date1.year, JDN);
    103.             }
    104.         } else {
    105.             JDN = strtol(argv[2], &strEnd, 10);
    106.             if (strEnd[0]==0){
    107.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    108.                 JDN += GetJDN(&date1);
    109.                 GetData(JDN, &date2);
    110.                 printf("%d.%02d.%d + %s = %d.%02d.%d\n", date1.day, date1.mon, date1.year, argv[2], date2.day, date2.mon, date2.year);
    111.             } else {
    112.                 if (GetDDpMMpYYYY(argv[2], &date2)==false) return 0;
    113.                 JDN = GetJDN(&date2);
    114.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    115.                 JDN = JDN - GetJDN(&date1);
    116.                 printf("%d.%02d.%d - %d.%02d.%d = %ld\n", date1.day, date1.mon, date1.year, date2.day, date2.mon, date2.year, JDN);
    117.             }
    118.         }
    119.     }
    120.     return 0;
    121. }
    Исправил, теперь код будет работать на самых древних машинах. Возможно будет термояд. война, будешь рад и 16 битной пекашки если выживешь!
     
  8. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    чет в отрицательную вселенную ваша прога иногда заскакивает
    не страшно в вечной мерзлоте? :)

    Код (Text):
    1. 15.10.2023 + 99999999999999999999 = -25.-7.-5877586
     
  9. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    alex_dz, допустимый диапазон +- 5879489 год, потом происходит переполнение. А так предполагается что пользователь вводит вменяемые параметры, хотя бы в пределах 10'000 лет.
     
  10. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    449
    никогда не доверяй юзеру (с) MCMXIILVK
    --- Сообщение объединено, 15 окт 2023 ---
    из-за таких вот предполагается потом уйма CVE зеродеев и подрывов атомных станций в Иране и Фукусиме
     
  11. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    alex_dz, я там немного накосячил с типами, в общем алгоритм предполагает положительные типа данные, точней беззнаковые типа кроме year. Возможно точку ноль надо не 4800 год до нашей эры, а MIN_INT. Тогда отрицательных чисел не будет. В общем, функция GetDate правильно работает до 2147451603, а потом выдаёт ошибку.
    --- Сообщение объединено, 16 окт 2023 ---
    Код (C++):
    1. ////////////////////////////////////////////////////////////////////
    2. //  Julian Day Number       v0.06
    3. //  (c) NanoBot
    4. ////////////////////////////////////////////////////////////////////
    5. #include <stdio.h>
    6. #include <stdlib.h>
    7. struct SDate
    8. {
    9.     int day;    //1..31
    10.     int mon;    //1..12
    11.     int year;
    12. };
    13. const int   LengthMON[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    14. const int   days400year = 400*365+97;
    15. const int   days100year = 100*365+24;
    16. const int   days4year   = 4*365+1;
    17. const int   days1year   = 1*365;
    18. const int   days5mon    = 5*30+3;
    19. const int   days2mon    = 2*30+1;
    20. const int   days1mon    = 1*30+1;
    21. long    GetJDN(SDate *date)
    22. {
    23.     unsigned long JDN = date->day;
    24.     int mon = date->mon-1;  //1..12
    25.     unsigned long year = date->year;
    26.     mon-=2; /* Новый год 1 марта! */
    27.     int k = mon<0 ? -1 : 0;
    28.     year += 4800+k + 5879600;
    29.     mon += k & 12;
    30.     JDN += mon*30+(mon%5+1)/2+mon/5*3;
    31.     JDN += year*365+year/4+year/400-year/100-32045;
    32.     return JDN - 2147479803;
    33. }
    34. void    GetDate(long JDN, SDate *date)
    35. {
    36.     unsigned int    j400,j100,j4,j1,year;
    37.     unsigned int    mon,m5,m2,m1;
    38.     unsigned long   day = JDN+32045-1+2147479803;
    39.     j400 = day/days400year; day %= days400year;
    40.     j100 = day/days100year; day %= days100year;
    41.     j4   = day/days4year;   day %= days4year;
    42.     j1   = day/days1year;   day %= days1year;
    43.     if (j1==4){//високосный день
    44.         j1--;
    45.         day = 365;
    46.     }
    47.     year = j400*400+j100*100+j4*4+j1-4800 - 5879600;
    48.     m5 = day/days5mon; day %= days5mon;
    49.     m2 = day/days2mon; day %= days2mon;
    50.     m1 = day/days1mon; day %= days1mon;
    51.     mon = m5*5+m2*2+m1+3;
    52.     if (mon > 12){
    53.         mon -= 12;
    54.         year++;
    55.     }
    56.     date->day = day + 1;
    57.     date->mon = mon;
    58.     date->year = year;
    59. }
    60. bool    GetDDpMMpYYYY(const char *strDate, SDate *date)
    61. {
    62.     char    *strEnd;
    63.     int day = strtol(strDate, &strEnd, 10);
    64.     if (strEnd[0]=='.'){
    65.         int mon = strtol(strEnd+1, &strEnd, 10);
    66.         if (strEnd[0]=='.'){
    67.             int year = strtol(strEnd+1, &strEnd, 10);
    68.             if (strEnd[0]==0){
    69.                 if (mon>=1 && mon<=12){
    70.                     int lenMon = LengthMON[mon-1];
    71.                     if (mon==2 && year%4==0 && year%100!=0 || year%400==0)
    72.                         lenMon++;
    73.                     if (day>=1 && day<=lenMon){
    74.                         date->day = day;
    75.                         date->mon = mon;
    76.                         date->year = year;
    77.                         return true;
    78.                     }
    79.                 }
    80.             }
    81.         }
    82.     }
    83.     printf("Date format error: '%s'\n", strDate);   //Ошибка формата даты
    84.     return false;
    85. }
    86. int main(int argc, const char *argv[])
    87. {
    88.     SDate   date1, date2;
    89.     char    *strEnd;
    90.     if (argc<2)
    91.         printf("Usage: JD DD.MM.YYYY [DD.MM.YYYY]\n");
    92.     else {
    93.         long    JDN;
    94.         if (argc==2){
    95.             JDN = strtol(argv[1], &strEnd, 10);
    96.             if (strEnd[0]==0){
    97.                 GetDate(JDN, &date1);
    98.                 printf("%ld = %d.%02d.%d\n", JDN, date1.day, date1.mon, date1.year);
    99.             } else {
    100.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    101.                 JDN = GetJDN(&date1);
    102.                 printf("%d.%02d.%d = %ld\n", date1.day, date1.mon, date1.year, JDN);
    103.             }
    104.         } else {
    105.             JDN = strtol(argv[2], &strEnd, 10);
    106.             if (strEnd[0]==0){
    107.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    108.                 JDN += GetJDN(&date1);
    109.                 GetDate(JDN, &date2);
    110.                 printf("%d.%02d.%d + %s = %d.%02d.%d\n", date1.day, date1.mon, date1.year, argv[2], date2.day, date2.mon, date2.year);
    111.             } else {
    112.                 if (GetDDpMMpYYYY(argv[2], &date2)==false) return 0;
    113.                 JDN = GetJDN(&date2);
    114.                 if (GetDDpMMpYYYY(argv[1], &date1)==false) return 0;
    115.                 JDN = JDN - GetJDN(&date1);
    116.                 printf("%d.%02d.%d - %d.%02d.%d = %ld\n", date1.day, date1.mon, date1.year, date2.day, date2.mon, date2.year, JDN);
    117.             }
    118.         }
    119.     }
    120.     return 0;
    121. }
    Ну тут исправил, как я сказал проблемы с отрицательными числами, а алгоритм ожидает положительные числа. Хотя возможно есть какой-то не допустимый диапазон, где результат не правильный. Но по жизни и старый код работал, нехрен забивать заведомо бредовые параметры. Минус 10 тыс лет или даже 100 тыс, плюс 10 тыс лет вам хватит. А в пределах несколько столетий туда сюда, точно всё работает.