Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일

파판14 - 에오르제아의 시간 알람을 위한 C# WinForms 응용 프로그램

오늘은 문득, 에오르제아의 시간이 현실 시간으로 어떻게 되나 궁금했습니다. 다행히, 이에 대한 힌트를 얻기 위해 검색해 본 다음의 사이트에,

http://ff14s.phps.kr/

아래와 같은 JavaScript 소스 코드를 구할 수 있습니다.

var mus = new Audio();

function get_et(){
    var now = new Date();
    var epock = Date.UTC(2010, 6, 12, 0, 0, 0) - 9 * 60 * 60 * 1000;
    return parseInt((parseInt((now.getTime() - epock) / 1000) - 90000) * (1440 / 70));
}

function update_timezone_pos(){
    var et = get_et();
    var h = parseInt((et % (3600*24)) / 3600);
    var m = parseInt((et % 3600) / 60);
    if(h==$("#h-set").val()&&m==$("#m-set").val()&&$("#h-set").val()!=""&&$("#m-set").val()!="") {
        mus.loop=true;mus.play();
        if($("#ok-alarm").prop("checked")==true){setTimeout(function(){mus.pause();mus.currentTime=0;},5000);}
    }
    $("#eClock").text(("0"+h).substr(-2)+":"+("0"+m).substr(-2));
}

$(function(){
    $("#chk").click(function(){
        $("#ifr").attr("src","");
    });
    $("#alarm-play").click(function(){
        mus.src = "http://ff14s.dothome.co.kr/FFXIV.mp3";
        mus.src = "https://a.clyp.it/ku4zi0bf.mp3";
        mus.type = "audio/mpeg";
        mus.preload="auto";
        mus.loop=true;
        mus.play();
    });
    $("#alarm-stop").click(function(){
        mus.pause();
        mus.currentTime=0;
    });
    
    update_timezone_pos();
    
    setInterval(function(){ update_timezone_pos();},2500);
});

중요한 것은 get_et 함수인데요, 관련해서 JavaScript의 시간을 C#으로 변환하는 것에 대해 다음의 글을 참조하시면,

JavaScript와 C#의 시간 변환
; https://www.sysnet.pe.kr/2/0/12849

C#으로 현재의 에오르제아 시간 구하는 코드를 이렇게 구현할 수 있습니다.

public static class TimeUtil
{
    static DateTime _etCreated = new DateTime(2010, 6 + 1, 12, 0, 0, 0, DateTimeKind.Utc);
    static double _etEpoch = GetTime(_etCreated) - 9 * 60 * 60 * 1000;

    public static long GetTime(this DateTime time)
    {
        return (time.Ticks - 621355968000000000) / TimeSpan.TicksPerMillisecond;
    }

    public static double CurrentEorzeaTime
    {
        get
        {
            double time = ((GetTime(DateTime.UtcNow) - _etEpoch) / 1000 - 90000) * (1440.0 / 70);
            return time;
        }
    }
}

그리고 CurrentEorzeaTime으로부터 "시간"과 "분"을 최종적으로 다음과 같이 구할 수 있습니다.

double now = TimeUtil.CurrentEorzeaTime;

int hour = (int)((now % (3600 * 24)) / 3600.0);
int minute = (int)((now % 3600) / 60.0);

자, 그럼 위에서 다뤘던 코드를 가만히 보면 에오르제아의 1분이 현실 시간으로 어떻게 되는지 구할 수 있습니다.

double time = ((GetTime(DateTime.UtcNow) - _etEpoch) / 1000 - 90000) * (1440.0 / 70);

우선 아래의 코드는 "- 90000"을 제외하면 그냥 epoch 시간으로부터 흐른 총 초를 의미합니다.

((GetTime(DateTime.UtcNow) - _etEpoch) / 1000 - 90000)

그리고 그 초에 (1440.0 / 70의 결과인) 20.571428...로 571428이 반복되는 순환소수를 곱합니다. 즉, 현실 시간의 1초가 흐르면 에오르제아 세계에서는 20.571428... 초가 흐르는 것입니다.

에오르제아는 시간을 "hh:mm"으로 보여주는데 결국 현실 시간으로 3초가 안 되는 시간이 흐르면 에오르제아에서는 1분이 흐르는 것입니다. 달리 말해 에오르제아의 1분은 아래의 비례식을 풀어,

1:20.571428... = x:60

(1440/70) * x = 60
x = 60 / (1440/70)
x = 2.916...(6 순환)...

현실에서 2.916... 초의 딱 떨어지지 않는 시간이 흘렀을 때 에오르제아에서는 1분이 지나 버리는 것입니다. (아마도, 에오르제아라는 행성은 지구보다 중력 가속도가 엄청 작아 시간이 빠르게 흐르는 듯합니다.)

이것을 따져봤을 때, ff14.js에 있는 소스 코드에서 setInterval 함수가,

setInterval(function(){ update_timezone_pos();},2500);

2500의 값을 쓰는 것이 그리 좋은 생각은 아닙니다. 하지만 이게 무슨 우주 왕복선의 코드도 아니니... ^^ 충분히 용납될 수 있습니다.

어쨌든, 저런 식의 계산으로 인해 현실 시간의 70분마다 에오르제아에서는 24시간의 하루가 지나게 됩니다.




그건 그렇고, 자바스크립트의 코드를 보면 좀 이해가 안 되는 부분이 있습니다.

function get_et(){
    var now = new Date();
    var epock = Date.UTC(2010, 6, 12, 0, 0, 0) - 9 * 60 * 60 * 1000;
    return parseInt((parseInt((now.getTime() - epock) / 1000) - 90000) * (1440 / 70));
}

