<a id="ch-07"></a>

## Chapter 7 — Night is a cut on the hour token

<!-- open-cyber-academy:lesson-figures:start ch-07 -->
### Lesson map

Lesson 07. Map, example, EX053.

```mermaid
flowchart TD
  T["Time token"] --> S["Split on spaces"]
  S --> H["First two characters of part two"]
  H --> I["Integer hour"]
  I --> Q{"Hour below 6, or hour at least 22?"}
  Q -->|Yes| N["Night flag"]
  Q -->|No| D["No night flag"]
```

The hour is parsed from characters. It is not a timezone.

### Logical drawing

```text
Fri 23:47 -> hour 23 -> night
Sat 00:02 -> hour 0 -> night
Fri 08:52 -> hour 8 -> not night
22:00 would be hour 22 -> night
06:00 would be hour 6 -> not night
```
<!-- open-cyber-academy:lesson-figures:end ch-07 -->

### Learning outcomes

After this chapter, you should be able to:

1. Show how the hour integer is parsed.
2. Apply the two cuts, including the boundaries.
3. Refuse a timezone reading the script does not perform.

### 7.1 The hour is two characters, then an integer cut.

`when.split()` breaks the time token on spaces. For `Fri 23:47` the parts are `Fri` and `23:47`. Index 1 selects the second part. `[:2]` keeps `23`. `int` makes the hour 23. The day word is never parsed. The minutes after the colon are never parsed. No timezone name is read, and no clock is shifted.

The night test is `hour < 6 or hour >= 22`. Hour 23 meets the second cut. Hour 0, from `Sat 00:02`, meets the first cut. Hour 8, from `Fri 08:52`, meets neither cut, and hour 13 meets neither cut. Hour 22 is the first integer the late cut accepts, so a token written 22:00 would still count as night, and that token is not stored here. Morning equality is the excluded edge: parsing 06:00 leaves the flag down because six sits outside both cuts, and that edge is absent from the roster.

Section 2.2 says the lab flags a time between 22:00 and 06:00. The predicate is the precise form: from 22:00 inclusive, and before 06:00. The exercise answer already in the appendix says "Before 06:00 or from 22:00." That wording matches the two cuts. This chapter does not replace the earlier sentence. It shows the characters the script actually reads.

| Token in this list | Parsed hour | Night? |
|---|---|---|
| Fri 23:47 | 23 | yes |
| Sat 00:02 | 0 | yes |
| Fri 08:52 | 8 | no |
| Fri 13:05 | 13 | no |
| Fri 09:10 | 9 | no |
| Fri 08:30 | 8 | no |

### 7.2 Worked example

| Offered hour | Predicate | Decision |
|---|---|---|
| 23 and 0 on the Brazil rows | Both cuts can fire | Keep |
| 8, 13, 9, and 8 on the UK rows | Neither cut fires | Keep |
| "06:00 is night." | Hour 6 fails both cuts | Refuse |
| "The day word sets the timezone." | The day word is ignored | Refuse |

> **Synthetic case.** Boundary hours 6 and 22 are not rows in the file.

### Errors and limits

Do not insert a 06:00 row or a 22:00 row into the published list.

### Apply

- **EX053 — Hour cuts.** Using the same predicate, is 22:00 night, is 06:00 night, and does the script read a timezone? *Rubric:* 3 = 22:00 is night because hour 22 meets `>= 22`; 06:00 is not night because hour 6 fails both cuts; the day word and the minutes are not a timezone;; 2 = 22:00 is night and 06:00 is not;; 1 = one boundary;; 0 = none.

<!-- open-cyber-academy:chapter-navigation:start ch-07 -->
### Continue studying — lesson 07 (chapter 07 of 20)

[← Chapter 06](#ch-06) · [Course chapter index](../SUBJECTS.md) · [Chapter 08 →](#ch-08)

Continue to the next authored lesson.
<!-- open-cyber-academy:chapter-navigation:end -->

## Worked answers

<a id="answer-ex053"></a>
**EX053.** 22:00 is night because hour 22 meets `>= 22`. 06:00 is not night because hour 6 fails both cuts. The day word is not a timezone.
