# Re-building the Date Workflow

[Flow › Chapter 4](../flow.md) walked through `date` on the command line — a process that takes a format argument and an optional `TZ` configuration, and produces a string. Time to build that workflow for real.

## What you will learn

- How to combine **two** upstream nodes into a single downstream node
- How **DateTime** uses configuration (timezone, format) plus a port
- How **PromptTemplate** stitches values together with named slots

## Reset the canvas

This page builds a different shape than the previous one. Open the editor and remove the nodes you no longer need:

- Delete TextProcessor.
- Delete the TextInput node feeding its `operation` port.

You should be left with just **ChatInput** and **ChatOutput**, unconnected.

## Step 1: Add a DateTime node

1. Click **+** and search for **Date Time** (under **Utility**).
2. Drop it on the canvas.

Click the new node and configure it:

- **operation**: `current` (this is the default — outputs the current time)
- **timezone**: `Europe/Berlin` (or whatever zone you like — try `Asia/Tokyo`)
- **format**: `Y-m-d H:i` (PHP date format — year-month-day hour:minute)

DateTime has no required input. It just produces values from its configuration.

## Step 2: Add a PromptTemplate node

1. Click **+** and add a **Prompt Template** (under **Text & Output**).
2. Click it to configure.
3. Set **template** to:

```
Hi {{ name }}, it's {{ now }} where I'm running.
```

PromptTemplate creates one input port for each `{{ variable }}` you reference. So this template gives you two ports: `name` and `now`.

## Step 3: Wire everything up

```
┌─────────────┐
│  ChatInput  │
│             │ message
└──────┬──────┘
       │
       │           ┌────────────────┐
       │ name      │ PromptTemplate │
       └──────────▶│                │
                   │ Hi {{name}},   │ prompt   ┌──────────────┐
       ┌──────────▶│ it's {{now}}…  ├─────────▶│  ChatOutput  │
       │ now       │                │          │              │
       │           └────────────────┘          └──────────────┘
┌──────┴──────┐
│  DateTime   │
│ Europe/Berlin│ datetime
│ Y-m-d H:i   │
└─────────────┘
```

To draw this:

1. ChatInput's `message` output → PromptTemplate's `name` input
2. DateTime's `datetime` output → PromptTemplate's `now` input
3. PromptTemplate's `prompt` output → ChatOutput's `message` input

## Step 4: Test

Save and open the Playground. Type `Alice`.

You should see:

```
Hi Alice, it's 2026-04-28 14:32 where I'm running.
```

Send another name. The time updates on each run, because DateTime re-evaluates every time the workflow runs.

## What just happened — comparing to Flow Ch. 4

In Flow Chapter 4 we drew this:

```
TimeZone ──▶  Clock  ──▶ Display
Get Date ──▶
              [Format, TimeZone configured inside]
```

What you just built is the same shape, with FlowDrop names:

| Flow Ch. 4 box | This workflow |
| --- | --- |
| Clock (the process) | **DateTime** node |
| `Format` (configured inside) | DateTime's **format** config |
| `TimeZone` (configured inside) | DateTime's **timezone** config |
| Get Date (trigger) | DateTime needs no upstream — execution starts it |
| Display | **ChatOutput** node |

The `name` input is new — that's the user's name flowing in from ChatInput. PromptTemplate is the glue that combines DateTime's output with that name into a single string.

## A small dynamic twist

Try this: DateTime has a `timezone` input port, not just a configuration value (same idea as Page 3). Add a TextInput with default `Asia/Tokyo`, wire it to DateTime's `timezone` input, save, send a message. The greeting now reports Tokyo time instead of Berlin.

Same pattern as before — config holds the default, a port overrides it at runtime.

## Why two upstream nodes matter

Until this page, every node had exactly one input flow. Here, **PromptTemplate has two parents**: ChatInput and DateTime. Both must finish before PromptTemplate runs. FlowDrop figures that out automatically — it walks the edges, finds the dependencies, and runs nodes in the right order.

This is the first place the workflow stops being a single chain and starts being a real graph.

## Next

[Trigger vs Data Edges →](trigger-vs-data.md) — what about an arrow that fires another node but carries no data?
