# 日期处理模块
日期处理模块提供了日期格式化、时间戳转换、年龄计算、闰年判断等常用的日期时间处理功能。
## 引用方式
### ES6 模块引用
```javascript
import sinma from 'sinmajs';
// 或者使用解构赋值
import { formatDate, calculateAge, isLeapYear, now } from 'sinmajs';
```
### CommonJS 引用
```javascript
const sinma = require('sinmajs');
```
### 浏览器直接引用
```html
<script src="https://unpkg.com/sinmajs@latest/dist/sinma.min.js"></script>
<script>
// 直接使用 sinma 对象
console.log(sinma.formatDate(new Date(), 'YYYY-MM-DD'));
</script>
```
## API 列表
### formatDate(date, format) - 日期格式化
将日期对象或日期字符串格式化为指定格式的字符串。
#### 参数
- `date` {Date|string|number} - 日期对象、日期字符串或时间戳
- `format` {string} - 格式化模板,默认 `'YYYY-MM-DD'`
#### 格式化符号
- `YYYY` - 四位年份
- `MM` - 两位月份(01-12)
- `DD` - 两位日期(01-31)
- `HH` - 两位小时(00-23)
- `mm` - 两位分钟(00-59)
- `ss` - 两位秒钟(00-59)
#### 返回值
- {string} - 格式化后的日期字符串,无效日期返回空字符串
#### 功能代码
```javascript
function formatDate(date, format = 'YYYY-MM-DD') {
const d = new Date(date);
if (isNaN(d.getTime())) return '';
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const hours = String(d.getHours()).padStart(2, '0');
const minutes = String(d.getMinutes()).padStart(2, '0');
const seconds = String(d.getSeconds()).padStart(2, '0');
return format
.replace('YYYY', year)
.replace('MM', month)
.replace('DD', day)
.replace('HH', hours)
.replace('mm', minutes)
.replace('ss', seconds);
}
```
#### 使用方法
```javascript
const now = new Date();
sinma.formatDate(now); // '2023-12-25'
sinma.formatDate(now, 'YYYY-MM-DD HH:mm:ss'); // '2023-12-25 14:30:45'
sinma.formatDate(now, 'MM/DD/YYYY'); // '12/25/2023'
sinma.formatDate(now, 'YYYY年MM月DD日'); // '2023年12月25日'
sinma.formatDate('2023-06-15'); // '2023-06-15'
sinma.formatDate(1703505045000); // '2023-12-25'
sinma.formatDate('invalid'); // ''
```
#### 使用范例
```javascript
// 文章发布时间显示
function formatPublishTime(timestamp) {
const now = new Date();
const publishDate = new Date(timestamp);
const diffMs = now - publishDate;
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
if (diffDays === 0) {
return '今天 ' + sinma.formatDate(publishDate, 'HH:mm');
} else if (diffDays === 1) {
return '昨天 ' + sinma.formatDate(publishDate, 'HH:mm');
} else if (diffDays < 7) {
return `${diffDays}天前`;
} else {
return sinma.formatDate(publishDate, 'YYYY-MM-DD');
}
}
// 日志记录格式化
function createLogEntry(level, message) {
const timestamp = sinma.formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss');
return `[${timestamp}] [${level.toUpperCase()}] ${message}`;
}
console.log(createLogEntry('info', '用户登录成功'));
// [2023-12-25 14:30:45] [INFO] 用户登录成功
// 文件名生成
function generateFileName(prefix, extension = 'log') {
const timestamp = sinma.formatDate(new Date(), 'YYYYMMDD_HHmmss');
return `${prefix}_${timestamp}.${extension}`;
}
console.log(generateFileName('backup', 'sql'));
// backup_20231225_143045.sql
// 报表日期范围
function formatDateRange(startDate, endDate) {
const start = sinma.formatDate(startDate, 'YYYY年MM月DD日');
const end = sinma.formatDate(endDate, 'YYYY年MM月DD日');
return `${start} 至 ${end}`;
}
```
---
### getTimestamp(date) - 获取时间戳
将日期转换为毫秒级时间戳。
#### 参数
- `date` {Date|string} - 日期对象或日期字符串
#### 返回值
- {number} - 毫秒级时间戳
#### 功能代码
```javascript
function getTimestamp(date) {
return new Date(date).getTime();
}
```
#### 使用方法
```javascript
sinma.getTimestamp(new Date()); // 1703505045000
sinma.getTimestamp('2023-12-25'); // 1703462400000
sinma.getTimestamp('2023-12-25 14:30'); // 1703505000000
```
#### 使用范例
```javascript
// 缓存过期检查
function isCacheExpired(cacheTimestamp, expireMinutes = 30) {
const now = sinma.getTimestamp(new Date());
const expireTime = cacheTimestamp + (expireMinutes * 60 * 1000);
return now > expireTime;
}
// API 请求去重
const requestCache = new Map();
function makeUniqueRequest(url, data) {
const key = url + JSON.stringify(data);
const cached = requestCache.get(key);
if (cached && !isCacheExpired(cached.timestamp, 5)) {
return Promise.resolve(cached.response);
}
return fetch(url, { method: 'POST', body: JSON.stringify(data) })
.then(response => response.json())
.then(result => {
requestCache.set(key, {
response: result,
timestamp: sinma.getTimestamp(new Date())
});
return result;
});
}
// 性能监控
class PerformanceMonitor {
constructor() {
this.startTime = null;
}
start() {
this.startTime = sinma.getTimestamp(new Date());
}
end(operationName) {
const endTime = sinma.getTimestamp(new Date());
const duration = endTime - this.startTime;
console.log(`${operationName} 耗时: ${duration}ms`);
return duration;
}
}
```
---
### calculateAge(birthday) - 计算年龄
根据生日字符串计算当前年龄。
#### 参数
- `birthday` {string} - 生日字符串(如:'1990-01-01')
#### 返回值
- {number} - 年龄(岁),最小为0
#### 功能代码
```javascript
function calculateAge(birthday) {
const birth = new Date(birthday);
const today = new Date();
let age = today.getFullYear() - birth.getFullYear();
if (today.getMonth() < birth.getMonth() ||
(today.getMonth() === birth.getMonth() && today.getDate() < birth.getDate())) {
age--;
}
return Math.max(0, age);
}
```
#### 使用方法
```javascript
sinma.calculateAge('1990-01-01'); // 33 (假设当前是2023年)
sinma.calculateAge('2000-12-25'); // 23
sinma.calculateAge('2023-06-15'); // 0 (当年出生)
sinma.calculateAge('2025-01-01'); // 0 (未来日期返回0)
```
#### 使用范例
```javascript
// 用户信息显示
function formatUserProfile(user) {
return {
name: user.name,
age: sinma.calculateAge(user.birthday),
ageGroup: getAgeGroup(sinma.calculateAge(user.birthday)),
birthday: sinma.formatDate(user.birthday, 'MM月DD日')
};
}
function getAgeGroup(age) {
if (age < 18) return '未成年';
if (age < 35) return '青年';
if (age < 60) return '中年';
return '老年';
}
// 生日提醒
function getBirthdayReminder(users) {
const today = new Date();
const todayStr = sinma.formatDate(today, 'MM-DD');
return users
.filter(user => {
const birthday = sinma.formatDate(user.birthday, 'MM-DD');
return birthday === todayStr;
})
.map(user => ({
name: user.name,
age: sinma.calculateAge(user.birthday),
message: `今天是 ${user.name} 的生日,${sinma.calculateAge(user.birthday)} 岁生日快乐!`
}));
}
// 年龄统计分析
function analyzeAgeDistribution(users) {
const ageGroups = {
'0-17': 0,
'18-30': 0,
'31-45': 0,
'46-60': 0,
'60+': 0
};
users.forEach(user => {
const age = sinma.calculateAge(user.birthday);
if (age < 18) ageGroups['0-17']++;
else if (age <= 30) ageGroups['18-30']++;
else if (age <= 45) ageGroups['31-45']++;
else if (age <= 60) ageGroups['46-60']++;
else ageGroups['60+']++;
});
return ageGroups;
}
// 保险费率计算
function calculateInsurancePremium(birthday, coverageAmount) {
const age = sinma.calculateAge(birthday);
let rate = 0.01; // 基础费率 1%
if (age < 25) rate = 0.008;
else if (age < 35) rate = 0.01;
else if (age < 50) rate = 0.015;
else rate = 0.02;
return {
age: age,
rate: `${rate * 100}%`,
premium: sinma.formatCurrency(coverageAmount * rate)
};
}
```
---
### isLeapYear(year) - 闰年判断
判断指定年份是否为闰年。
#### 参数
- `year` {number} - 年份
#### 返回值
- {boolean} - 是闰年返回 `true`,否则返回 `false`
#### 功能代码
```javascript
function isLeapYear(year) {
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
}
```
#### 使用方法
```javascript
sinma.isLeapYear(2024); // true (能被4整除,不能被100整除)
sinma.isLeapYear(2000); // true (能被400整除)
sinma.isLeapYear(1900); // false (能被100整除,不能被400整除)
sinma.isLeapYear(2023); // false (不能被4整除)
```
#### 使用范例
```javascript
// 日历生成
function getDaysInMonth(year, month) {
const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
if (month === 2 && sinma.isLeapYear(year)) {
return 29;
}
return daysInMonth[month - 1];
}
// 年份信息
function getYearInfo(year) {
return {
year: year,
isLeap: sinma.isLeapYear(year),
daysInYear: sinma.isLeapYear(year) ? 366 : 365,
daysInFebruary: sinma.isLeapYear(year) ? 29 : 28
};
}
console.log(getYearInfo(2024));
// { year: 2024, isLeap: true, daysInYear: 366, daysInFebruary: 29 }
// 生日验证
function validateBirthday(dateStr) {
const [year, month, day] = dateStr.split('-').map(Number);
if (month < 1 || month > 12) {
return { valid: false, error: '月份无效' };
}
const maxDays = getDaysInMonth(year, month);
if (day < 1 || day > maxDays) {
return { valid: false, error: `${year}年${month}月只有${maxDays}天` };
}
return { valid: true };
}
// 闰年列表生成
function getLeapYears(startYear, endYear) {
const leapYears = [];
for (let year = startYear; year <= endYear; year++) {
if (sinma.isLeapYear(year)) {
leapYears.push(year);
}
}
return leapYears;
}
console.log(getLeapYears(2020, 2030));
// [2020, 2024, 2028]
```
---
### now(format) - 获取当前时间
获取当前时间的格式化字符串。
#### 参数
- `format` {string} - 格式化模板,默认 `'YYYY-MM-DD HH:mm:ss'`
#### 返回值
- {string} - 格式化后的当前时间字符串
#### 功能代码
```javascript
function now(format = 'YYYY-MM-DD HH:mm:ss') {
return this.formatDate(new Date(), format);
}
```
#### 使用方法
```javascript
sinma.now(); // '2023-12-25 14:30:45'
sinma.now('YYYY-MM-DD'); // '2023-12-25'
sinma.now('HH:mm:ss'); // '14:30:45'
sinma.now('YYYY年MM月DD日 HH:mm'); // '2023年12月25日 14:30'
```
#### 使用范例
```javascript
// 日志记录
function log(level, message) {
const timestamp = sinma.now();
console.log(`[${timestamp}] [${level}] ${message}`);
}
// 数据备份
function createBackup(data) {
const filename = `backup_${sinma.now('YYYYMMDD_HHmmss')}.json`;
// 保存数据逻辑
return filename;
}
// 会话管理
class Session {
constructor(userId) {
this.userId = userId;
this.createdAt = sinma.now();
this.lastActive = sinma.now();
}
updateActivity() {
this.lastActive = sinma.now();
}
getInfo() {
return {
userId: this.userId,
createdAt: this.createdAt,
lastActive: this.lastActive,
duration: this.calculateDuration()
};
}
calculateDuration() {
const start = sinma.getTimestamp(this.createdAt);
const end = sinma.getTimestamp(this.lastActive);
const diffMs = end - start;
const diffMinutes = Math.floor(diffMs / (1000 * 60));
return `${diffMinutes}分钟`;
}
}
// API响应时间戳
function apiResponse(data) {
return {
data: data,
timestamp: sinma.now(),
serverTime: sinma.getTimestamp(new Date())
};
}
// 定时任务标记
function scheduleTask(taskName, intervalMinutes) {
console.log(`任务 ${taskName} 开始执行: ${sinma.now()}`);
setInterval(() => {
console.log(`任务 ${taskName} 执行中: ${sinma.now()}`);
// 执行具体任务
}, intervalMinutes * 60 * 1000);
}
```
## 高级用法示例
### 日期区间处理
```javascript
// 日期区间工具类
class DateRange {
constructor(startDate, endDate) {
this.startDate = new Date(startDate);
this.endDate = new Date(endDate);
}
// 获取区间天数
getDays() {
const diffTime = this.endDate - this.startDate;
return Math.ceil(diffTime / (1000 * 60 * 60 * 24));
}
// 检查日期是否在区间内
contains(date) {
const checkDate = new Date(date);
return checkDate >= this.startDate && checkDate <= this.endDate;
}
// 获取区间内所有日期
getAllDates() {
const dates = [];
const current = new Date(this.startDate);
while (current <= this.endDate) {
dates.push(sinma.formatDate(current));
current.setDate(current.getDate() + 1);
}
return dates;
}
// 格式化显示
toString() {
return `${sinma.formatDate(this.startDate)} 至 ${sinma.formatDate(this.endDate)}`;
}
}
const range = new DateRange('2023-12-01', '2023-12-07');
console.log(range.toString()); // '2023-12-01 至 2023-12-07'
console.log(range.getDays()); // 7
```
### 工作日计算
```javascript
// 工作日计算工具
function calculateWorkdays(startDate, endDate, holidays = []) {
const start = new Date(startDate);
const end = new Date(endDate);
const holidaySet = new Set(holidays.map(h => sinma.formatDate(h)));
let workdays = 0;
const current = new Date(start);
while (current <= end) {
const dayOfWeek = current.getDay();
const currentDateStr = sinma.formatDate(current);
// 不是周末且不是节假日
if (dayOfWeek !== 0 && dayOfWeek !== 6 && !holidaySet.has(currentDateStr)) {
workdays++;
}
current.setDate(current.getDate() + 1);
}
return workdays;
}
// 项目工期计算
function calculateProjectDuration(startDate, workdaysNeeded) {
const holidays = ['2023-12-25', '2024-01-01']; // 节假日
let current = new Date(startDate);
let remainingDays = workdaysNeeded;
while (remainingDays > 0) {
const dayOfWeek = current.getDay();
const currentDateStr = sinma.formatDate(current);
if (dayOfWeek !== 0 && dayOfWeek !== 6 && !holidays.includes(currentDateStr)) {
remainingDays--;
}
if (remainingDays > 0) {
current.setDate(current.getDate() + 1);
}
}
return sinma.formatDate(current);
}
```
### 时间段统计
```javascript
// 时间段统计工具
function analyzeTimeDistribution(timestamps) {
const distribution = {
morning: 0, // 06:00-12:00
afternoon: 0, // 12:00-18:00
evening: 0, // 18:00-22:00
night: 0 // 22:00-06:00
};
timestamps.forEach(timestamp => {
const date = new Date(timestamp);
const hour = date.getHours();
if (hour >= 6 && hour < 12) distribution.morning++;
else if (hour >= 12 && hour < 18) distribution.afternoon++;
else if (hour >= 18 && hour < 22) distribution.evening++;
else distribution.night++;
});
const total = timestamps.length;
return {
counts: distribution,
percentages: {
morning: `${Math.round(distribution.morning / total * 100)}%`,
afternoon: `${Math.round(distribution.afternoon / total * 100)}%`,
evening: `${Math.round(distribution.evening / total * 100)}%`,
night: `${Math.round(distribution.night / total * 100)}%`
}
};
}
```
## 性能优化建议
1. **缓存计算结果**: 对于重复的日期计算,考虑缓存结果
2. **批量处理**: 大量日期数据处理时使用批量函数
3. **时区处理**: 根据需要选择是否考虑时区问题
4. **日期验证**: 在处理用户输入时添加日期有效性验证
## 注意事项
1. **时区问题**: 默认使用本地时区,跨时区应用需要特别处理
2. **日期格式**: 输入的日期字符串格式要符合JavaScript Date构造函数的要求
3. **年份范围**: JavaScript Date对象的年份范围限制(1970-2038年问题)
4. **闰秒**: 不考虑闰秒的影响
## 相关模块
- [字符串模块](./string.md) - 提供日期字符串格式化功能
- [数字模块](./number.md) - 提供时间戳数值计算功能
- [中文处理模块](./chinese.md) - 提供从身份证提取生日等功能
