Skip to content

Commit 7c207ea

Browse files
zys777ci_lynx
authored andcommitted
[BugFix] fix date parse to adapt dst(day saving time)
[internal]: AutoLand: release/2.11 issue: f-6073082544 [end_internal]
1 parent 6403183 commit 7c207ea

File tree

4 files changed

+42
-11
lines changed

4 files changed

+42
-11
lines changed

src/interpreter/quickjs/include/quickjs-inner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2696,7 +2696,7 @@ QJS_HIDE LEPUSValue js_closure2(LEPUSContext *ctx, LEPUSValue func_obj,
26962696
QJS_HIDE void js_random_init(LEPUSContext *ctx);
26972697
QJS_HIDE LEPUSValue js_math_random(LEPUSContext *ctx, LEPUSValueConst this_val,
26982698
int argc, LEPUSValueConst *argv);
2699-
QJS_HIDE int getTimezoneOffset(int64_t time);
2699+
QJS_HIDE int getTimezoneOffset(int64_t time, int dst_mode = 0);
27002700
QJS_HIDE int JS_SetPrototypeInternal_GC(LEPUSContext *ctx, LEPUSValueConst obj,
27012701
LEPUSValueConst proto_val,
27022702
BOOL throw_flag);

src/interpreter/quickjs/source/quickjs.cc

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41275,7 +41275,7 @@ QJS_STATIC LEPUSValue js___date_clock(LEPUSContext *ctx,
4127541275

4127641276
/* OS dependent. d = argv[0] is in ms from 1970. Return the difference
4127741277
between local time and UTC time 'd' in minutes */
41278-
int getTimezoneOffset(int64_t time) {
41278+
int getTimezoneOffset(int64_t time, int dst_mode) {
4127941279
#if defined(_WIN32)
4128041280
TIME_ZONE_INFORMATION tzi;
4128141281
memset(&tzi, 0, sizeof(tzi));
@@ -41317,7 +41317,14 @@ int getTimezoneOffset(int64_t time) {
4131741317
}
4131841318
ti = time;
4131941319
localtime_r(&ti, &tm);
41320-
return -tm.tm_gmtoff / 60;
41320+
double ret = -tm.tm_gmtoff / 60;
41321+
// judge timezone for dst
41322+
if (tm.tm_isdst && dst_mode == 2) { // isn't dst in date parse
41323+
ret += 60;
41324+
} else if (!tm.tm_isdst && dst_mode == 1) { // is dst in date parse
41325+
ret -= 60;
41326+
}
41327+
return ret;
4132141328
#endif
4132241329
}
4132341330

@@ -50109,7 +50116,8 @@ QJS_STATIC double time_clip(double t) {
5010950116
return LEPUS_FLOAT64_NAN;
5011050117
}
5011150118

50112-
QJS_STATIC double set_date_fields(double fields[], int is_local) {
50119+
QJS_STATIC double set_date_fields(double fields[], int is_local,
50120+
int dst_mode = 0) {
5011350121
int64_t y;
5011450122
double days, h, m1;
5011550123
volatile double d; /* enforce evaluation order */
@@ -50130,7 +50138,7 @@ QJS_STATIC double set_date_fields(double fields[], int is_local) {
5013050138
h = fields[3] * 3600000 + fields[4] * 60000 + fields[5] * 1000 + fields[6];
5013150139
d = days * 86400000;
5013250140
d += h;
50133-
if (is_local) d += getTimezoneOffset(d) * 60000;
50141+
if (is_local) d += getTimezoneOffset(d, dst_mode) * 60000;
5013450142
return time_clip(d);
5013550143
}
5013650144

@@ -50488,6 +50496,10 @@ QJS_STATIC LEPUSValue js_Date_parse(LEPUSContext *ctx, LEPUSValueConst this_val,
5048850496

5048950497
rv = LEPUS_NAN;
5049050498

50499+
struct tm info {};
50500+
time_t t;
50501+
int dst_mode = 0;
50502+
5049150503
s = JS_ToString_RC(ctx, argv[0]);
5049250504
if (LEPUS_IsException(s)) return LEPUS_EXCEPTION;
5049350505

@@ -50570,7 +50582,15 @@ QJS_STATIC LEPUSValue js_Date_parse(LEPUSContext *ctx, LEPUSValueConst this_val,
5057050582
}
5057150583
}
5057250584
for (i = 0; i < 7; i++) fields1[i] = fields[i];
50573-
d = set_date_fields(fields1, is_local) - tz * 60000;
50585+
info.tm_year = fields[0] - 1900;
50586+
info.tm_mon = fields[1];
50587+
info.tm_mday = fields[2];
50588+
info.tm_hour = fields[3];
50589+
info.tm_min = 0;
50590+
info.tm_isdst = 1;
50591+
t = mktime(&info);
50592+
dst_mode = info.tm_isdst == 1 ? 1 : 2; // 1: dst, 2: no dst
50593+
d = set_date_fields(fields1, is_local, dst_mode) - tz * 60000;
5057450594
rv = __JS_NewFloat64(ctx, d);
5057550595

5057650596
done:

src/interpreter/quickjs/source/quickjs_gc.cc

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27102,7 +27102,7 @@ static double time_clip(double t) {
2710227102
return LEPUS_FLOAT64_NAN;
2710327103
}
2710427104

27105-
static double set_date_fields(double fields[], int is_local) {
27105+
static double set_date_fields(double fields[], int is_local, int dst_mode = 0) {
2710627106
int64_t y;
2710727107
double days, h, m1;
2710827108
volatile double d;
@@ -27123,7 +27123,7 @@ static double set_date_fields(double fields[], int is_local) {
2712327123
h = fields[3] * 3600000 + fields[4] * 60000 + fields[5] * 1000 + fields[6];
2712427124
d = days * 86400000;
2712527125
d += h;
27126-
if (is_local) d += getTimezoneOffset(d) * 60000;
27126+
if (is_local) d += getTimezoneOffset(d, dst_mode) * 60000;
2712727127
return time_clip(d);
2712827128
}
2712927129

@@ -27476,6 +27476,9 @@ static LEPUSValue js_Date_parse(LEPUSContext *ctx, LEPUSValueConst this_val,
2747627476

2747727477
rv = LEPUS_NAN;
2747827478
HandleScope func_scope(ctx, &rv, HANDLE_TYPE_LEPUS_VALUE);
27479+
struct tm info {};
27480+
time_t t;
27481+
int dst_mode = 0;
2747927482

2748027483
s = JS_ToString_GC(ctx, argv[0]);
2748127484
if (LEPUS_IsException(s)) return LEPUS_EXCEPTION;
@@ -27560,7 +27563,15 @@ static LEPUSValue js_Date_parse(LEPUSContext *ctx, LEPUSValueConst this_val,
2756027563
}
2756127564
}
2756227565
for (i = 0; i < 7; i++) fields1[i] = fields[i];
27563-
d = set_date_fields(fields1, is_local) - tz * 60000;
27566+
info.tm_year = fields[0] - 1900;
27567+
info.tm_mon = fields[1];
27568+
info.tm_mday = fields[2];
27569+
info.tm_hour = fields[3];
27570+
info.tm_min = 0;
27571+
info.tm_isdst = 1;
27572+
t = mktime(&info);
27573+
dst_mode = info.tm_isdst == 1 ? 1 : 2; // 1: dst, 2: no dst
27574+
d = set_date_fields(fields1, is_local, dst_mode) - tz * 60000;
2756427575
rv = __JS_NewFloat64(ctx, d);
2756527576

2756627577
done:

testing/quickjs/compiler/test_common.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ extern "C" {
2222
#endif
2323

2424
int32_t typed_array_is_detached(LEPUSContext*, LEPUSObject*);
25-
double set_date_fields(double[], int);
25+
double set_date_fields(double[], int, int);
2626

2727
namespace common_qjs_test {
2828
LEPUSValue js_deep_copy(LEPUSContext* ctx, LEPUSValueConst this_val, int argc,
@@ -1239,7 +1239,7 @@ TEST_F(CommonQjsTest, TypedArraySliceMemOverlap) {
12391239

12401240
TEST_F(CommonQjsTest, TestDateUtc) {
12411241
double fields[] = {1970, 0, 213503982336, 0, 0, 0, -18446744073709552000.0};
1242-
auto ret = set_date_fields(fields, 0);
1242+
auto ret = set_date_fields(fields, 0, 0);
12431243
ASSERT_EQ(ret, 34447360);
12441244
}
12451245

0 commit comments

Comments
 (0)