디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

수천억년을 초 단위로 표현가능한 날짜 타입

mozzart갤로그로 이동합니다. 2016.05.22 08:18:28
조회 2856 추천 18 댓글 30
														


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b38577a16fb3dab004c86b6fb8c469a51a456a5782032fed780bd3a47f47c6526366d52631d19a6150c3966ac4ad0d72ce89bc7533fa462576


viewimage.php?id=3dafdf21f7d335ab67b1d1&no=29bcc427b38577a16fb3dab004c86b6fb8c469a51a456a5782032fed780bd3a47f47c6526366d52631d19a6150c3966ac4fe5a26ca8eef7260fa462576


#include <iostream>

#include <string>


#define CSTR


using   i8                      = char;

using   u8                      = unsigned char;

using   i16                     = short;

using   u16                     = unsigned short;

using   i32                     = int;

using   u32                     = unsigned int;

using   i64                     = long long;

using   u64                     = unsigned long long;


using   f32                     = float;

using   f64                     = double;


#define rigid                   constexpr


//---------------------------------------------------------------------------------------


rigid   u32 CHAR_BITS           = 8;


template< typename T >

inline  rigid   auto    msb()

{

    return  sizeof( T ) * CHAR_BITS - 1;

}


template< typename T >

inline  rigid   auto    msb_value()

{

    return  (T)1 << msb< T >();

}


#define msb_pos( var ) msb< decltype( var ) >()

#define msb_val( var ) msb_value< decltype( var ) >()


template< typename T0, typename T1 >

inline  void    set_msbs( T0& dst, const T1 bits )

{

    *( (T1*)&dst + ( sizeof dst / sizeof bits - 1 ) ) |= bits;

}

//---------------------------------------------------------------------------------------


template< typename TR >

inline  TR      atou( char*& s )

{

    TR value;

    for( value = 0; *s <= '9' && *s >= '0'; ++s )

        value = value * 10 + ( *s & 0xF );

    return  value;

}


template< typename TR >

inline  TR      atoi( char*& s )

{

    if( *s == '-' )

        return  (TR)( -1 * atou< TR >( ++s ) );

    return  (TR)atou< TR >( s );

}


#include <cmath>

template< typename T = f64 >

inline  T       atof( char*& s )

{

    char* p = s;

    u32 sign = 0;

    T   digit = 0.;

    T   base = 1.;

    T   step = 1.;


    for( i8 token; token = *p++; )

    {

        switch( token )

        {

        case '-':

            sign = msb_val( sign );

            break;

        case '.':

            step = 10;

            break;

        case 'E':

        case 'e':

            digit *= (T)std::pow( 10., (f64)atof< T >( s = p ) );

            goto exit;

        default:

            if( token <= '9' && token >= '0' )

            {

                digit = digit * 10 + ( token & 0xF );

                base *= step;

                continue;

            }

            goto exit;

        }

    }

exit:

    if( s < p - 1 ) s = p - 1;

    set_msbs( digit, sign );

    return  T( digit / base );

}

//---------------------------------------------------------------------------------------


#include <stdarg.h>


template< const u32 MAX_SIZE = 1024 >

inline  std::string     format_string( const char* format, ... )

