1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "base/utils/date_util.h"
17
18#include "base/utils/utils.h"
19
20namespace OHOS::Ace {
21
22Date Date::Current()
23{
24    Date date;
25    auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
26    auto local = std::localtime(&now);
27    CHECK_NULL_RETURN(local, date);
28    date.year = static_cast<uint32_t>(local->tm_year) + 1900; // local date start from 1900
29    date.month = static_cast<uint32_t>(local->tm_mon) + 1;    // local month start from 0 to 11, need add one.
30    date.day = static_cast<uint32_t>(local->tm_mday);
31    date.week = static_cast<uint32_t>(local->tm_wday);
32    return date;
33}
34
35bool Date::IsLeapYear(int32_t year)
36{
37    return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
38}
39
40int32_t Date::DayOfMonth(int32_t year, int32_t month)
41{
42    int32_t day = 0;
43    switch (month) {
44        case 1:
45        case 3:
46        case 5:
47        case 7:
48        case 8:
49        case 10:
50        case 12:
51            day = 31;
52            break;
53        case 4:
54        case 6:
55        case 9:
56        case 11:
57            day = 30;
58            break;
59        case 2:
60            day = IsLeapYear(year) ? 29 : 28;
61            break;
62        default:
63            day = 0;
64    }
65    return day;
66}
67
68int32_t Date::CalculateWeekDay(int32_t year, int32_t month, int32_t day)
69{
70    if (month == 1 || month == 2) {
71        month += 12;
72        year--;
73    }
74
75    // Day of the week calculation formula
76    return (day + 2 * month + 3 * (month + 1) / 5 + year + year / 4 - year / 100 + year / 400) % 7;
77}
78
79int64_t Date::GetMilliSecondsByDateTime(std::tm& dateTime)
80{
81    auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
82    auto local = std::localtime(&now);
83    CHECK_NULL_RETURN(local, 0);
84    if (dateTime.tm_year == 0) {
85        dateTime.tm_year = local->tm_year;
86    }
87    if (dateTime.tm_mday == 0) {
88        dateTime.tm_mday = local->tm_mday;
89    }
90    auto timestamp = std::chrono::system_clock::from_time_t(std::mktime(&dateTime));
91    auto duration = timestamp.time_since_epoch();
92    auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
93    return milliseconds;
94}
95} // namespace OHOS::Ace
96