> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gorules.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Date operations

> Working with dates and times in ZEN expressions.

ZEN provides the `d()` function for comprehensive date handling with timezone support, arithmetic, comparisons, and formatting.

## Creating dates

### From string

```
d("2024-01-15")                    // 2024-01-15T00:00:00Z
d("2024-01-15 14:30")              // 2024-01-15T14:30:00Z
d("2024-01-15 14:30:45")           // 2024-01-15T14:30:45Z
```

### With timezone

```
d("2024-01-15", "America/New_York")       // 2024-01-15T00:00:00-05:00
d("2024-01-15", "Europe/London")          // 2024-01-15T00:00:00Z
d("2024-01-15 14:30", "Asia/Tokyo")       // 2024-01-15T14:30:00+09:00
```

### Current date/time

```
d()                               // Current date and time
d("America/Los_Angeles")          // Current time in LA timezone
```

## Date components

### Getters

| Method         | Example                             | Result          |
| -------------- | ----------------------------------- | --------------- |
| `.year()`      | `d("2024-01-15").year()`            | `2024`          |
| `.month()`     | `d("2024-01-15").month()`           | `1`             |
| `.day()`       | `d("2024-01-15").day()`             | `15`            |
| `.weekday()`   | `d("2024-01-15").weekday()`         | `1` (Monday)    |
| `.hour()`      | `d("2024-01-15 14:30").hour()`      | `14`            |
| `.minute()`    | `d("2024-01-15 14:30").minute()`    | `30`            |
| `.second()`    | `d("2024-01-15 14:30:45").second()` | `45`            |
| `.dayOfYear()` | `d("2024-01-15").dayOfYear()`       | `15`            |
| `.quarter()`   | `d("2024-01-15").quarter()`         | `1`             |
| `.timestamp()` | `d("2024-01-15").timestamp()`       | `1705276800000` |

### Setters

```
d("2024-01-15").set("year", 2025)      // 2025-01-15
d("2024-01-15").set("month", 6)        // 2024-06-15
d("2024-01-15").set("day", 20)         // 2024-01-20
```

## Date arithmetic

### Adding time

```
d("2024-01-15").add("1d")              // 2024-01-16
d("2024-01-15").add("1w")              // 2024-01-22
d("2024-01-15").add("1M")              // 2024-02-15
d("2024-01-15").add("1y")              // 2025-01-15
d("2024-01-15").add("2d 5h")           // 2024-01-17T05:00:00

// Alternative syntax
d("2024-01-15").add(1, "d")            // 2024-01-16
d("2024-01-15").add(3, "M")            // 2024-04-15
```

### Subtracting time

```
d("2024-01-15").sub("7d")              // 2024-01-08
d("2024-01-15").sub("1M")              // 2023-12-15
d("2024-01-15").sub(1, "y")            // 2023-01-15
```

### Duration units

| Unit   | Aliases                  |
| ------ | ------------------------ |
| Year   | `y`, `year`, `years`     |
| Month  | `M`, `month`, `months`   |
| Week   | `w`, `week`, `weeks`     |
| Day    | `d`, `day`, `days`       |
| Hour   | `h`, `hour`, `hours`     |
| Minute | `m`, `minute`, `minutes` |
| Second | `s`, `second`, `seconds` |

## Date comparisons

### Comparison methods

```
d("2024-01-15").isBefore(d("2024-01-20"))         // true
d("2024-01-15").isAfter(d("2024-01-10"))          // true
d("2024-01-15").isSame(d("2024-01-15"))           // true
d("2024-01-15").isSameOrBefore(d("2024-01-15"))   // true
d("2024-01-15").isSameOrAfter(d("2024-01-15"))    // true
```

### Comparison with granularity

```
d("2024-01-15").isSame(d("2024-01-20"), "month")    // true (same month)
d("2024-01-15").isSame(d("2024-06-15"), "year")     // true (same year)
d("2024-01-15").isBefore(d("2024-02-01"), "month")  // true
```

### Comparison operators

```
d("2024-01-15") == d("2024-01-15")    // true
d("2024-01-15") != d("2024-01-20")    // true
d("2024-01-15") < d("2024-01-20")     // true
d("2024-01-15") > d("2024-01-10")     // true
d("2024-01-15") <= d("2024-01-15")    // true
d("2024-01-15") >= d("2024-01-15")    // true
```

