# Plutus : Slot and Time Ranges

Here is the updated tutorial with:

* ✅ **Numbered sections**
* ✅ A clean **Table of Contents**
* ✅ A clear **Glossary** at the end
* ✅ All links updated to the [Intersect Plutus Apps Haddock](https://intersectmbo.github.io/plutus-apps/main/)

***

## 📘 Plutus : Slot and Time Ranges

***

### 📑 Table of Contents

1. Introduction
2. Slot vs POSIXTime
3. POSIXTimeRange and Interval
4. ScriptContext Time Checks
5. Off-Chain Slot Conversions
6. Full Example: Deadline Validator
7. Glossary
8. References

***

### 1. 🧭 Introduction

Time-sensitive logic is common in Plutus smart contracts. You often need to:

* Enforce **deadlines**
* Allow **scheduled unlocks**
* Handle **auction close** times

Plutus uses `POSIXTime` and `Interval POSIXTime` (a.k.a. `POSIXTimeRange`) to model time. You **do not** check `Slot` directly on-chain—it's for *off-chain conversion*.

***

### 2. 🧮 Slot vs POSIXTime

| Term        | Description                       | Used In   |
| ----------- | --------------------------------- | --------- |
| `Slot`      | Blockchain slot number (`SlotNo`) | Off-chain |
| `POSIXTime` | Unix time in milliseconds         | On-chain  |

To use real time on-chain, you write Plutus validators in terms of `POSIXTime`. Slot-related logic is done off-chain.

📄 Off-chain conversion: [`Ledger.TimeSlot`](https://intersectmbo.github.io/plutus-apps/main/ledger/html/Ledger-TimeSlot.html)

```haskell
slotToBeginPOSIXTime :: Slot -> POSIXTime
```

***

### 3. 📐 POSIXTimeRange and Interval

#### 📌 Definition

On-chain time constraints are represented as:

```haskell
type POSIXTimeRange = Interval POSIXTime
```

This lets you express “when” a transaction is valid.

📄 Docs:

* [`Plutus.V1.Ledger.Time`](https://intersectmbo.github.io/plutus-apps/main/plutus-ledger-api/html/Plutus-V1-Ledger-Time.html)
* [`Plutus.V1.Ledger.Interval`](https://intersectmbo.github.io/plutus-apps/main/plutus-ledger-api/html/Plutus-V1-Ledger-Interval.html)

#### 🛠 Common Constructors

| Constructor    | Meaning                       |
| -------------- | ----------------------------- |
| `always`       | Infinite range (no bounds)    |
| `from t`       | Time ≥ `t`                    |
| `to t`         | Time ≤ `t`                    |
| `interval a b` | Between `a` and `b` inclusive |

#### 🧪 Example

```haskell
deadline :: POSIXTime
deadline = 1660000000

validRange = to deadline  -- Valid before or at the deadline
```

***

### 4. 🧾 ScriptContext Time Checks

The transaction’s valid range is pulled from the context:

```haskell
txInfoValidRange :: TxInfo -> POSIXTimeRange
scriptContextTxInfo :: ScriptContext -> TxInfo
```

#### ✅ Check if TX is before deadline:

```haskell
{-# INLINABLE validateBeforeDeadline #-}
validateBeforeDeadline :: POSIXTime -> () -> ScriptContext -> Bool
validateBeforeDeadline deadline _ ctx =
    contains (to deadline) (txInfoValidRange $ scriptContextTxInfo ctx)
```

***

### 5. 🔁 Off-Chain Slot Conversions

To convert between slot numbers and real time (POSIX), use:

```haskell
slotToPOSIXTime      :: Slot -> POSIXTime
slotToBeginPOSIXTime :: Slot -> POSIXTime
slotToEndPOSIXTime   :: Slot -> POSIXTime
```

This is useful when:

* You know the deadline in *slots*
* You're building the transaction *off-chain*

📄 Module: [`Ledger.TimeSlot`](https://intersectmbo.github.io/plutus-apps/main/ledger/html/Ledger-TimeSlot.html)

***

### 6. ✅ Full Example: Validator with Deadline

```haskell
{-# INLINABLE mkValidator #-}
mkValidator :: POSIXTime -> () -> ScriptContext -> Bool
mkValidator deadline _ ctx =
    traceIfFalse "deadline passed" withinRange
  where
    info = scriptContextTxInfo ctx
    withinRange = contains (to deadline) (txInfoValidRange info)
```

📌 This validator:

* Accepts a `POSIXTime` as deadline
* Fails if the transaction is *after* that time

***

### 7. 📚 Glossary

| Term               | Meaning                                                     |
| ------------------ | ----------------------------------------------------------- |
| `Slot`             | A unit of blockchain time (e.g., one block every 1 sec)     |
| `POSIXTime`        | Unix time in milliseconds (standard time format)            |
| `Interval a`       | A range with lower and upper bounds of type `a`             |
| `POSIXTimeRange`   | A type alias: `Interval POSIXTime`                          |
| `ScriptContext`    | All on-chain data available to the validator                |
| `TxInfo`           | Contains TX metadata, inputs, outputs, range, signers, etc. |
| `txInfoValidRange` | Time range the transaction declares itself valid for        |
| `contains`         | Checks whether one interval is completely within another    |

***

### 8. 🔗 References

* [📄 Plutus.V1.Ledger.Time](https://intersectmbo.github.io/plutus-apps/main/plutus-ledger-api/html/Plutus-V1-Ledger-Time.html)
* [📄 Plutus.V1.Ledger.Interval](https://intersectmbo.github.io/plutus-apps/main/plutus-ledger-api/html/Plutus-V1-Ledger-Interval.html)
* [📄 Ledger.TimeSlot (off-chain slot utils)](https://intersectmbo.github.io/plutus-apps/main/ledger/html/Ledger-TimeSlot.html)
* [🌐 Main Plutus Apps Docs Index](https://intersectmbo.github.io/plutus-apps/main/)

***
