// // Copyright (c) 1993-2022 Robert McNeel & Associates. All rights reserved. // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert // McNeel & Associates. // // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF // MERCHANTABILITY ARE HEREBY DISCLAIMED. // // For complete openNURBS copyright information see . // //////////////////////////////////////////////////////////////// #include "opennurbs.h" #if !defined(ON_COMPILING_OPENNURBS) // This check is included in all opennurbs source .c and .cpp files to insure // ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled. // When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined // and the opennurbs .h files alter what is declared and how it is declared. #error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs #endif // 1582 was the first Gregorian year. See http://en.wikipedia.org/wiki/Gregorian_calendar #define FIRST_GREGORIAN_YEAR 1582 bool ON_IsGregorianLeapYear( unsigned int year ) { // According to http://en.wikipedia.org/wiki/Gregorian_calendar, // the Gregorian calendar was introduced 24, February 1582, in // the Papal States, Spain, Portugal, the Polish-Lithuanian // Commonwealth, and most of Italy. However the Julian leap // day was omitted for the first 10 occurances to correct // for the "vernal equinox drift" the Julian calendar had // introduced from AD 325 to 1582. The goal was to have // March 21 be the date of the vernal equinox. // As a result, the first Gregorian calendary leap day // leap day in the Gregorian calendar occured on Feb 29, 1624. return ( year >= 1624 && 0 == (year %4) && (0 == (year%400) || 0 != (year%100)) ); } unsigned int ON_DaysInGregorianYear( unsigned int year ) { return (year >= FIRST_GREGORIAN_YEAR) ? (ON_IsGregorianLeapYear(year) ? 366 : 365) : 0; } static const unsigned int* CommonYearDayCount() { static const unsigned int common_year_day_count[13] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; return common_year_day_count; } static const unsigned int* LeapYearDayCount() { static const unsigned int leap_year_day_count[13] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}; return leap_year_day_count; } static const unsigned int* YearDayCount(unsigned int year) { return ON_IsGregorianLeapYear(year) ? LeapYearDayCount() : CommonYearDayCount(); } unsigned int ON_DaysInMonthOfGregorianYear( unsigned int year, unsigned int month ) { unsigned int days_in_month = 0; if( year >= FIRST_GREGORIAN_YEAR && month >= 1 && month <= 12) { const unsigned int* year_day_count = YearDayCount(year); days_in_month = year_day_count[month] - year_day_count[month-1]; } return days_in_month; } unsigned int ON_DayOfGregorianYear( unsigned int year, unsigned int month, unsigned int date ) { unsigned int day_of_year = 0; if( year >= FIRST_GREGORIAN_YEAR && month >= 1 && month <= 12 && date >= 1 && date <= 31 ) { const unsigned int* year_day_count = YearDayCount(year); day_of_year = year_day_count[month-1] + date; if ( day_of_year > year_day_count[month] ) day_of_year = 0; // input date value too large } return day_of_year; } bool ON_GetGregorianMonthAndDayOfMonth( unsigned int year, unsigned int day_of_year, unsigned int* month, unsigned int* date ) { unsigned int mm = 0; unsigned int dd = 0; if( year >= FIRST_GREGORIAN_YEAR ) { const unsigned int* year_day_count = YearDayCount(year); for ( mm = 1; mm <= 12; mm++ ) { if ( day_of_year <= year_day_count[mm] ) { dd = day_of_year - year_day_count[mm-1]; break; } } if ( 0 == dd ) mm = dd; } if ( 0 != month ) *month = mm; if ( 0 != date ) *date = dd; return (0 != dd); }