Merge pull request #20826 from raphael10241024/mybranch
fix #20390: handle time before year 1970
This commit is contained in:
commit
f33a9db279
2 changed files with 33 additions and 26 deletions
|
@ -658,7 +658,7 @@ Dictionary _OS::get_time(bool utc) const {
|
||||||
*
|
*
|
||||||
* @return epoch calculated
|
* @return epoch calculated
|
||||||
*/
|
*/
|
||||||
uint64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
||||||
|
|
||||||
// Bunch of conversion constants
|
// Bunch of conversion constants
|
||||||
static const unsigned int SECONDS_PER_MINUTE = 60;
|
static const unsigned int SECONDS_PER_MINUTE = 60;
|
||||||
|
@ -703,13 +703,18 @@ uint64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
||||||
// Calculate all the seconds from months past in this year
|
// Calculate all the seconds from months past in this year
|
||||||
uint64_t SECONDS_FROM_MONTHS_PAST_THIS_YEAR = DAYS_PAST_THIS_YEAR_TABLE[LEAPYEAR(year)][month - 1] * SECONDS_PER_DAY;
|
uint64_t SECONDS_FROM_MONTHS_PAST_THIS_YEAR = DAYS_PAST_THIS_YEAR_TABLE[LEAPYEAR(year)][month - 1] * SECONDS_PER_DAY;
|
||||||
|
|
||||||
uint64_t SECONDS_FROM_YEARS_PAST = 0;
|
int64_t SECONDS_FROM_YEARS_PAST = 0;
|
||||||
|
if (year >= EPOCH_YR) {
|
||||||
for (unsigned int iyear = EPOCH_YR; iyear < year; iyear++) {
|
for (unsigned int iyear = EPOCH_YR; iyear < year; iyear++) {
|
||||||
|
|
||||||
SECONDS_FROM_YEARS_PAST += YEARSIZE(iyear) * SECONDS_PER_DAY;
|
SECONDS_FROM_YEARS_PAST += YEARSIZE(iyear) * SECONDS_PER_DAY;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (unsigned int iyear = EPOCH_YR - 1; iyear >= year; iyear--) {
|
||||||
|
SECONDS_FROM_YEARS_PAST -= YEARSIZE(iyear) * SECONDS_PER_DAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t epoch =
|
int64_t epoch =
|
||||||
second +
|
second +
|
||||||
minute * SECONDS_PER_MINUTE +
|
minute * SECONDS_PER_MINUTE +
|
||||||
hour * SECONDS_PER_HOUR +
|
hour * SECONDS_PER_HOUR +
|
||||||
|
@ -732,34 +737,36 @@ uint64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
||||||
*
|
*
|
||||||
* @return dictionary of date and time values
|
* @return dictionary of date and time values
|
||||||
*/
|
*/
|
||||||
Dictionary _OS::get_datetime_from_unix_time(uint64_t unix_time_val) const {
|
Dictionary _OS::get_datetime_from_unix_time(int64_t unix_time_val) const {
|
||||||
|
|
||||||
// Just fail if unix time is negative (when interpreted as an int).
|
|
||||||
// This means the user passed in a negative value by accident
|
|
||||||
ERR_EXPLAIN("unix_time_val was really huge!" + itos(unix_time_val) + " You probably passed in a negative value!");
|
|
||||||
ERR_FAIL_COND_V((int64_t)unix_time_val < 0, Dictionary());
|
|
||||||
|
|
||||||
OS::Date date;
|
OS::Date date;
|
||||||
OS::Time time;
|
OS::Time time;
|
||||||
|
|
||||||
unsigned long dayclock, dayno;
|
long dayclock, dayno;
|
||||||
int year = EPOCH_YR;
|
int year = EPOCH_YR;
|
||||||
|
|
||||||
dayclock = (unsigned long)unix_time_val % SECS_DAY;
|
if (unix_time_val >= 0) {
|
||||||
dayno = (unsigned long)unix_time_val / SECS_DAY;
|
dayno = unix_time_val / SECS_DAY;
|
||||||
|
dayclock = unix_time_val % SECS_DAY;
|
||||||
time.sec = dayclock % 60;
|
|
||||||
time.min = (dayclock % 3600) / 60;
|
|
||||||
time.hour = dayclock / 3600;
|
|
||||||
|
|
||||||
/* day 0 was a thursday */
|
/* day 0 was a thursday */
|
||||||
date.weekday = static_cast<OS::Weekday>((dayno + 4) % 7);
|
date.weekday = static_cast<OS::Weekday>((dayno + 4) % 7);
|
||||||
|
|
||||||
while (dayno >= YEARSIZE(year)) {
|
while (dayno >= YEARSIZE(year)) {
|
||||||
dayno -= YEARSIZE(year);
|
dayno -= YEARSIZE(year);
|
||||||
year++;
|
year++;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dayno = (unix_time_val - SECS_DAY + 1) / SECS_DAY;
|
||||||
|
dayclock = unix_time_val - dayno * SECS_DAY;
|
||||||
|
date.weekday = static_cast<OS::Weekday>((dayno - 3) % 7 + 7);
|
||||||
|
do {
|
||||||
|
year--;
|
||||||
|
dayno += YEARSIZE(year);
|
||||||
|
} while (dayno < 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
time.sec = dayclock % 60;
|
||||||
|
time.min = (dayclock % 3600) / 60;
|
||||||
|
time.hour = dayclock / 3600;
|
||||||
date.year = year;
|
date.year = year;
|
||||||
|
|
||||||
size_t imonth = 0;
|
size_t imonth = 0;
|
||||||
|
|
|
@ -270,8 +270,8 @@ public:
|
||||||
Dictionary get_date(bool utc) const;
|
Dictionary get_date(bool utc) const;
|
||||||
Dictionary get_time(bool utc) const;
|
Dictionary get_time(bool utc) const;
|
||||||
Dictionary get_datetime(bool utc) const;
|
Dictionary get_datetime(bool utc) const;
|
||||||
Dictionary get_datetime_from_unix_time(uint64_t unix_time_val) const;
|
Dictionary get_datetime_from_unix_time(int64_t unix_time_val) const;
|
||||||
uint64_t get_unix_time_from_datetime(Dictionary datetime) const;
|
int64_t get_unix_time_from_datetime(Dictionary datetime) const;
|
||||||
Dictionary get_time_zone_info() const;
|
Dictionary get_time_zone_info() const;
|
||||||
uint64_t get_unix_time() const;
|
uint64_t get_unix_time() const;
|
||||||
uint64_t get_system_time_secs() const;
|
uint64_t get_system_time_secs() const;
|
||||||
|
|
Loading…
Reference in a new issue