### Range checks

```
d("2024-01-15") in [d("2024-01-01")..d("2024-01-31")]     // true
d("2024-01-15") in (d("2024-01-01")..d("2024-01-31"))     // true
d("2024-02-15") not in [d("2024-01-01")..d("2024-01-31")] // true
```

## Calculating differences

```
d("2024-01-15").diff("2024-01-10", "day")       // 5
d("2024-01-15").diff("2024-01-01", "week")      // 2
d("2024-06-15").diff("2024-01-15", "month")     // 5
d("2025-01-15").diff("2024-01-15", "year")      // 1
```

Negative differences when the first date is earlier:

```
d("2024-01-10").diff("2024-01-15", "day")       // -5
```

## Start and end of periods

```
d("2024-01-15").startOf("day")      // 2024-01-15T00:00:00
d("2024-01-15").endOf("day")        // 2024-01-15T23:59:59
d("2024-01-15").startOf("month")    // 2024-01-01T00:00:00
d("2024-01-15").endOf("month")      // 2024-01-31T23:59:59
d("2024-01-15").startOf("year")     // 2024-01-01T00:00:00
d("2024-01-15").endOf("year")       // 2024-12-31T23:59:59
d("2024-01-15").startOf("week")     // 2024-01-15T00:00:00 (Monday)
d("2024-01-15").endOf("week")       // 2024-01-21T23:59:59 (Sunday)
d("2024-05-15").startOf("quarter")  // 2024-04-01T00:00:00
d("2024-05-15").endOf("quarter")    // 2024-06-30T23:59:59
```

## Timezone conversion

```
d("2024-01-15T12:00:00Z").tz("America/New_York")    // 2024-01-15T07:00:00-05:00
d("2024-01-15T12:00:00Z").tz("Europe/London")       // 2024-01-15T12:00:00Z
d("2024-01-15T12:00:00Z").tz("Asia/Tokyo")          // 2024-01-15T21:00:00+09:00
```

Get timezone name:

```
d("2024-01-15", "America/New_York").offsetName()    // "America/New_York"
```

## Relative dates

```
d().isToday()          // true if today
d().sub(1, "d").isYesterday()    // true
d().add(1, "d").isTomorrow()     // true
```

## Validation

```
d("2024-01-15").isValid()         // true
d("invalid").isValid()            // false
d("2024-02-30").isValid()         // false (invalid date)
d(null).isValid()                 // false
```

## Leap years

```
d("2024-01-15").isLeapYear()      // true
d("2023-01-15").isLeapYear()      // false
d("2000-01-15").isLeapYear()      // true
d("1900-01-15").isLeapYear()      // false
```

## Formatting

```
d("2024-01-15").format("%Y-%m-%d")                    // "2024-01-15"
d("2024-01-15").format("%Y/%m/%d")                    // "2024/01/15"
d("2024-01-15T14:30:45Z").format("%A, %B %d %Y")      // "Monday, January 15 2024"
d("2024-01-15T14:30:45Z").format("%H:%M:%S")          // "14:30:45"
```

### Format codes

| Code | Description         | Example   |
| ---- | ------------------- | --------- |
| `%Y` | 4-digit year        | `2024`    |
| `%m` | Month (01-12)       | `01`      |
| `%d` | Day (01-31)         | `15`      |
| `%H` | Hour (00-23)        | `14`      |
| `%M` | Minute (00-59)      | `30`      |
| `%S` | Second (00-59)      | `45`      |
| `%A` | Full weekday        | `Monday`  |
| `%a` | Abbreviated weekday | `Mon`     |
| `%B` | Full month          | `January` |
| `%b` | Abbreviated month   | `Jan`     |
| `%j` | Day of year         | `015`     |

## Min/max with dates

```
min([d("2024-01-15"), d("2024-03-20"), d("2024-02-10")])    // 2024-01-15
max([d("2024-01-15"), d("2024-03-20"), d("2024-02-10")])    // 2024-03-20
```

## Common patterns

### Age calculation

```
d().diff(birthDate, "year")
```

### Days until expiration

```
d(expirationDate).diff(d(), "day")
```

### Is within last 30 days

```
d(eventDate).isAfter(d().sub(30, "d"))
```

### Business days check

```
d(orderDate).weekday() in [1..5]    // 1=Monday, 5=Friday
```
