Вот код, который я сам сделал уже не помню когда. Код (C): /*============================================ Julian Day Number v0.02 (c) NanoBot ============================================*/ #include <stdio.h> #include <time.h> long GetJDN(struct tm *date) { int mon, year, k; long JDN = date->tm_mday; mon = date->tm_mon; year = date->tm_year; k = (mon-=2)<0; /* Новый год 1 марта! */ year += 4800-k; mon += 12*k; JDN += mon*30+(mon%5+1)/2+mon/5*3; JDN += year*365+year/4+year/400-year/100-32045; return JDN; } long GetMJD(struct tm *date) { struct tm date0; date0.tm_mday = 17; date0.tm_mon = 11-1; /* ноябрь */ date0.tm_year = 1858; return GetJDN(date)-GetJDN(&date0); } int main(int argc, char *argv[]) { struct tm date; long num_jd; char* strEnd; if(argc!=4){ puts("Usage: JD day mon year\n"); return 0; } date.tm_mday = strtol(argv[1], &strEnd, 10); if (!*strEnd){ date.tm_mon = strtol(argv[2], &strEnd, 10) - 1; if (!*strEnd){ date.tm_year = strtol(argv[3], &strEnd, 10); if (!*strEnd){ num_jd = GetJDN(&date); printf("%d.%02d.%d, JD = %ld/n", date.tm_mday, date.tm_mon, date.tm_year, num_jd); return 0; } } } printf("ERROR The integer is expected. %s\r\n", strEnd); return 1; } У него есть проблема. Неправильно вычисляется номер дня после 4800 года до нашего стиля. Надо бы доработать код. ЗЫ Да, код я чисто сам создал. --- Сообщение объединено, 19 дек 2020 --- Ну и в ответку конечно ассемблер UASM. Код (ASM): ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Julian Day Number v0.02 ;; (c) NanoBot ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .486 .model flat, stdcall option casemap:none include msvcrt.inc include \masm32\macros\macros.asm include macros.asm main PROTO C :dword, :dword, :dword tm struct tm_sec dword ? tm_min dword ? tm_hour dword ? tm_mday dword ? tm_mon dword ? tm_year dword ? tm_wday dword ? tm_yday dword ? tm_isdst dword ? tm ends ;.date .code mainCRTStartup proc local argc:sdword, argv:ptr, environ:ptr, StartInfo:_startupinfo and StartInfo.newmode, 0 __getmainargs(&argc, &argv, &environ, 0, &StartInfo) .if (eax==0) main(argc, argv, environ) .endif _exit(eax) mainCRTStartup endp int_div MACRO a:req, b:req IFDIFI <a>, <eax> mov eax, a ENDIF mov ecx, b cdq idiv ecx ENDM int_div$ MACRO a:req, b:req int_div a, b EXITM <eax> ENDM align_proc GetJDN proc (dword) uses esi edi ebx date:ptr tm mov edx, date ASSUME edx:ptr tm mov esi, [edx].tm_mday ;JDN mov ebx, [edx].tm_mon ;mon mov edi, [edx].tm_year ;year ASSUME edx:nothing ;k = (mon-=2)<0; /* Новый год 1 марта! */ xor eax, eax sub ebx, 2 setl al neg eax ;k= mon<0 ? -1 : 0; ;year += 4800-k; lea edi, [edi+eax+4800] ;mon += 12*k; and eax, 12 add ebx, eax ;JDN += mon*30+(mon%5+1)/2+mon/5*3; imul eax, ebx, 30 add esi, eax int_div ebx, 5 inc edx shr edx, 1 ;/=2 lea eax, [eax*2+eax] ;*=3 add esi, edx add esi, eax ;JDN += year*365+year/4+year/400-year/100-32045; imul eax, edi, 365 add esi, eax add esi, int_div$(edi, 4) add esi, int_div$(edi, 400) sub esi, int_div$(edi, 100) lea eax, [esi-32045] ret GetJDN endp ;align_proc ;GetMJD proc date:ptr tm ;local date0:tm ; mov date0.tm_mday, 17 ; mov date0.tm_mon, 11-1 ;ноябрь ; mov date0.tm_year, 1858 ; mov ebx, GetJDN(date) ; sub ebx, GetJDN(&date0) ; mov eax, ebx ; ret ;GetMJD endp align_proc main proc C argc:sdword, argv:ptr ptr, envp:ptr ptr local date:tm, strEnd:ptr byte mov esi, argv .if (argc!=4) printf("Usage: JD day mon year\n") xor eax, eax ret .endif ASSUME eax:ptr byte mov date.tm_mday, strtol([esi+1*4], &strEnd, 10) mov eax, strEnd .if ([eax]==0) strtol([esi+2*4], &strEnd, 10) dec eax mov date.tm_mon, eax mov eax, strEnd .if ([eax]==0) mov date.tm_year, strtol([esi+3*4], &strEnd, 10) mov eax, strEnd .if ([eax]==0) GetJDN(&date) printf("%d.%02d.%d, JD = %ld/n", date.tm_mday, date.tm_mon, date.tm_year, eax) xor eax, eax ret .endif .endif .endif ASSUME eax:nothing printf("ERROR! The integer is expected. %s\n", strEnd) mov eax, 1 ret main endp end mainCRTStartup Код ( (Unknown Language)): @echo off ..\..\..\uasm246_x86\bin\uasm32 /c /coff /I\assemblers\uasm246_x86\include JD.asm \masm32\bin\link /SUBSYSTEM:CONSOLE /LIBPATH:\assemblers\uasm246_x86\lib JD.obj rem ..\..\..\uasm246_x86\bin\polink if exist JD.obj del JD.obj pause Если что код своих библиотек потом вылажу. Я грозился для UASM MS-DOS сделать стандартную библиотеку сделать. Ладно!
Я помню, тут уже это выкладывал. Вот только совсем не подходящей теме. Код (C): /*===================================================== Дата православной и католической пасхи. По формуле Карла Фридриха Гаусса (1777-1855). Календарь и хронология. Климишин И.А. 1990, стр. 133 (c) Intro v1.04 5.04.2019 2.04.2020 ======================================================*/ #include <stdio.h> #include <stdlib.h> #ifndef bool #define bool char #define true 1 #define false 0 #endif typedef struct _Sdate { int day; /* 1-31 */ int mon; /* 1-12 */ } Sdate; /* Расхождение между новым и старым стилем, дней. */ int NewStyleDay(int year) { int century = year/100; return (century/4)*3 + century%4 - 2; } /* номер дня от 1 марта в Sdate */ const int days_in_year[12] = {31,30,31,30,31,31,30,31,30,31,31,28}; void NumDay2Data(Sdate *date, int day) { int mon; for(mon=0; mon<12 && day>days_in_year[mon]; ++mon) day -= days_in_year[mon]; date->day = day; date->mon = mon+3; } int GetEasterGauss(int year, int m, int n, bool is_catholic) { int a,b,c,d,e,day; a = year % 19; b = year % 4; c = year % 7; d = (19*a + m) % 30; e = (2*b + 4*c + 6*d + n) % 7; day = 22 + d + e; if (is_catholic && (day>=56 && e==6)) day -= 7; return day; } int GetOrthodoxEaster(int year) /* православная пасха */ { return GetEasterGauss(year, 15, 6, false); } int GetCatholicEaster(int year) /* католическая пасха */ { int M,N,p,q,century; century = year/100; p = (century*8 + 13)/25; q = century/4; M = (century - p - q + 15) % 30; N = (century - q + 4) % 7; return GetEasterGauss(year, M, N, true); } int main(int argc, char *argv[]) { Sdate old_s, new_s; int year, day; if(argc!=2){ puts("Usage: easter year\n"); return 0; } year = atoi(argv[1]); day = GetOrthodoxEaster(year); /* old style */ NumDay2Data(&old_s, day); day += NewStyleDay(year); NumDay2Data(&new_s, day); printf("Orthodox easter in %d:\n", year); printf("Old style: %2d.%02d New style: %2d.%02d\n", old_s.day, old_s.mon, new_s.day, new_s.mon); day = GetCatholicEaster(year); /* new style */ NumDay2Data(&new_s, day); day -= NewStyleDay(year); NumDay2Data(&old_s, day); printf("Catholic easter in %d:\n", year); printf("Old style: %2d.%02d New style: %2d.%02d\n", old_s.day, old_s.mon, new_s.day, new_s.mon); return 0; } Так же есть проблемы, если год задан слишком большой, но в пределах до 3000 года дата вычисляется точно.
Блиннн, аптимизатыр хреныф. Код (C): /*============================================ Julian Day Number v0.02 (c) NanoBot ============================================*/ #include <stdio.h> #include <time.h> long GetJDN(struct tm *date) { int mon, year, k; long JDN = date->tm_mday; mon = date->tm_mon; year = date->tm_year; k = (mon-=2)<0; /* Новый год 1 марта! */ year += 4800-k; mon += 12*k; JDN += mon*30+(mon%5+1)/2+mon/5*3; JDN += year*365+year/4+year/400-year/100-32045; return JDN; } long GetMJD(struct tm *date) { struct tm date0; date0.tm_mday = 17; date0.tm_mon = 11-1; /* ноябрь */ date0.tm_year = 1858; return GetJDN(date)-GetJDN(&date0); } int main(int argc, char *argv[]) { struct tm date; long num_jd; char* strEnd; if(argc!=4){ puts("Usage: JD day mon year\n"); return 0; } date.tm_mday = strtol(argv[1], &strEnd, 10); if (!*strEnd){ int mon = strtol(argv[2], &strEnd, 10); /* 1..12 */ if (!*strEnd){ date.tm_year = strtol(argv[3], &strEnd, 10); if (!*strEnd){ date.tm_mon = mon-1; num_jd = GetJDN(&date); printf("%d.%02d %d, JD = %ld/n", date.tm_mday, mon, date.tm_year, num_jd); return 0; } } } printf("ERROR The integer is expected. %s\r\n", strEnd); return 1; }