# Holiday Traits

<div data-full-width="true"><figure><img src="https://1439106760-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FKN3EFr5qxYFPQP8tyKq7%2Fuploads%2FipsmC4vfs2W7DrzuT0HO%2Fholiday.png?alt=media&#x26;token=102b4ee6-0330-48de-bbfe-92a5cb853a2a" alt=""><figcaption></figcaption></figure></div>

Holiday Traits offer holders a unique way to celebrate various occasions throughout the year, fostering engagement with their community and audience. Our aim is to elevate personal branding to a new height. At launch, we are introducing eight distinct holiday traits, with plans to expand this to dozens in a future update.

The top-of-head trait is designed to automatically update on the eve of the holiday and will remain active for 48 hours. To ensure uniqueness, even during holidays, we've ensured that no two ninjas will look the same. This necessitated precise adjustments to our [art generation algorithm](https://ninjalerts.gitbook.io/bitcoin-ordinals-pizza-ninjas/generative-art-process).

### **v1 Holiday Traits**

* **Halloween**: October 31st every year.
* **Christmas**: December 25th every year.
* **New Year's Eve**: December 31st every year.
* **Ordinals Birthday**: Celebrating the official launch of Ordinals on January 21st every year.
* **Chinese New Year**: The first day of the new moon that appears between 21 January and 20 February.
* **Valentine's Day**: February 14th every year.
* **St. Patrick's Day**: March 17th every year.
* **Easter Sunday**: The first Sunday after the full moon that occurs on or after the spring equinox.

### v2 Ideas

For v2, we would love to hear your suggestions and idea for specific holidays and what the trait could look like!

* Additional Holidays
  * Diwali
  * Thanksgiving
  * Autumn Festival
  * Mardi Gras
  * Hanukkah
  * Ramadan
  * Kwanzaa
  * Oktoberfest
* For Bitcoin
  * Satoshi Nakamoto's Birthday
  * Bitcoin Pizza Day
  * Genesis Block
  * Launch of the Whitepaper (also on Halloween)
* For Ordinals
  * Inscription 0: The first inscription.
  * Inscription 1 (Dick Butt Meme): A great story.
  * Inscription 10,000
  * Inscription 1,000,000
  * Inscription 10,000,000

### Holiday Traits Code Sample

We initially contemplated using block height to update traits, but due to its unreliability from year to year – with discrepancies of up to two weeks – we opted for a straightforward JavaScript-based method that checks the user's local browser time.

We are currently utilizing a basic library to determine the time, and we plan to share the finalized version in the upcoming weeks.

{% code lineNumbers="true" %}

```javascript
function calculateEaster(year) {
    const a = year % 19;
    const b = Math.floor(year / 100);
    const c = year % 100;
    const d = Math.floor(b / 4);
    const e = b % 4;
    const f = Math.floor((b + 8) / 25);
    const g = Math.floor((b - f + 1) / 3);
    const h = (19 * a + b - d - g + 15) % 30;
    const i = Math.floor(c / 4);
    const k = c % 4;
    const l = (32 + 2 * e + 2 * i - h - k) % 7;
    const m = Math.floor((a + 11 * h + 22 * l) / 451);
    const month = Math.floor((h + l - 7 * m + 114) / 31);
    const day = ((h + l - 7 * m + 114) % 31) + 1;
    return new Date(year, month - 1, day);
}

function calculateChineseNewYear(year) {
    if (year < 1900 || year > 2099) {
        throw new Error('Year out of supported range. This method is accurate only between 1900 and 2099.');
    }

    const term1 = (year * 12.3685);
    const term2 = Math.floor(year / 100) * 0.2422 - 6.4;
    const term3 = [
        5.23, 20.84, 5.22, 20.84, 5.23, 21.85, 6.24, 21.85, 6.24,
        21.85, 6.24, 22.86, 0.24, 23.86, 0.24, 23.86, 0.24, 23.86
    ][(year - 1900) % 18];

    const newMoonDay = Math.floor(term1) + term2 + term3;
    const month = (newMoonDay < 31) ? 0 : 1;
    const day = month === 0 ? newMoonDay : newMoonDay - 31;

    return new Date(year, month, day);
}

function calculateThanksgiving(year) {
    const fourthThursday = new Date(year, 10, 1); // 10: November
    fourthThursday.setDate(22 + (11 - fourthThursday.getDay()) % 7);
    return fourthThursday;
}

function isWithinHolidayPeriod() {
    const now = new Date();
    const year = now.getFullYear();

    // Define the holidays and key dates
    const holidays = [
        { name: 'New Years Day', month: 0, day: 1, hoursBefore: 32 },
        { name: 'Chinese New Year', date: calculateChineseNewYear(year), hoursBefore: 32 },
        { name: 'Valentine\'s Day', month: 1, day: 14, hoursBefore: 32 },
        { name: 'St. Patrick\'s Day', month: 2, day: 17, hoursBefore: 32 },
        { name: 'Easter Day', date: calculateEaster(year), hoursBefore: 32 },
        { name: 'April Fools Day', month: 3, day: 1, hoursBefore: 2, hoursAfter: 2 },
        { name: 'Satoshi Nakamoto\'s Birthday', month: 4, day: 5, hoursBefore: 32 }, // Speculative date
        { name: 'Bitcoin Pizza Day', month: 4, day: 22, hoursBefore: 32 },
        { name: 'Bitcoin\'s Birthday', month: 0, day: 3, hoursBefore: 32 }, // Approximate date
        { name: 'Halloween', month: 9, day: 31, hoursBefore: 32 },
        { name: 'Thanksgiving Day', date: calculateThanksgiving(year), hoursBefore: 32 },
        { name: 'Christmas Day', month: 11, day: 25, hoursBefore: 32 }
    ];

    for (let holiday of holidays) {
        const holidayDate = holiday.date || new Date(year, holiday.month, holiday.day);
        const startPeriod = new Date(holidayDate);
        startPeriod.setHours(startPeriod.getHours() - holiday.hoursBefore);

        const endPeriod = new Date(holidayDate);
        if (holiday.hoursAfter) {
            endPeriod.setHours(endPeriod.getHours() + holiday.hoursAfter);
        } else {
            endPeriod.setHours(24); // End of the holiday day
        }

        if (now >= startPeriod && now <= endPeriod) {
            return `You are within the specified time range before ${holiday.name}!`;
        }
    }
    
    return 'You are not within the specified time range before any key date or holiday.';
}

// Test the function
console.log(isWithinHolidayPeriod());
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ninjalerts.gitbook.io/bitcoin-ordinals-pizza-ninjas/holiday-traits.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
