티스토리 뷰
반응형
델파이로 양력을 음력으로 변환하거나, 반대로 음력을 양력으로 변환해야 하는 경우가 많은데요.
오늘은 음력과 양력을 변환하여 주는 함수를 포스팅 하여 보겠습니다.
오래전에 여기 저기 검색하여 찾은 함수인데,
다시 찾으려 하니 보이지가 않더군요.
다시 정리하여 올려 봅니다.
필요하신 분은 사용하여 보세요.
단, 저는 잘 사용하고 있는데 보장은 할 수 없습니다.
우선 상수 선언이 필요합니다.
const
s_Year = 1881;
e_Year = 2050;
LunDays: array[1..6]of Integer = (353, 354, 355, 383, 384, 385);
LunData: array[s_Year..e_Year, 1..5]of Char = (
'5H57A', '3 55B', '2 25D', '5F95B', '2 92B', '2 A95', '5ED95', '2 B4A', '3 B55', '5C6D5', // 1890
'3 55B', '5G277', '2 257', '2 52B', '4FAAA', '3 E95', '2 6AA', '5DBAA', '3 AB5', '5I4BD', // 1900
'2 4AE', '3 A57', '4F54D', '2 D26', '3 D95', '5e655', '2 56A', '3 9AD', '5C55D', '2 4AE', // 1910
'5GA5B', '2 A4D', '2 D25', '5FDA9', '3 B55', '2 56A', '5CADA', '3 95D', '5H4BB', '2 49B', // 1920
'2 A4B', '5FB4B', '2 6A9', '2 AD4', '6EBB5', '2 2B6', '3 95B', '5C537', '2 497', '4G656', // 1930
'2 E4A', '3 EA5', '5f6A9', '3 5B5', '2 2B6', '5d8AE', '2 92E', '5hC8D', '2 C95', '2 D4A', // 1940
'5gD8A', '3 B69', '3 56D', '5e25B', '2 25D', '2 92D', '5CD2B', '2 A95', '5HD55', '2 B4A', // 1950
'3 B55', '5f555', '3 4DB', '2 25B', '5d857', '2 52B', '5IA9B', '2 695', '2 6AA', '5GAEA', // 1960
'3 AB5', '2 4B6', '5EAAE', '3 A57', '2 527', '4D726', '3 D95', '5H6B5', '2 56A', '3 9AD', // 1970
'5F4DD', '2 4AE', '2 A4E', '5ED4D', '2 D25', '5ID59', '2 B54', '3 D6A', '5g95A', '3 95B', // 1980
'2 49B', '5EA9B', '2 A4B', '5KB27', '2 6A5', '2 6D4', '6GB75', '2 2B6', '3 95B', '5F4B7', // 1990
'2 497', '2 64B', '4D74A', '3 EA5', '5I6D9', '3 5AD', '2 2B6', '5F96E', '2 92E', '2 C96', // 2000
'5EE95', '2 D4A', '3 DA5', '5C755', '2 56C', '6HABB', '2 25D', '2 92D', '5FCAB', '2 A95', // 2010 //2009 5FCAB
'2 B4A', '5dB4A', '3 B55', '5J55D', '2 4BA', '3 A5B', '5F557', '2 52B', '2 A95', '5EB95', // 2020
'2 6AA', '3 AD5', '5C6B5', '2 4B6', '5GA6E', '3 A57', '2 527', '4F6A6', '3 D93', '2 5AA', // 2030
'5DB6A', '3 96D', '5L4AF', '2 4AE', '2 A4D', '5gD0D', '2 D25', '2 D52', '5FDD4', '3 B6A', // 2040
'3 96D', '5C55B', '2 49B', '5HA57', '2 A4B', '2 B25', '5fB25', '2 6D4', '3 ADA', '5d8B6'); // 2050
함수 정의는 다음과 같습니다.
//
// 음력을 양력으로 변환
function Luna2Sola(
luYear, luMonth, luDay: Word; IsLeap: Boolean; // 전달 음력 연월일
var soYear, soMonth, soDay: Word; // 수신 양력 연월일
var ErrMsg: string): Boolean; // 오류 메시지
// 양력을 음력으로 변환
function Sola2Luna(
soYear, soMonth, soDay: Word; // 전달 양력 연월일
var luYear, luMonth, luDay: Word; var IsLeap, IsLarge: Boolean; // 수신 음력 연월일
var ErrMsg: string): Boolean; // 오류 메시지
//
// 공용함수
function LunaHexToBin(Data: string): string;
// 양력을 음력으로 변환하는 함수 본분입니다.
//
// 양력을 음력으로 변환하는 함수
function Sola2Luna(
soYear, soMonth, soDay: Word; // 전달 정보
var luYear, luMonth, luDay: Word; var IsLeap, IsLarge: Boolean; // 반환 정보
var ErrMsg: string): Boolean; // 에러메시지
var
EnDays: Integer;
// 서브함수
FUNCTION CheckDays(d: Integer): Boolean;
begin
Result := EnDays - d > 0;
if Result then EnDays := EnDays - d;
end;
// 서브함수
PROCEDURE DoLuner(StartYear, Days: Integer);
var
BitStr: string;
LeapIndex: Integer;
begin
Result := True;
EnDays := EnDays - Days;
luYear := StartYear;
while CheckDays(LunDays[StrToInt(LunData[luYear, 1])])do
Inc(luYear);
BitStr := LunaHexToBin(LunData[luYear]);
luMonth := 1;
while CheckDays(29 + Ord(BitStr[luMonth]))do
Inc(luMonth);
luDay := EnDays;
IsLarge := BitStr[luMonth] = #1;
LeapIndex := Ord(UpCase(LunData[luYear, 2])) - 64;
IsLeap := luMonth = LeapIndex;
if(LeapIndex > 0)and(LeapIndex <= luMonth)then
Dec(luMonth);
end;
begin
Result := False;
try
EnDays := Trunc(EnCodeDate(soYear, soMonth, soDay));
except
ErrMsg := '입력된 날자가 올바르지 않습니다.';
end;
if(EnDays < -6909)or(EnDays > 55194)then // EnCodeDate(1881, 1, 30), EnCodeDate(2051, 2, 10)
ErrMsg := '양력의 입력범위는 1881-01-30 ~ 2051-02-10 입니다.'
else
if EnDays > 24128 then DoLuner(1966, 24128)
else DoLuner(1881, -6909);
end;
// 음력을 양력으로 변환하는 함수 본문입니다.
//
// 음력을 양력으로 변환
function Luna2Sola(
luYear, luMonth, luDay: Word; IsLeap: Boolean; // 전달정보
var soYear, soMonth, soDay: Word; // 반환정보
var ErrMsg: string): Boolean; // 반환에러메시지
var
LeapIndex: Integer;
BitStr: string;
// 서브함수
PROCEDURE DoSolar(StartYear, Days: Integer);
var
I: Integer;
begin
Result := True;
Days := luDay + Days;
for I := StartYear to luYear - 1 do
Days := Days + LunDays[StrToInt(LunData[I, 1])];
if IsLeap or(LeapIndex > 0)and(LeapIndex <= luMonth)then
Inc(luMonth);
for I := 1 to luMonth - 1 do
Days := Days + 29 + Ord(BitStr[I]);
DeCodeDate(Days, soYear, soMonth, soDay);
end;
begin
Result := False;
if(luYear < s_Year)or(luYear > e_Year)then
ErrMsg := '음력의 입력범위는 1881년 ~ 2050년 입니다.'
else
begin
BitStr := LunaHexToBin(LunData[luYear]);
LeapIndex := Ord(UpCase(LunData[luYear, 2])) - 64;
if (IsLeap) and (LeapIndex <> (luMonth + 1)) then
ErrMsg := IntToStr(luYear) + '-' + IntToStr(luMonth) + '월은 윤달이 없습니다'
else
if LeapIndex < luMonth then
begin
if luDay > 29 + Ord(BitStr[luMonth+1])then
ErrMsg := IntToStr(luYear) + '-' + IntToStr(luMonth) + '월은 ' +
IntToStr(29 + Ord(BitStr[luMonth])) + '일 까지 입니다.'
else
if luYear > 1965 then DoSolar(1966, 24128)
else DoSolar(1881, -6909);
end
else begin
if luDay > 29 + Ord(BitStr[luMonth])then
ErrMsg := IntToStr(luYear) + '-' + IntToStr(luMonth) + '월은 ' +
IntToStr(29 + Ord(BitStr[luMonth])) + '일 까지 입니다.'
else
if luYear > 1965 then DoSolar(1966, 24128)
else DoSolar(1881, -6909);
end;
end;
end;
다음은 위 두 함수에서 공용으로 사용하는 함수 본문입니다.
//
// 공용함수
function LunaHexToBin(Data: string): string;
var
I, Hex, Temp: Integer;
begin
SetLength(Result, 12);
Hex := StrToInt('$' + Copy(Data, 3, 3));
Temp := 2048; // 10000000000 12자리 2진수 비트값
for I := 1 to 12 do
begin
if Hex < Temp then
Result[I] := #0 // 작은달
else
begin
Result[I] := #1; // 큰달
Hex := Hex - Temp;
end;
Temp := Temp shr 1;
end;
case Data[2]of
'A'..'L' : Insert(#0, Result, Ord(Data[2]) - 64); // 윤달 작은달 삽입
'a'..'l' : Insert(#1, Result, Ord(Data[2]) - 96); // " 큰달 "
end;
end;
반응형
'프로그래밍' 카테고리의 다른 글
[Delphi] 델파이 라이브러리 제공되지 않는 문자열 필터링 함수 (4) | 2023.02.12 |
---|---|
[Delphi] 델파이 폼위치 기록 INI파일 이용하여 위치저장 및 복구 함수 (0) | 2023.02.06 |
[Delphi] 델파이 썸네일 등 이미지 파일크기 축소 (0) | 2023.02.06 |
[Delphi] 델파이 PC명칭 OS버젼 MAC주소 HDD볼륨 구하는 함수 (0) | 2023.02.06 |
[Delphi] 델파이 내부IP 외부IP 구하는 함수 (0) | 2023.02.06 |
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 내부IP구하기
- 델파이날짜연산 #델파이날짜함수 #날짜연산 #날짜함수 #델파이
- 동부시립병원
- 전화특허
- 가정용전동드라이버
- 선물하기좋은차
- 통화매니저
- 문자보내기 #PC문자보내기 #콜백문자 #콜백서비스 #자동문자 #통화매니저
- 와룡공원드라마촬영장소
- 소형전기드릴
- 유기농건강차
- 가정용전기드라이버
- 한양도성둘레길
- 통화매니저 #KT통화매니저 #발신자정보표시 #고객관리 #콜백문자 #문자보내기
- 고객이음 #문자보내기 #단체문자 #고객관리 #회원관리 #콜백문자 #콜백서비스 #자동문자
- 그레이엄빌
- 폼위치저장
- 명륜유치원
- 성북동부자마을
- 고객관리 #회원관리 #휴대폰주소록 #문자보내기 #콜백문자 #콜백서비스 #자동문자 #통화매니저
- 델파이
- 성북동판자촌
- 도메인IP변환
- 외부IP구하기
- 가정용전기드릴
- 전화번호대시넣기
- 소형전동드릴
- 미니드릴
- Hexa문자열변환
- 부재중문자
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
글 보관함