{

    char    temp[ MAX_SIZE ];

    va_list va;

    va_start( va, format );

    vsprintf( temp, format, va );

    va_end( va );

    return  temp;

//---------------------------------------------------------------------------------------


#include <type_traits>


template< typename T >

inline  rigid   auto    is_signed_()

{

    return  std::is_same< T, i8  >::value || std::is_same< T, i16 >::value ||

            std::is_same< T, i32 >::value || std::is_same< T, i64 >::value;

}


template< typename T >

inline  rigid   auto    is_unsigned_()

{

    return  std::is_same< T, u8  >::value || std::is_same< T, u16 >::value ||

            std::is_same< T, u32 >::value || std::is_same< T, u64 >::value;

}


template< typename T >

inline  rigid   auto    is_floating_()

{

    return  std::is_same< T, f32 >::value || std::is_same< T, f64 >::value;

}


template< typename T >

inline  char*   parse_number( const char* string, T& param )

{

    char* s = (char*)string;

    while( *s <= ' ' || *s == '/' || *s == ':' ) s++;


    if( is_signed_< T >() )

    {

        param = atoi< T >( s );

    }

    else if( is_unsigned_< T >() )

    {

        param = atou< T >( s );

    }

    else if( is_floating_< T >() )

    { 

        param = atof< T >( s );

    }

    return  s;

}


template< typename T, typename... Ts >

inline  char*   parse_number( const char* string, T& param1, Ts&... rest )

{

    return  parse_number( parse_number( string, param1 ), rest... );

}

//---------------------------------------------------------------------------------------


rigid   i32  msecs_in_1sec      = 1000;

rigid   i32   secs_in_1min      = 60;

rigid   i32   mins_in_1hour     = 60;

rigid   i32  hours_in_1day      = 24;

rigid   i32   secs_in_1hour     = mins_in_1hour     * secs_in_1min;

rigid   i32   mins_in_1day      = hours_in_1day     * mins_in_1hour;

rigid   i32   secs_in_1day      = mins_in_1day      * secs_in_1min;

rigid   i32  msecs_in_1day      = secs_in_1day      * msecs_in_1sec;

rigid   i32  value_of_1day      = secs_in_1day;


rigid   i32   days_in_1year     = 365;

rigid   i32   days_in_4years    = days_in_1year     * 4  + 1;

rigid   i32   days_in_100years  = days_in_4years    * 25 - 1;

rigid   i32   days_in_400years  = days_in_100years  * 4  + 1;

rigid   i32   secs_in_1year     = days_in_1year     * secs_in_1day;

                                  

rigid   i64  years_in_bc        = 100000000000LL;

rigid   i64   days_in_bc        = years_in_bc / 400 * days_in_400years;

rigid   i64   secs_in_bc        = days_in_bc        * secs_in_1day;

rigid   i64   days_in_bc_greg   = days_in_400years  * years_in_bc / 400;

rigid   i64   days_in_bc_juli   = days_in_4years    * years_in_bc / 4;

rigid   i64   juli_to_greg      = days_in_bc_greg   - days_in_bc_juli - 2;


rigid   i32 final_day_fragment  = (u64)-1 - (u64)-1 / value_of_1day * value_of_1day;


rigid   u32 sum_days100[ 4 ][ 14 ]

{

    { 0,    0,   31,   59,   90,  120,  151,  181,  212,  243,  273,  304,  334,  365, },

    { 0,  365,  396,  424,  455,  485,  516,  546,  577,  608,  638,  669,  699,  730, },

    { 0,  730,  761,  789,  820,  850,  881,  911,  942,  973, 1003, 1034, 1064, 1095, },

    { 0, 1095, 1126, 1154, 1185, 1215, 1246, 1276, 1307, 1338, 1368, 1399, 1429, 1460, },

};


rigid   u32 sum_days[ 4 ][ 14 ]

{

    { 0,    0,   31,   59,   90,  120,  151,  181,  212,  243,  273,  304,  334,  365, },

    { 0,  365,  396,  424,  455,  485,  516,  546,  577,  608,  638,  669,  699,  730, },

    { 0,  730,  761,  789,  820,  850,  881,  911,  942,  973, 1003, 1034, 1064, 1095, },

    { 0, 1095, 1126, 1155, 1186, 1216, 1247, 1277, 1308, 1339, 1369, 1400, 1430, 1461, },

};


const   char*   day_names[]

{

    "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",

};

//---------------------------------------------------------------------------------------


template< typename T0, typename T1, typename T2 >

inline  auto                    times( const T0 hours, const T1 mins, const T2 secs )

{

    return  hours * secs_in_1hour + mins * secs_in_1min + secs;

}


template< typename T >

inline  u64                     days( const T days )

{

    return  days * secs_in_1day;

}


inline  u64                     seconds( const u64 secs )

{

    return  secs;

}

///--------------------------------------------------------------------------------------


enum    class                   DATE_METHOD

{

    julian,

    gregorian,

};


template< DATE_METHOD method =  DATE_METHOD::gregorian >

class   DATE_

{

private:

    u64                         secs;


    void                        date_parsing( const char* date_string )

    {

        i64     year;

        u32     month, day;

        parse_number( date_string, year, month, day );

        encode( year, month, day );

    }


public:

    CSTR                        DATE_() : secs( 0 )

    {}

    CSTR    explicit            DATE_( const u64 secs ) : secs( secs )

    {}

    CSTR                        DATE_( const i64 year, const u32 mm, const u32 dd )

    {

        encode( year, mm, dd );

    }

    CSTR                        DATE_( const i64 year, const u32 mm, const u32 dd,

                                       const u32 hh, const u32 nn, const u32 ss )

    {

        encode( year, mm, dd );

        secs += times( hh, nn, ss );

    }


    CSTR    explicit            DATE_( const char* date_string )

    {

        date_parsing( date_string );

    }

    CSTR    explicit            DATE_( const std::string date_string )

    {

        date_parsing( date_string.c_str() );

    }


    void                        encode( const i64 year, const u32 month, const u32 day )

    {

        u64     xx  = year + years_in_bc - ( year > 0 );

        if( method == DATE_METHOD::gregorian )

        {

            secs    = xx / 400 * days_in_400years;

            u32 x2  = xx % 400;


            u32 y1  = x2 / 100 * days_in_100years;

            u32 x1  = x2 % 100;


            u32 y0  = x1 / 4 * days_in_4years;

            u32 x0  = x1 % 4;


            auto s  = sum_days[ x0 ];

            if( x2 != 399 && x1 == 99 )

                 s  = sum_days100[ x0 ];


            secs   += y1 + y0 + s[ month ] + day - 1;

        }

        else

        {

            secs    = xx / 4 * days_in_4years +

                      ( sum_days[ xx % 4 ][ month ] + day + ( juli_to_greg - 1 ) );

        }

        secs       *= value_of_1day;

    }


    void                        decode( i64& year, u32& month, u32& day ) const

    {

        u64     xx  = secs / value_of_1day;

        u32     x, y;

        year        = -years_in_bc;

        auto    s   = sum_days;

        if( method == DATE_METHOD::gregorian )

        {

            year   += xx / days_in_400years * 400;

            u32 x2  = xx % days_in_400years;


            u32 y1  = x2 / days_in_100years - x2 / ( days_in_100years * 4 );

            u32 x1  = x2 - days_in_100years * y1;

                y1  = y1 * 100;


            u32 y0  = x1 / days_in_4years * 4;

            x       = x1 % days_in_4years;


            y       = x / days_in_1year - x / ( days_in_1year * 4 );


            if( y1 < 300 && y0 + y == 99  )

                s   = sum_days100;


            year   += y1 + y0 + y;

        }

        else

        {

            xx     -= juli_to_greg;


            u64 y0  = xx / days_in_4years * 4;

            x       = xx % days_in_4years;


            y       = x / days_in_1year - x / ( days_in_1year * 4 );


            year   += y0 + y;

        }


        month       = ( x - y * days_in_1year ) / 29;

        month      += x >= s[ y ][ month + 1 ];

        day         = x - s[ y ][ month ] + 1;

        year       += year >= 0;

    }

    ///----------------------------------------------------------------------------------


    const   auto                name() const

    {

        return  day_names[ secs / value_of_1day % 7 ];

    }


    const   auto                date( bool ad_bc = false ) const

    {

        i64     year;

        u32     month, day;

        decode( year, month, day );

        if( !ad_bc )

            return  format_string( "%lld/u/u", year, month, day );

        else

            return  format_string( "%s.%llu/u/u", year > 0 ? "AD" : "BC",

                    std::abs( year ), month, day );

    }


    const   auto                time( bool am_pm = false ) const

    {

        u32     hh, mm, ss;

        ss      = time_seconds();

        hh      = ss / secs_in_1hour;

        ss      = ss % secs_in_1hour;

        mm      = ss / secs_in_1min;

        ss      = ss % secs_in_1min;

        return  format_string( "u:u:u", hh, mm, ss ) +

                ( am_pm ? ( hh < 12 ? " am" : " pm" ) : "" );

    }


    const   auto                date_time() const

    {

        return  date() + " " + time();

    }


    const   auto                long_date() const

    {

        return  std::string( method == DATE_METHOD::gregorian ? "G:" : "J:" ) +

            date( true ) + " " + name();

    }


    const   auto                long_date_time() const

    {

        return  long_date() + " " + time( true );

    }

    ///----------------------------------------------------------------------------------


    const   auto                seconds() const

    {

        return  secs;

    }


    const   u32                 time_seconds() const

    {

        return  secs % secs_in_1day;

    }


    const   auto                days() const

    {

        return  secs / secs_in_1day;

    }

    ///----------------------------------------------------------------------------------


    auto&                       operator-=( const DATE_& rhs )

    {

        return  secs -= rhs.secs, *this;

    }


    auto&                       operator+=( const DATE_& rhs )

    {

        return  secs += rhs.secs, *this;

    }


    template< DATE_METHOD M >

    const   auto                operator-( const DATE_< M >& rhs ) const

    {

        return  DATE_< method >( secs - rhs.seconds() );

    }


    template< DATE_METHOD M >

    const   auto                operator+( const DATE_< M >& rhs ) const

    {

        return  DATE_< method >( secs + rhs.seconds() );

    }


    const   auto                operator-( const u64 duration ) const

    {

        return  DATE_< method >( secs - duration );

    }


    const   auto                operator+( const u64 duration ) const

    {

        return  DATE_< method >( secs + duration );

    }


    auto&                       operator-=( const u64 duration )

    {

        return  secs -= duration, *this;

    }


    auto&                       operator+=( const u64 duration )

    {

        return  secs += duration, *this;

    }


    auto&                       operator--()

    {

        return  *this -= secs_in_1day;

    }


    auto&                       operator++()

    {

        return  *this += secs_in_1day;

    }


    const   bool                operator<( const DATE_& rhs ) const

    {

        return  secs < rhs.secs;

    }


    friend  std::ostream&       operator<<( std::ostream& os, const DATE_& date )

    {

        return  os << date.long_date_time();

    }

};

//---------------------------------------------------------------------------------------


using   DATE  = DATE_< DATE_METHOD::gregorian >;

using   DATEJ = DATE_< DATE_METHOD::julian >;


inline  auto    historical_date( const DATE gregorian_date )

{

    const   auto    julian_to_gregorian_date = DATE( 1582,10,15 );

    if( gregorian_date < julian_to_gregorian_date )

        return  DATEJ( gregorian_date.seconds() ).long_date();

    return  gregorian_date.long_date();

}

//---------------------------------------------------------------------------------------


율리우스력 ~ 그레고리력으로 넘어가는 경계 ( 1582년 10월 15일 ) 처리와

클래스 공용형태에 주목.


enum    class                   DATE_METHOD

{

    julian,

    gregorian,

};


template< DATE_METHOD method =  DATE_METHOD::gregorian >

class   DATE_


최적화는 꽤 해뒀지만, 날짜 출력 포맷은 아직 결정하지 못했음.

좀 찍어보고 고민을 해야 할듯.

꽤 중요한 프로젝트에 사용될 코드고

니들이 워낙 피드백을 주지 않으니 그닥 공개할 생각은 없었는데,

여기까진 괜찮을듯. 만들어둔지 2달쯤 된 코드.


http://ideone.com/B4iuWV

추천 비추천

18

고정닉 0

2

댓글 영역

전체 댓글 0
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 며느리, 사위되면 시댁, 처가에 잘할 것 같은 스타 운영자 25/10/13 - -
공지 프로그래밍 갤러리 이용 안내 [96] 운영자 20.09.28 47976 65
2896727 음기 충전 발명도둑잡기(211.246) 03:10 28 0
2896726 IT 쪽 프리랜서 가능한 직업 뭐 있지 프갤러(67.162) 02:50 22 0
2896725 와 한국인 가술력 개쩐다 ㄷㄷ ㅇㅇ(106.101) 02:20 28 0
2896724 만약에 캄보디아에서 이재용 아들 납치되면 무슨일 벌어짐 ?? [1] ㅇㅇ(223.39) 02:11 40 0
2896721 귀무가설 발명도둑잡기(211.246) 01:07 18 0
2896720 그냥 갑자기 궁금한건데 캄보디아 사람하나 빼내오는게 힘든일임?? [1] ㅇㅇ(223.39) 00:50 28 0
2896718 음악 관련 기술 서비스 10선 발명도둑잡기(211.246) 00:40 18 0
2896717 반대로 생각할 줄 알아야한다. [1] 프갤러(110.8) 00:37 40 0
2896715 번역은 중국모델이 제일 좋음. 이유가 [1] ㅆㅇㅆ(113.192) 00:24 41 0
2896714 요즘 느끼는게 AI 나오고나서 AI번역 쓰니까 좆되지 않냐? [3] ㅆㅇㅆ(113.192) 00:21 53 0
2896713 업계 선배에게는 배울것이 반드시 하나쯤은 있다 [3] 박민준갤로그로 이동합니다. 00:18 55 0
2896710 SSH로 접속 가능한 채팅+BBS 만들었습니다 [3] 파란빤스갤로그로 이동합니다. 10.15 65 0
2896706 美 공화당 MZ 간부들 채팅기록 유출…노예제·히틀러 칭송 발명도둑잡기(211.246) 10.15 27 0
2896705 근데 생각해보면 담배값 존나 비싼거네 ㅇㅅㅇ ㅇㅇ(223.39) 10.15 31 0
2896698 윈도우 ui를 맥이나 태블릿처럼 쫀득쫀득한 느낌나게 바꾸는 법은 없나요 [2] 프갤러(211.192) 10.15 56 0
2896695 리눅스 쓰는 사람 있나요 [9] 프갤러(211.192) 10.15 132 0
2896694 클린 아키텍처말고 [4] 루도그담당(58.239) 10.15 70 0
2896693 근데 확실히 내 이해가 좀 많이 얕노 [2] ㅆㅇㅆ(113.192) 10.15 74 0
2896692 갤러리 존나 기괴하네 [1] 프갤러(106.101) 10.15 72 6
2896691 세상엔 올바른 코드는 없지만 유지보수하기 쉬운 코드는 존재한다 프갤러(61.75) 10.15 29 0
2896690 [해설] 미국 셧다운 장기화, 어디까지 번질까? 발명도둑잡기(211.246) 10.15 16 0
2896689 그냥 타입참조가 밖에서 안으로 흐른다 <<이거 하나로 이해해 [7] ㅆㅇㅆ(113.192) 10.15 84 0
2896687 미제국주의 침략의 도구가 된 노벨평화상 발명도둑잡기(211.246) 10.15 16 0
2896686 도메인 << 워딩 보면 볼수록 병신같음 루도그담당(58.239) 10.15 33 0
2896685 "10·15 부동산 대책, 文 떠올리게 해"…경실련·참여연대도 비판 발명도둑잡기(211.246) 10.15 19 0
2896683 보통 안드로이드 클린 아키텍쳐라는게 대략 이런구조잖아 [5] ㅆㅇㅆ(113.192) 10.15 73 0
2896679 전체 맥락을 이해 못하니 좀 쉽게 설명해줌 [3] ㅆㅇㅆ(113.192) 10.15 63 0
2896678 미래의 여사친한테 텔레파시를 받았다 [1] 발명도둑잡기(211.246) 10.15 28 0
2896676 124.48은 좀 아스퍼거라 이 문맥적인 판단력이 떨어지는거 같음. [1] ㅆㅇㅆ(113.192) 10.15 43 0
2896674 근데 프로그래밍 이야기하다보면 맨날 실없는 소리 밖에 못하게됨 [2] ㅆㅇㅆ(113.192) 10.15 49 0
2896673 최원종 시즌2 예감 발명도둑잡기(211.246) 10.15 62 0
2896672 이 대사가 자토이치 오마주엿넹 ㄷㅅㄷ ♥덩냥이♥갤로그로 이동합니다. 10.15 17 0
2896671 클린 아키텍쳐를 선택하는 건 낮은 비용이라서 그런거임 [4] ㅆㅇㅆ(113.192) 10.15 52 1
2896670 칼집이 없는 칼 같이 날카로운 삶 [1] ♥덩냥이♥갤로그로 이동합니다. 10.15 28 0
2896669 형태에 집착하면 기능을 잃게 됨. 근데 보통 형태에 집착하지 ㅆㅇㅆ(113.192) 10.15 19 0
2896668 가령 프레임워크에 따라서 트랙잭션 모델이 다르고 ㅆㅇㅆ(113.192) 10.15 19 0
2896667 어차피 설계라는게 프레임워크에 따르게 되있어서 어떤 프레임워크 선택하는가 [1] ㅆㅇㅆ(113.192) 10.15 43 1
2896666 와이파이로 휴대폰에 바이러스 심는거 가능? ㅇㅇ(146.70) 10.15 14 0
2896665 자토이치 보구 뭔가 생각이 바겻당 ♥덩냥이♥갤로그로 이동합니다. 10.15 45 0
2896664 기능 구현만 잘하는 개발자인데 더 잘하고 싶어 (조언부탁) [21] 프갤러(112.149) 10.15 107 0
2896660 연락와서 처리중 ㅆㅇㅆ(113.192) 10.15 23 0
2896656 유튜브 ui왜 개병신됨?? 진짜 왜 그러는거임 ㅇㅇ(223.39) 10.15 27 0
2896655 자토이치 ㄹㅇ 존나 머싯따.. 낭만검객.. ♥덩냥이♥갤로그로 이동합니다. 10.15 25 0
2896652 저장용 ♥덩냥이♥갤로그로 이동합니다. 10.15 19 0
2896647 나님 집 주소 인증⭐ [3] ♥덩냥이♥갤로그로 이동합니다. 10.15 54 0
2896646 한국일본이용하는 미국..우린 중러가 필요하다 [1] 발명도둑잡기(211.246) 10.15 36 0
2896645 ❤✨☀⭐⚡☘⛩나님 시작합니당⛩☘⚡⭐☀✨❤ ♥덩냥이♥갤로그로 이동합니다. 10.15 44 0
2896644 김건희 석방 에어로홍갤로그로 이동합니다. 10.15 42 0
2896643 윤석열 석방 에어로홍갤로그로 이동합니다. 10.15 45 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

디시미디어

디시이슈

1/2