1/*
2 * Copyright (c) 2021-2023 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
16import { MILLISECOND } from '../constants/Constant';
17import StringUtil from './StringUtil';
18import { getResourceString } from './Tools';
19import Logger from '../../base/log/Logger';
20import LanguageUtil from './LanguageUtil';
21
22const TAG = 'DateTimeUtil';
23
24namespace DateTimeUtil {
25  /**
26   * 日期格式常量
27   */
28  export const DATE_FORMAT = {
29    YYYY_MM_DD: 'yyyy/mm/dd',
30    MM_DD: 'mm/dd',
31    DATE_TIME: 'yyyy/mm/dd HH:MM:SS',
32    YYYY_MM_DD_CHINESE: 'yyyy年mm月dd日',
33    MM_DD_CHINESE: 'm月d日',
34    DATE_TIME_CHINESE: 'yyyy年mm月dd日 HH:MM'
35  };
36
37  /**
38   * @description 获取指定时间戳当天0点的时间戳
39   * @param timeStamp 指定时间戳
40   * @return 当天0点的时间戳
41   */
42  export function getDayBeginTimeStamp(timeStamp: number) {
43    const date = new Date(timeStamp);
44    const year = date.getFullYear();
45    const month = date.getMonth() + 1;
46    const day = date.getDate();
47
48    return new Date(`${year}-${month}-${day}`).getTime();
49  }
50
51  /**
52   * @description 将时长转化成转化为时分秒
53   * @param duration 时长
54   * @param unit 时间单位
55   * @return 格式化时长,如:08:20
56   */
57  export function formatDuration(duration: number): string {
58    let remainTime = duration;
59    const hours = Math.floor(remainTime / MILLISECOND.ONE_HOUR);
60    remainTime -= hours * MILLISECOND.ONE_HOUR;
61    const minutes = Math.floor(remainTime / MILLISECOND.ONE_MINUTE);
62    remainTime -= minutes * MILLISECOND.ONE_MINUTE;
63    const seconds = Math.floor(remainTime / MILLISECOND.ONE_SECOND);
64
65    const minutesStr = StringUtil.padStart(minutes);
66    const secondsStr = StringUtil.padStart(seconds);
67    if (hours) {
68      const hoursStr = StringUtil.padStart(hours);
69      return `${hoursStr}:${minutesStr}:${secondsStr}`;
70    } else {
71      return `${minutesStr}:${secondsStr}`;
72    }
73  }
74
75  /**
76   * @description 格式化文件更新时间
77   * @param timeStamp 时间戳,单位毫秒
78   * @param 格式化时间,如:YYYY/MM/HH hh:mm:ss
79   */
80  export function formatFileModifiedTime(timeStamp: number): string {
81    const dateTime = new Date(timeStamp);
82    const year = dateTime.getFullYear();
83    const month = StringUtil.padStart(dateTime.getMonth() + 1);
84    const day = StringUtil.padStart(dateTime.getDate());
85    const hour = StringUtil.padStart(dateTime.getHours());
86    const minute = StringUtil.padStart(dateTime.getMinutes());
87    const second = StringUtil.padStart(dateTime.getSeconds());
88    return `${year}/${month}/${day} ${hour}:${minute}:${second}`;
89  }
90
91  /**
92   * 日期格式转换
93   * @param timestamp 时间戳
94   * @param format 格式(可选)
95   * @example formatDate(new Date(), "YYYY-mm-dd HH:MM:SS") => 2021-11-02 09:39:59
96   */
97  export function formatDate(timestamp, format = DATE_FORMAT.YYYY_MM_DD) {
98    let res = '';
99    try {
100      const date = new Date(timestamp);
101      const opt = {
102        'y+': date.getFullYear().toString(), // 年
103        'm+': (date.getMonth() + 1).toString(), // 月
104        'd+': date.getDate().toString(), // 日
105        'H+': date.getHours().toString(), // 时
106        'M+': date.getMinutes().toString(), // 分
107        'S+': date.getSeconds().toString(), // 秒
108      };
109      for (let key in opt) {
110        const reg = new RegExp(key);
111        let ret = reg.exec(format);
112        if (ret) {
113          format = format.replace(
114            reg, ret[0].length == 1 ? opt[key] : opt[key].padStart(ret[0].length, '0')
115          );
116        }
117      }
118      res = format;
119    } catch (error) {
120      Logger.e(TAG, 'formatDate error: ' + error.toString());
121    }
122    return res;
123  }
124
125  /**
126   * @description 获取YYYY/MM/DD格式的日期
127   * @param timeStamp 时间戳,单位毫秒
128   * @return 格式化时间,格式:中文显示“2022/10/08”,其他显示“08/10/2022”
129   */
130  export function getSimpleDateString(timeStamp: number, format: string = ''): string {
131    return formatDate(timeStamp, format || DATE_FORMAT.YYYY_MM_DD);
132  }
133
134  /**
135   * @description 格式化时间
136   * @param timeStamp 时间戳,单位毫秒
137   * @return 格式化时间,规则如下:
138   *  当前日期同一天:今天
139   *  当前日期前一天:昨天
140   *  其他:YYYY/MM/DD
141   */
142  export function getDateStringForCategory(timeStamp: number): string {
143    const now = Date.now();
144    const current = getDayBeginTimeStamp(timeStamp);
145    const today = getDayBeginTimeStamp(now);
146    const yesterday = today - MILLISECOND.ONE_DAY;
147    if (current === today) {
148      return getResourceString($r('app.string.today'));
149    } else if (current === yesterday) {
150      return getResourceString($r('app.string.yesterday'));
151    } else {
152      return getSimpleDateString(timeStamp);
153    }
154  }
155
156  /**
157   * @description 获取最近卡片显示的格式日期
158   * @param timeStamp 时间戳,单位毫秒
159   * @return 格式化时间,规则如下:
160   *  当前时间1分钟内:刚刚
161   *  当前时间1小时内:XX分钟前
162   *  当前日期同一天:上午 08:00
163   *  当前日期前一天:昨天
164   *  今年:MM月DD日
165   *  往年:YYYY/MM/DD
166   */
167  export function getDateStringForRecentCard(timeStamp: number): Resource | string {
168    let dateString = undefined;
169    const date = new Date();
170    const now = date.getTime();
171    const nowYear = date.getFullYear();
172    const cardYear = new Date(timeStamp).getFullYear();
173    const timeGap = now - timeStamp;
174    const todayBegin = getDayBeginTimeStamp(now);
175    const yesterdayBegin = todayBegin - MILLISECOND.ONE_DAY;
176    if (timeStamp > todayBegin) {
177      if (timeGap < MILLISECOND.ONE_MINUTE) {
178        dateString = $r('app.string.justNow');
179      } else if (timeGap < MILLISECOND.ONE_HOUR) {
180        const minute = Math.floor(timeGap / MILLISECOND.ONE_MINUTE);
181        dateString = $r('app.plural.minute_ago', minute, minute);
182      } else {
183        dateString = $r('app.string.today');
184      }
185    } else if (timeStamp > yesterdayBegin) {
186      dateString = $r('app.string.yesterday');
187    } else if (cardYear === nowYear) {
188      const format = LanguageUtil.isChineseLanguage() ? DATE_FORMAT.MM_DD_CHINESE : DATE_FORMAT.MM_DD;
189      dateString = formatDate(timeStamp, format);
190    } else {
191      dateString = getSimpleDateString(timeStamp);
192    }
193    return dateString;
194  }
195}
196
197export default DateTimeUtil;
198