Skip to content

Commit 4171e69

Browse files
Merge pull request #407 from nocodb/docs/script-date-conversion
2 parents b8cb105 + bc51c27 commit 4171e69

File tree

2 files changed

+139
-1
lines changed

2 files changed

+139
-1
lines changed

content/scripts/examples/meta.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"link-records-by-field",
1414
"unique-field-values-summary",
1515
"script-steps",
16-
"import-csv"
16+
"import-csv",
17+
"text-to-date"
1718
]
1819
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
title: Convert Date Text to ISO Format (Interactive Bulk Version)
3+
description: This script converts date-time text fields in the format "MM/DD/YYYY HH:MM AM/PM" to ISO 8601 format across multiple records in a selected table.
4+
tags: ['examples', 'text to date', 'date conversion', 'bulk processing', 'ISO format']
5+
---
6+
7+
## Convert Date Text to ISO Format (Interactive Bulk Version)
8+
This script allows you to convert date-time text fields in the format "MM/DD/YYYY HH:MM AM/PM" to ISO 8601 format across multiple records in a selected table. You will be prompted to select the table and fields for processing.
9+
10+
11+
```javascript
12+
// ------------------------------------------------------------
13+
// Script: Convert Date Text to ISO Format (Interactive Bulk Version)
14+
// ------------------------------------------------------------
15+
16+
// Step 1: Initialization
17+
script.step({
18+
title: 'Initializing Script',
19+
description: 'Preparing to convert date-time text fields to ISO format',
20+
icon: 'clock',
21+
color: 'blue'
22+
});
23+
24+
// Step 2: Collect user input
25+
script.step({
26+
title: 'Collecting Inputs',
27+
description: 'Please select table and fields for processing',
28+
icon: 'input',
29+
color: 'yellow'
30+
});
31+
32+
// Ask user to select table and fields
33+
const table = await input.tableAsync('Select a table to process:');
34+
const inputField = await input.fieldAsync('Select the input field (MM/DD/YYYY HH:MM AM/PM):', table);
35+
const outputField = await input.fieldAsync('Select the output field (for ISO format):', table);
36+
37+
// Confirm configuration
38+
output.markdown(`
39+
### ⚙️ Configuration
40+
- **Table:** ${table.name}
41+
- **Input Field:** ${inputField.name}
42+
- **Output Field:** ${outputField.name}
43+
`);
44+
45+
// Step 3: Load records
46+
script.step({
47+
title: 'Loading Records',
48+
description: `Fetching all records from "${table.name}"`,
49+
icon: 'download',
50+
color: 'blue'
51+
});
52+
53+
const result = await table.selectRecordsAsync({ pageSize: 50 });
54+
while (result.hasMoreRecords) {
55+
await result.loadMoreRecords();
56+
output.text(`📥 Loaded ${result.records.length} records...`);
57+
}
58+
output.text(`✅ Total records loaded: ${result.records.length}`);
59+
60+
// Step 4: Process records
61+
script.step({
62+
title: 'Processing Records',
63+
description: 'Parsing input values and preparing ISO formatted timestamps',
64+
icon: 'code',
65+
color: 'purple'
66+
});
67+
68+
const BATCH_SIZE = 10;
69+
let updates = [];
70+
let processed = 0;
71+
let updatedCount = 0;
72+
let skippedCount = 0;
73+
74+
for (const record of result.records) {
75+
processed++;
76+
77+
const inputValue = record.getCellValue(inputField);
78+
if (!inputValue) {
79+
skippedCount++;
80+
continue;
81+
}
82+
83+
const match = inputValue.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4}) (\d{1,2}):(\d{2}) (AM|PM)$/);
84+
if (!match) {
85+
skippedCount++;
86+
continue;
87+
}
88+
89+
let [, month, day, year, hour, minute, period] = match.map(v => v.trim());
90+
hour = parseInt(hour, 10);
91+
if (period === "PM" && hour !== 12) hour += 12;
92+
if (period === "AM" && hour === 12) hour = 0;
93+
94+
const iso = `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}T${String(hour).padStart(2, "0")}:${minute}:00`;
95+
96+
updates.push({
97+
id: record.id,
98+
fields: { [outputField.id]: iso }
99+
});
100+
101+
if (updates.length === BATCH_SIZE) {
102+
await table.updateRecordsAsync(updates);
103+
updatedCount += updates.length;
104+
updates = [];
105+
output.text(`💾 Committed ${updatedCount}/${result.records.length} records...`);
106+
}
107+
108+
if (processed % 100 === 0) {
109+
output.text(`🔄 Processed ${processed}/${result.records.length} records...`);
110+
}
111+
}
112+
113+
// Step 5: Commit remaining updates
114+
if (updates.length > 0) {
115+
await table.updateRecordsAsync(updates);
116+
updatedCount += updates.length;
117+
}
118+
119+
// Step 6: Completion summary
120+
script.step({
121+
title: 'Conversion Complete',
122+
description: 'All applicable records have been processed and updated',
123+
icon: 'checkCircle',
124+
color: 'green'
125+
});
126+
127+
output.markdown(`
128+
✅ **Conversion Summary**
129+
- **Table:** ${table.name}
130+
- **Total Records Loaded:** ${result.records.length}
131+
- **Records Updated:** ${updatedCount}
132+
- **Skipped (No / Invalid Data):** ${skippedCount}
133+
134+
All valid date values from **${inputField.name}** are now converted to ISO format in **${outputField.name}**.
135+
`);
136+
137+
```

0 commit comments

Comments
 (0)