@@ -177,8 +177,8 @@ scoped_c_thread_locale::~scoped_c_thread_locale()
177
177
}
178
178
}
179
179
#elif (defined(ANDROID) || defined(__ANDROID__))
180
- scoped_c_thread_locale::scoped_c_thread_locale () {}
181
- scoped_c_thread_locale::~scoped_c_thread_locale () {}
180
+ scoped_c_thread_locale::scoped_c_thread_locale () { }
181
+ scoped_c_thread_locale::~scoped_c_thread_locale () { }
182
182
#else
183
183
scoped_c_thread_locale::scoped_c_thread_locale () : m_prevLocale(nullptr )
184
184
{
@@ -620,7 +620,13 @@ utf16string __cdecl conversions::to_utf16string(const std::string& value) { retu
620
620
621
621
static const int64_t NtToUnixOffsetSeconds = 11644473600 ; // diff between windows and unix epochs (seconds)
622
622
623
- static bool year_is_leap_year (int year) { return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0 )); }
623
+ static bool year_is_leap_year_1601 (int year)
624
+ {
625
+ int decimal_year = year + 1601 ;
626
+ return (decimal_year % 4 == 0 && (decimal_year % 100 != 0 || decimal_year % 400 == 0 ));
627
+ }
628
+
629
+ static bool year_is_leap_year (int year) { return year_is_leap_year_1601 (year + 299 ); }
624
630
625
631
static const int SecondsInMinute = 60 ;
626
632
static const int SecondsInHour = SecondsInMinute * 60 ;
@@ -639,26 +645,27 @@ static const int64_t SecondsFrom1900To2001 = INT64_C(3187296000);
639
645
640
646
static const int64_t NtTo1900OffsetInterval = INT64_C(0x014F373BFDE04000 );
641
647
642
- static int count_leap_years ( const int yearsSince1900 )
648
+ static int count_leap_years_1601 ( int yearsSince1601 )
643
649
{
644
- int tmpYears = yearsSince1900 + 299 ; // shift into 1601, the first 400 year cycle including 1900
645
-
646
- int year400 = tmpYears / 400 ;
647
- tmpYears -= year400 * 400 ;
650
+ int year400 = yearsSince1601 / 400 ;
651
+ yearsSince1601 -= year400 * 400 ;
648
652
int result = year400 * 97 ;
649
653
650
- int year100 = tmpYears / 100 ;
651
- tmpYears -= year100 * 100 ;
654
+ int year100 = yearsSince1601 / 100 ;
655
+ yearsSince1601 -= year100 * 100 ;
652
656
result += year100 * 24 ;
653
657
654
- result += tmpYears / 4 ;
655
-
656
- // subtract off leap years from 1601
657
- result -= 72 ;
658
+ result += yearsSince1601 / 4 ;
658
659
659
660
return result;
660
661
}
661
662
663
+ static int count_leap_years (const int yearsSince1900)
664
+ {
665
+ // shift into 1601, the first 400 year cycle including 1900, then subtract leap years from 1601->1900
666
+ return count_leap_years_1601 (yearsSince1900 + 299 ) - 72 ;
667
+ }
668
+
662
669
// The following table assumes no leap year; leap year is added separately
663
670
static const unsigned short cumulative_days_to_month[12 ] = {
664
671
0 , // Jan
@@ -720,20 +727,16 @@ struct compute_year_result
720
727
int secondsLeftThisYear;
721
728
};
722
729
723
- static const int64_t secondsFrom1601To1900 = INT64_C(9435484800 );
724
-
725
- static compute_year_result compute_year (int64_t secondsSince1900)
730
+ static compute_year_result compute_year_1601 (int64_t secondsSince1601)
726
731
{
727
- int64_t secondsLeft = secondsSince1900 + secondsFrom1601To1900; // shift to start of this 400 year cycle
728
-
729
- int year400 = static_cast <int >(secondsLeft / SecondsIn400Years);
730
- secondsLeft -= year400 * SecondsIn400Years;
732
+ int year400 = static_cast <int >(secondsSince1601 / SecondsIn400Years);
733
+ secondsSince1601 -= year400 * SecondsIn400Years;
731
734
732
- int year100 = static_cast <int >(secondsLeft / SecondsIn100Years);
733
- secondsLeft -= year100 * SecondsIn100Years;
735
+ int year100 = static_cast <int >(secondsSince1601 / SecondsIn100Years);
736
+ secondsSince1601 -= year100 * SecondsIn100Years;
734
737
735
- int year4 = static_cast <int >(secondsLeft / SecondsIn4Years);
736
- int secondsInt = static_cast <int >(secondsLeft - year4 * SecondsIn4Years);
738
+ int year4 = static_cast <int >(secondsSince1601 / SecondsIn4Years);
739
+ int secondsInt = static_cast <int >(secondsSince1601 - year4 * SecondsIn4Years);
737
740
738
741
int year1 = secondsInt / SecondsInYear;
739
742
if (year1 == 4 )
@@ -743,9 +746,16 @@ static compute_year_result compute_year(int64_t secondsSince1900)
743
746
}
744
747
745
748
secondsInt -= year1 * SecondsInYear;
749
+ return {year400 * 400 + year100 * 100 + year4 * 4 + year1, secondsInt};
750
+ }
746
751
747
- // shift back to 1900 base from 1601:
748
- return {year400 * 400 + year100 * 100 + year4 * 4 + year1 - 299 , secondsInt};
752
+ static const int64_t secondsFrom1601To1900 = INT64_C(9435484800 );
753
+ static compute_year_result compute_year (int64_t secondsSince1900)
754
+ {
755
+ // shift to start of this 400 year cycle
756
+ auto partialResult = compute_year_1601 (secondsSince1900 + secondsFrom1601To1900);
757
+ // shift back to 1900
758
+ return {partialResult.year - 299 , partialResult.secondsLeftThisYear };
749
759
}
750
760
751
761
utility::string_t datetime::to_string (date_format format) const
@@ -755,11 +765,11 @@ utility::string_t datetime::to_string(date_format format) const
755
765
throw std::out_of_range (" The requested year exceeds the year 9999." );
756
766
}
757
767
758
- const int64_t epochAdjusted = static_cast <int64_t >(m_interval) - NtTo1900OffsetInterval ;
759
- const int64_t secondsSince1900 = epochAdjusted / _secondTicks; // convert to seconds
760
- const int fracSec = static_cast <int >(epochAdjusted % _secondTicks);
768
+ const int64_t interval = static_cast <int64_t >(m_interval);
769
+ const int64_t secondsSince1601 = interval / _secondTicks; // convert to seconds
770
+ const int fracSec = static_cast <int >(interval % _secondTicks);
761
771
762
- const auto yearData = compute_year (secondsSince1900 );
772
+ const auto yearData = compute_year_1601 (secondsSince1601 );
763
773
const int year = yearData.year ;
764
774
const int yearDay = yearData.secondsLeftThisYear / SecondsInDay;
765
775
int leftover = yearData.secondsLeftThisYear % SecondsInDay;
@@ -768,15 +778,15 @@ utility::string_t datetime::to_string(date_format format) const
768
778
const int minute = leftover / SecondsInMinute;
769
779
leftover = leftover % SecondsInMinute;
770
780
771
- const auto & monthTable = year_is_leap_year (year) ? cumulative_days_to_month_leap : cumulative_days_to_month;
781
+ const auto & monthTable = year_is_leap_year_1601 (year) ? cumulative_days_to_month_leap : cumulative_days_to_month;
772
782
int month = 0 ;
773
783
while (month < 11 && monthTable[month + 1 ] <= yearDay)
774
784
{
775
785
++month;
776
786
}
777
787
778
788
const auto monthDay = yearDay - monthTable[month] + 1 ;
779
- const auto weekday = static_cast <int >((secondsSince1900 / SecondsInDay + 1 ) % 7 );
789
+ const auto weekday = static_cast <int >((secondsSince1601 / SecondsInDay + 1 ) % 7 );
780
790
781
791
char outBuffer[38 ]; // Thu, 01 Jan 1970 00:00:00 GMT\0
782
792
// 1970-01-01T00:00:00.1234567Z\0
@@ -791,7 +801,7 @@ utility::string_t datetime::to_string(date_format format) const
791
801
dayNames + 4 * weekday,
792
802
monthDay,
793
803
monthNames + 4 * month,
794
- year + 1900 ,
804
+ year + 1601 ,
795
805
hour,
796
806
minute,
797
807
leftover);
@@ -801,7 +811,7 @@ utility::string_t datetime::to_string(date_format format) const
801
811
dayNames + 4 * weekday,
802
812
monthDay,
803
813
monthNames + 4 * month,
804
- year + 1900 ,
814
+ year + 1601 ,
805
815
hour,
806
816
minute,
807
817
leftover);
@@ -815,15 +825,15 @@ utility::string_t datetime::to_string(date_format format) const
815
825
sprintf_s (outCursor,
816
826
20 ,
817
827
" %04d-%02d-%02dT%02d:%02d:%02d" ,
818
- year + 1900 ,
828
+ year + 1601 ,
819
829
month + 1 ,
820
830
monthDay,
821
831
hour,
822
832
minute,
823
833
leftover);
824
834
#else // ^^^ _MSC_VER // !_MSC_VER vvv
825
835
sprintf (
826
- outCursor, " %04d-%02d-%02dT%02d:%02d:%02d" , year + 1900 , month + 1 , monthDay, hour, minute, leftover);
836
+ outCursor, " %04d-%02d-%02dT%02d:%02d:%02d" , year + 1601 , month + 1 , monthDay, hour, minute, leftover);
827
837
#endif // _MSC_VER
828
838
outCursor += 19 ;
829
839
if (fracSec != 0 )
0 commit comments