* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/platform/time.h"
#include <timezoneapi.h>
#include <ctime>
#include <windows.h>
namespace panda::ecmascript {
static constexpr int MS_PER_SECOND = 1000;
static constexpr int MS_PER_MINUTE = 60000;
static constexpr int HOUR_PER_DAY = 24;
static constexpr int MINUTE_PER_DAY = 24 * 60;
static constexpr int SECOND_PER_DAY = 24 * 60 * 60;
static constexpr int MS_PER_DAY = SECOND_PER_DAY * MS_PER_SECOND;
int64_t GetLocalOffsetFromOS([[maybe_unused]] int64_t timeMs, bool isLocal)
{
if (!isLocal) {
return 0;
}
TIME_ZONE_INFORMATION tmp;
GetTimeZoneInformation(&tmp);
int64_t res = -tmp.Bias;
return res * MS_PER_MINUTE;
}
int64_t GetUTCTimestamp(int64_t year, int64_t month, int64_t day, int64_t hour, int64_t minute, int64_t second,
int64_t millisecond)
{
if (hour >= HOUR_PER_DAY) {
int64_t tmp = hour / HOUR_PER_DAY;
day += tmp;
hour -= tmp * HOUR_PER_DAY;
}
if (minute >= MINUTE_PER_DAY) {
int64_t tmp = minute / MINUTE_PER_DAY;
day += tmp;
minute -= tmp * MINUTE_PER_DAY;
}
if (second >= SECOND_PER_DAY) {
int64_t tmp = second / SECOND_PER_DAY;
day += tmp;
second -= tmp * SECOND_PER_DAY;
}
if (millisecond >= MS_PER_DAY) {
int64_t tmp = millisecond / MS_PER_DAY;
day += tmp;
millisecond -= tmp * MS_PER_DAY;
}
tm localTime = {
.tm_sec = second + (millisecond / MS_PER_SECOND),
.tm_min = minute,
.tm_hour = hour,
.tm_mday = day,
.tm_mon = month,
.tm_year = year,
.tm_isdst = -1
};
return (mktime(&localTime) * MS_PER_SECOND) + (millisecond % MS_PER_SECOND);
}
int64_t GetCurrentTimestamp()
{
return 0;
}
bool IsDst(int64_t timeMs)
{
timeMs /= MS_PER_SECOND;
time_t tv = timeMs;
struct tm nowtm;
localtime_s(&nowtm, &tv);
int month = nowtm.tm_mon + 1;
int day = nowtm.tm_mday;
int hour = nowtm.tm_hour;
TIME_ZONE_INFORMATION tzi;
GetTimeZoneInformation(&tzi);
SYSTEMTIME stDSTStart = tzi.DaylightDate;
SYSTEMTIME stDSTEnd = tzi.StandardDate;
if (month > stDSTStart.wMonth && month < stDSTEnd.wMonth) {
return true;
} else if (month == stDSTStart.wMonth) {
if (day > stDSTStart.wDay || (day == stDSTStart.wDay && hour >= tzi.DaylightBias)) {
return true;
}
} else if (month == stDSTEnd.wMonth) {
if (day < stDSTEnd.wDay || (day == stDSTEnd.wDay && hour < tzi.DaylightBias)) {
return true;
}
}
return false;
}
}