Skip to content

Commit 5ffda47

Browse files
committed
[BugFix] fix date parse to adapt dst(day saving time)
[internal]: AutoLand: release/2.11 issue: f-6073082544 [end_internal]
1 parent b397bfe commit 5ffda47

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
@@ -41280,7 +41280,7 @@ QJS_STATIC LEPUSValue js___date_clock(LEPUSContext *ctx,
4128041280

4128141281
/* OS dependent. d = argv[0] is in ms from 1970. Return the difference
4128241282
between local time and UTC time 'd' in minutes */
41283-
int getTimezoneOffset(int64_t time) {
41283+
int getTimezoneOffset(int64_t time, int dst_mode) {
4128441284
#if defined(_WIN32)
4128541285
TIME_ZONE_INFORMATION tzi;
4128641286
memset(&tzi, 0, sizeof(tzi));
@@ -41322,7 +41322,14 @@ int getTimezoneOffset(int64_t time) {
4132241322
}
4132341323
ti = time;
4132441324
localtime_r(&ti, &tm);
41325-
return -tm.tm_gmtoff / 60;
41325+
double ret = -tm.tm_gmtoff / 60;
41326+
// judge timezone for dst
41327+
if (tm.tm_isdst && dst_mode == 2) { // isn't dst in date parse
41328+
ret += 60;
41329+
} else if (!tm.tm_isdst && dst_mode == 1) { // is dst in date parse
41330+
ret -= 60;
41331+
}
41332+
return ret;
4132641333
#endif
4132741334
}
4132841335

@@ -50114,7 +50121,8 @@ QJS_STATIC double time_clip(double t) {
5011450121
return LEPUS_FLOAT64_NAN;
5011550122
}
5011650123

50117-
QJS_STATIC double set_date_fields(double fields[], int is_local) {
50124+
QJS_STATIC double set_date_fields(double fields[], int is_local,
50125+
int dst_mode = 0) {
5011850126
int64_t y;
5011950127
double days, h, m1;
5012050128
volatile double d; /* enforce evaluation order */
@@ -50135,7 +50143,7 @@ QJS_STATIC double set_date_fields(double fields[], int is_local) {
5013550143
h = fields[3] * 3600000 + fields[4] * 60000 + fields[5] * 1000 + fields[6];
5013650144
d = days * 86400000;
5013750145
d += h;
50138-
if (is_local) d += getTimezoneOffset(d) * 60000;
50146+
if (is_local) d += getTimezoneOffset(d, dst_mode) * 60000;
5013950147
return time_clip(d);
5014050148
}
5014150149

@@ -50493,6 +50501,10 @@ QJS_STATIC LEPUSValue js_Date_parse(LEPUSContext *ctx, LEPUSValueConst this_val,
5049350501

5049450502
rv = LEPUS_NAN;
5049550503

50504+
struct tm info {};
50505+
time_t t;
50506+
int dst_mode = 0;
50507+
5049650508
s = JS_ToString_RC(ctx, argv[0]);
5049750509
if (LEPUS_IsException(s)) return LEPUS_EXCEPTION;
5049850510

@@ -50575,7 +50587,15 @@ QJS_STATIC LEPUSValue js_Date_parse(LEPUSContext *ctx, LEPUSValueConst this_val,
5057550587
}
5057650588
}
5057750589
for (i = 0; i < 7; i++) fields1[i] = fields[i];
50578-
d = set_date_fields(fields1, is_local) - tz * 60000;
50590+
info.tm_year = fields[0] - 1900;
50591+
info.tm_mon = fields[1];
50592+
info.tm_mday = fields[2];
50593+
info.tm_hour = fields[3];
50594+
info.tm_min = 0;
50595+
info.tm_isdst = 1;
50596+
t = mktime(&info);
50597+
dst_mode = info.tm_isdst == 1 ? 1 : 2; // 1: dst, 2: no dst
50598+
d = set_date_fields(fields1, is_local, dst_mode) - tz * 60000;
5057950599
rv = __JS_NewFloat64(ctx, d);
5058050600

5058150601
done:

src/interpreter/quickjs/source/quickjs_gc.cc

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27105,7 +27105,7 @@ static double time_clip(double t) {
2710527105
return LEPUS_FLOAT64_NAN;
2710627106
}
2710727107

27108-
static double set_date_fields(double fields[], int is_local) {
27108+
static double set_date_fields(double fields[], int is_local, int dst_mode = 0) {
2710927109
int64_t y;
2711027110
double days, h, m1;
2711127111
volatile double d;
@@ -27126,7 +27126,7 @@ static double set_date_fields(double fields[], int is_local) {
2712627126
h = fields[3] * 3600000 + fields[4] * 60000 + fields[5] * 1000 + fields[6];
2712727127
d = days * 86400000;
2712827128
d += h;
27129-
if (is_local) d += getTimezoneOffset(d) * 60000;
27129+
if (is_local) d += getTimezoneOffset(d, dst_mode) * 60000;
2713027130
return time_clip(d);
2713127131
}
2713227132

@@ -27479,6 +27479,9 @@ static LEPUSValue js_Date_parse(LEPUSContext *ctx, LEPUSValueConst this_val,
2747927479

2748027480
rv = LEPUS_NAN;
2748127481
HandleScope func_scope(ctx, &rv, HANDLE_TYPE_LEPUS_VALUE);
27482+
struct tm info {};
27483+
time_t t;
27484+
int dst_mode = 0;
2748227485

2748327486
s = JS_ToString_GC(ctx, argv[0]);
2748427487
if (LEPUS_IsException(s)) return LEPUS_EXCEPTION;
@@ -27563,7 +27566,15 @@ static LEPUSValue js_Date_parse(LEPUSContext *ctx, LEPUSValueConst this_val,
2756327566
}
2756427567
}
2756527568
for (i = 0; i < 7; i++) fields1[i] = fields[i];
27566-
d = set_date_fields(fields1, is_local) - tz * 60000;
27569+
info.tm_year = fields[0] - 1900;
27570+
info.tm_mon = fields[1];
27571+
info.tm_mday = fields[2];
27572+
info.tm_hour = fields[3];
27573+
info.tm_min = 0;
27574+
info.tm_isdst = 1;
27575+
t = mktime(&info);
27576+
dst_mode = info.tm_isdst == 1 ? 1 : 2; // 1: dst, 2: no dst
27577+
d = set_date_fields(fields1, is_local, dst_mode) - tz * 60000;
2756727578
rv = __JS_NewFloat64(ctx, d);
2756827579

2756927580
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)