9 * 60 * 60 * 1000은 9시간에 대한 총 밀리 초를 의미합니다. 그런데 왜 굳이 UTC에서 9시간을 뺸 것일까요? 게임 서버가 위치한 곳이 한국이라고 가정했을 때 한국 표준시(KST)에 해당하는 9시간을 빼면 UTC가 나옵니다. 즉, 위의 코드는 어차피 Local Time이 아닌 UTC 시간에서 다시 KST 시간에 해당하는 밀리 초만큼을 빼고 있는 것입니다.

저 오류는 아마도 파판14 측의 개발자에서부터 잘못한 것으로 보입니다. 어쩌면 그는 UTC/Local 시간에 대한 정확한 이해가 없는 상태에서 저렇게 시간을 정한 듯싶고 이후 그 계산법에서 파생된 여러 소스 코드들에서 어쩔 수 없이 (UTC - 9시간)에 해당하는 수식을 넣어야만 했을 것입니다.

마지막으로, 저렇게 만든 시간이 정작 게임에서 보이는 시간과는 ET 1~2(초가 아닌)분의 차이가 발생할 수 있습니다. 왜냐하면 해당 게임 서버의 시간과 여러분의 컴퓨터 시간이 정확히 일치하지는 않을 것이기 때문에 그 정도 차이는 가능합니다.




자... 시간에 대한 이야기는 이걸로 끝이고, 이제 남은 작업은 약간 지루한 것들입니다. 사용자가 원하는 시간을 설정할 수 있도록 해야 하고, 그 값을 저장 및 복원하는 것도 필요할 것입니다. 또한 당연히 설정한 시간과 분이 되었을 때 알릴 수 있어야 하고.

그중에서, 사용자에게 알리는 부분은 다음의 코드를 넣으면 좋을 듯합니다.^^

.NET 코드 - 창 흔드는 효과
; https://www.sysnet.pe.kr/2/0/966

그리고 이 모든 것을 종합해 Windows Forms 응용 프로그램을,

ff14_alarm_timer_winform_1.png

만든 소스 코드를 첨부했으니 원하시는 분은 가져다 써도 되겠습니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 10/19/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2023-01-27 08시30분
goatcorp/Dalamud - FFXIV plugin framework and API
; https://github.com/goatcorp/Dalamud
정성태

1  [2]  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
527정성태7/13/20215642Microsoft Edge의 뉴스 알림 창 끄는 방법
526정성태7/11/202111327AMD CPU를 장착한 컴퓨터에서 Windows 11을 위한 fTPM 활성화 방법
525정성태6/30/20219530저작권 표시 없는 상업적 사용 가능한 무료 아이콘 구하기 [3]
524정성태6/25/20218502Windows 11 설치를 가로막는 TPM 칩, 운이 좋다면 구매할 수 있습니다. [3]
523정성태5/3/202110024절전 모드로 내려가는 우분투 머신 [7]
522정성태9/16/2020108232020년 작업 PC ^^ [7]
521정성태11/25/201910940[종료] "시작하세요. C# 8.0 프로그래밍" 책을 1만원에 판매합니다. (4권 한정) [2]
520정성태8/26/20197525Snagit 2019(Build 3847) 사용 시 Effect 변경 후 창을 닫는 시점에 응용 프로그램이 종료하는 현상
519정성태7/15/20199677youtube-dl.exe를 윈도우 샌드 박스에서 실행
518정성태7/1/201910425크로미움 기반의 Microsoft Edge 웹 브라우저... 쓸만하네요. ^^ [4]
517정성태5/16/20199530윈도 운영체제는 태생적으로 갖고 있는 문제들로 인해 아직도 매우 취약한 운영체제로 분류됩니다?!! [2]
516정성태5/16/20198519배터리 사용 중인 태블릿에는 크롬보다는 Edge 브라우저가 더 낫습니다.
515정성태11/19/201812873LED 전등 교체와 잔광 현상 제거 콘덴서 - 두 번째 이야기
514정성태10/30/201814510LED 매입등 교체와 잔광 현상 제거 콘덴서
513정성태9/13/20189860블로거 분들 랜섬웨어 메일 "저작권관련 이미지 무단사용 안내메일(장명옥 본인제작)" 조심하세요. [2]
512정성태8/10/20189620번개는 땅에서부터 하늘로 올라가는 현상? [1]
511정성태7/21/20189991[종료] DDR 3 4GB * 4EA, AMD 페넘II-X4 905e, 메인 보드 GA-770TA-UD3를 드립니다. [3]
509정성태6/12/201811427목/허리가 아픈 개발자들을 위한 근육 마사지 치료법 - KSNS [1]
508정성태5/22/201814859로이 베나비데스
507정성태4/13/201810902sysnet 블로그 관련 수치 [1]
506정성태1/20/201816971삼성 A/S 경험 - 오디세이(Odyssey) 노트북이 게임 도중 갑자기 전원이 나가는 경우 [2]
505정성태1/9/201716103모니터 간단 소개 - LG IPS LED 24MA53, 델 UltraSharp 24 - U2414H, 알파스캔 AOC 2477 IPS
504정성태9/25/201621376모니터 3대를 NVidia Surround로 연결하기 - 두 번째 [3]
503정성태9/22/201615645Wacom BAMBOO 태블릿 - Tablet PC Defined 메뉴가 없는 경우 [1]
501정성태5/31/201615667twoomail.com으로부터 온 "'...'님이 쪽지를 보냈습니다."는 twoo.com의 스팸 메일입니다.
499정성태2/16/2016177202016년 작업 PC ^^ [2]
1  [2]  3  4  5  6  7  8  9  10  11  12  13  14  15  ...