Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 32 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[![Build Status](https://img.shields.io/github/actions/workflow/status/yize/solarlunar/test.yml?style=flat-square)](https://github.com/yize/solarlunar/actions)
[![File Size](https://img.shields.io/bundlephobia/minzip/solarlunar?style=flat-square)](https://bundlephobia.com/package/solarlunar)

*High-performance solar-lunar calendar conversion with天干地支, 生肖, and 24 solar terms support*
_High-performance solar-lunar calendar conversion with天干地支, 生肖, and 24 solar terms support_

</div>

Expand All @@ -32,27 +32,32 @@
npm install solarlunar
```

> **Note**: Use lowercase `solarlunar` (not `solarLunar`) when importing. Some case-sensitive file systems may fail to resolve the package with uppercase letters.

## 🛠️ Quick Start

### ES6 Modules

```javascript
import solarLunar from 'solarlunar';

// Solar to Lunar
const lunar = solarLunar.solar2lunar(2023, 10, 15);
console.log(lunar.lYear, lunar.lMonth, lunar.lDay); // 2023 8 30

// Lunar to Solar
// Lunar to Solar
const solar = solarLunar.lunar2solar(2023, 8, 30);
console.log(solar.cYear, solar.cMonth, solar.cDay); // 2023 10 15
```

### CommonJS

```javascript
const solarLunar = require('solarlunar');
```

### Browser

```html
<script src="https://unpkg.com/solarlunar/dist/solarlunar.min.js"></script>
<script>
Expand All @@ -63,19 +68,23 @@ const solarLunar = require('solarlunar');
## 📋 API Reference

### solarLunar.solar2lunar(year, month, day)

Convert solar date to lunar date.

**Parameters:**

- `year` (Number): Solar year (1900-2100)
- `month` (Number): Solar month (1-12)
- `month` (Number): Solar month (1-12)
- `day` (Number): Solar day (1-31)

**Returns:** Object with lunar date information

### solarLunar.lunar2solar(year, month, day, isLeapMonth?)

Convert lunar date to solar date.

**Parameters:**

- `year` (Number): Lunar year (1900-2100)
- `month` (Number): Lunar month (1-12)
- `day` (Number): Lunar day (1-30)
Expand All @@ -89,32 +98,32 @@ Convert lunar date to solar date.
{
// Basic lunar info
lYear: 2023, // Lunar year
lMonth: 8, // Lunar month
lMonth: 8, // Lunar month
lDay: 30, // Lunar day
isLeap: false, // Whether leap month

// Basic solar info
cYear: 2023, // Solar year
cMonth: 10, // Solar month
cDay: 15, // Solar day
isToday: false, // Whether today

// Chinese representations
yearCn: '二零二三年', // Chinese year
monthCn: '八月', // Chinese month
dayCn: '三十', // Chinese day
ncWeek: '星期日', // Chinese weekday

// Stems and Branches
gzYear: '癸卯', // Year stem-branch
gzMonth: '辛酉', // Month stem-branch
gzMonth: '辛酉', // Month stem-branch
gzDay: '甲子', // Day stem-branch

// Zodiac and terms
animal: '兔', // Zodiac animal
isTerm: false, // Whether solar term day
term: '', // Solar term name if applicable

// Weekday info
nWeek: 7 // Weekday number (1-7 for Mon-Sun)
}
Expand All @@ -123,6 +132,7 @@ Convert lunar date to solar date.
## 🧪 Examples

### Complete Conversion

```javascript
const result = solarLunar.solar2lunar(2023, 12, 22); // Winter Solstice day

Expand All @@ -142,12 +152,14 @@ console.log(result);
```

### Zodiac Calculation

```javascript
// Precise zodiac based on Spring Festival
const animal = solarLunar.getAnimal(2023, 2, 5); // Accurate based on 立春
```

### Solar Term Detection

```javascript
const hasTerm = solarLunar.solar2lunar(2023, 12, 22);
if (hasTerm.isTerm) {
Expand All @@ -158,24 +170,26 @@ if (hasTerm.isTerm) {
## 🏗️ Architecture

### Modern Build System

- **Rollup 4**: Optimized builds with tree-shaking
- **Vitest**: Fast, modern testing framework
- **ESLint + Prettier**: Code quality and formatting
- **TypeScript**: Complete type definitions

### Performance Optimizations

- Optimized algorithms for date calculations
- Precomputed data structures
- Efficient memory usage
- Fast lookup mechanisms

## 📊 Performance

| Operation | Average Time | Throughput |
|-----------|--------------|------------|
| Solar to Lunar | < 0.003ms | >340,000 ops/sec |
| Lunar to Solar | < 0.004ms | >270,000 ops/sec |
| Zodiac Calculation | < 0.001ms | >41,000,000 ops/sec |
| Operation | Average Time | Throughput |
| ------------------ | ------------ | ------------------- |
| Solar to Lunar | < 0.003ms | >340,000 ops/sec |
| Lunar to Solar | < 0.004ms | >270,000 ops/sec |
| Zodiac Calculation | < 0.001ms | >41,000,000 ops/sec |

## 🛡️ Reliability

Expand All @@ -187,7 +201,7 @@ if (hasTerm.isTerm) {
## 📚 Documentation

- [Quick Start Guide](QUICKSTART.md)
- [API Documentation](API.md)
- [API Documentation](API.md)
- [Usage Examples](EXAMPLES.md)
- [Development Guide](DEVELOPMENT.md)
- [Release Notes](RELEASE-NOTES.md)
Expand All @@ -201,7 +215,7 @@ We welcome contributions! Please see our [Development Guide](DEVELOPMENT.md) for
```bash
npm install # Install dependencies
npm test # Run tests
npm run test:watch # Watch mode for tests
npm run test:watch # Watch mode for tests
npm run dev # Development build watch
npm run build # Production build
npm run lint # Code quality check
Expand All @@ -227,4 +241,4 @@ Based on the original work by [JJonline](http://blog.jjonline.cn/userInterFace/1

[Get Started](#-quick-start) • [API Docs](API.md) • [Examples](EXAMPLES.md) • [Report Issue](https://github.com/yize/solarlunar/issues)

</div>
</div>
3 changes: 3 additions & 0 deletions solarlunar.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ declare const solarLunar: {
toChinaDay(d: number): string;
getAnimal(y: number, month?: number, day?: number): string;
getShiChen(hour: number, dayGanIndex: number): string;
getFestivals(year: number, month: number, day: number): string[];
addFestival(name: string, month: number, day: number): void;
clearFestivals(): void;
solar2lunar(year?: number, month?: number, day?: number): SolarLunarResult | -1;
lunar2solar(
year: number,
Expand Down
65 changes: 65 additions & 0 deletions src/solarLunar.js
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,71 @@ const solarLunar = {

return solarLunar.solar2lunar(cY, cM, cD);
},

/**
* 获取指定日期的传统节日
* @param {number} year - 公历年
* @param {number} month - 公历月
* @param {number} day - 公历日
* @returns {string[]} 传统节日数组
*/
getFestivals(year, month, day) {
const festivals = [];
const lunar = solarLunar.solar2lunar(year, month, day);
if (lunar === -1) return festivals;

const { lMonth, lDay } = lunar;

const fixedFestivals = {
'1-1': '春节',
'1-15': '元宵节',
'5-5': '端午节',
'7-7': '七夕节',
'8-15': '中秋节',
'9-9': '重阳节',
'12-8': '腊八节',
'12-23': '小年',
};

const key = `${lMonth}-${lDay}`;
if (fixedFestivals[key]) {
festivals.push(fixedFestivals[key]);
}

if (lMonth === 1 && lDay === 1) {
festivals.push('农历新年');
}

if (solarLunar.customFestivals) {
solarLunar.customFestivals.forEach((f) => {
if (f.month === lMonth && f.day === lDay) {
festivals.push(f.name);
}
});
}

return festivals;
},

/**
* 添加自定义农历节日
* @param {string} name - 节日名称
* @param {number} month - 农历月
* @param {number} day - 农历日
*/
addFestival(name, month, day) {
if (!solarLunar.customFestivals) {
solarLunar.customFestivals = [];
}
solarLunar.customFestivals.push({ name, month, day });
},

/**
* 清除所有自定义节日
*/
clearFestivals() {
solarLunar.customFestivals = [];
},
};

export default solarLunar;