浏览代码

JSON: Better date handling in the internal libc

Lukas M 5 年之前
父节点
当前提交
a7c976188b
共有 2 个文件被更改,包括 89 次插入0 次删除
  1. 86 0
      deps/libc_time.c
  2. 3 0
      deps/libc_time.h

+ 86 - 0
deps/libc_time.c

@@ -81,3 +81,89 @@ int __secs_to_tm(long long t, struct mytm *tm) {
 
     return 0;
 }
+
+int __month_to_secs(int month, int is_leap)
+{
+	static const int secs_through_month[] = {
+		0, 31*86400, 59*86400, 90*86400,
+		120*86400, 151*86400, 181*86400, 212*86400,
+		243*86400, 273*86400, 304*86400, 334*86400 };
+	int t = secs_through_month[month];
+	if (is_leap && month >= 2) t+=86400;
+	return t;
+}
+
+long long __year_to_secs(long long year, int *is_leap)
+{
+	if (year-(int)2ULL <= 136) {
+		int y = (int)year;
+		int leaps = (y-68)>>2;
+		if (!((y-68)&3)) {
+			leaps--;
+			if (is_leap) *is_leap = 1;
+		} else if (is_leap) *is_leap = 0;
+		return 31536000*(y-70) + 86400*leaps;
+	}
+
+	int cycles, centuries, leaps, rem;
+
+        //if (!is_leap) is_leap = &(int){0};
+        int is_leap_val = 0;
+	if (!is_leap){
+            is_leap = &is_leap_val;
+        }
+	cycles = (int)((year-100) / 400);
+	rem = (int)((year-100) % 400);
+	if (rem < 0) {
+		cycles--;
+		rem += 400;
+	}
+	if (!rem) {
+		*is_leap = 1;
+		centuries = 0;
+		leaps = 0;
+	} else {
+		if (rem >= 200) {
+			if (rem >= 300) centuries = 3, rem -= 300;
+			else centuries = 2, rem -= 200;
+		} else {
+			if (rem >= 100) centuries = 1, rem -= 100;
+			else centuries = 0;
+		}
+		if (!rem) {
+			*is_leap = 0;
+			leaps = 0;
+		} else {
+			leaps = (rem / (int)4U);
+			rem %= (int)4U;
+			*is_leap = !rem;
+		}
+	}
+
+	leaps += 97*cycles + 24*centuries - *is_leap;
+
+	return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
+}
+
+long long __tm_to_secs(const struct mytm *tm)
+{
+	int is_leap;
+	long long year = tm->tm_year;
+	int month = tm->tm_mon;
+	if (month >= 12 || month < 0) {
+		int adj = month / 12;
+		month %= 12;
+		if (month < 0) {
+			adj--;
+			month += 12;
+		}
+		year += adj;
+	}
+	long long t = __year_to_secs(year, &is_leap);
+	t += __month_to_secs(month, is_leap);
+	t += 86400LL * (tm->tm_mday-1);
+	t += 3600LL * tm->tm_hour;
+	t += 60LL * tm->tm_min;
+	t += tm->tm_sec;
+	return t;
+}

+ 3 - 0
deps/libc_time.h

@@ -16,5 +16,8 @@ struct mytm {
 };
 
 int __secs_to_tm(long long t, struct mytm *tm);
+int __month_to_secs(int month, int is_leap);
+long long __year_to_secs(long long year, int *is_leap);
+long long __tm_to_secs(const struct mytm *tm);
 
 #endif /* LIBC_TIME_H_ */