austrian-cpi
Version:
Query and merge Austrian CPI time series data for economic modeling
127 lines (111 loc) • 2.9 kB
JavaScript
import { austrianCPI } from "../austrianCPI.js";
/**
* Internal helper to extract sorted CPI data
* @param {string} seriesKey
* @param {'monthly'|'yearly'} frequency
* @param {string|null} start
* @param {string|null} end
* @returns {Array<{ date: string, value: number }>}
*/
function extractSeriesValues(
seriesKey,
frequency = "monthly",
start = null,
end = null,
) {
return austrianCPI
.map((row) => {
const parsed = parsePeriod(row);
if (!parsed || parsed.type !== frequency) return null;
const dateKey = parsed.key;
if (start && dateKey < start) return null;
if (end && dateKey > end) return null;
let val = row[seriesKey];
if (
val === "None" ||
val === undefined ||
val === null ||
typeof val === "object"
)
return null;
val = typeof val === "string" ? parseFloat(val.replace(",", ".")) : val;
return { date: dateKey, value: val };
})
.filter(Boolean)
.sort((a, b) => a.date.localeCompare(b.date));
}
function padMonth(month) {
return month.length === 1 ? "0" + month : month;
}
// helper
function parsePeriod(entry) {
let period = entry && entry.period ? entry.period : "";
if (!period) return null;
period = period
.replace(/[\u00A0\u202F\u200E\u200F]/g, " ")
.replace(/\s+/g, " ")
.trim();
if (period.startsWith("Ø")) {
const yearStr = period.slice(2).trim();
const fullYear =
yearStr.length === 2
? parseInt(yearStr, 10) > 50
? "19" + yearStr
: "20" + yearStr
: yearStr;
return {
type: "yearly",
year: parseInt(fullYear, 10),
key: fullYear,
};
}
const match = period.match(/^([A-Za-zÄÖÜäöüß]{3,4})\.\s*(\d{2})$/);
if (!match) return null;
const monthStr = match[1];
const yearStr = match[2];
const monthMap = {
// German
Jän: "01",
Feb: "02",
Mär: "03",
Apr: "04",
Mai: "05",
Jun: "06",
Jul: "07",
Aug: "08",
Sep: "09",
Okt: "10",
Nov: "11",
Dez: "12",
// EN (3- or 4-letter forms)
Jan: "01",
Mar: "03",
May: "05",
Sept: "09",
Oct: "10",
Dec: "12",
};
const month = monthMap[monthStr];
if (!month) return null;
const fullYear = parseInt(yearStr, 10) > 50 ? "19" + yearStr : "20" + yearStr;
return {
type: "monthly",
year: parseInt(fullYear, 10),
month: parseInt(month, 10),
key: fullYear + "-" + month,
};
}
/**
* Normalize YYYY-MM dates, e.g. 2023-1 -> 2023-01
*/
function normalizeDate(dateStr) {
if (!dateStr || typeof dateStr !== "string") return "";
const parts = dateStr.trim().split("-");
if (parts.length === 2) {
const year = parts[0];
const month = padMonth(parts[1]);
return `${year}-${month}`;
}
return dateStr.trim();
}
export { extractSeriesValues, normalizeDate, parsePeriod };