I’m using DayJS in my project. The user can enter some booking details, which are passed to a serverside function. This function should process the booking, but using the Dutch timezone.
No matter what I try, it keeps on using ‘en’ as locale. I’ve tried setting it globally, directly after importing the language file. Also I’ve tried to add it to every dayjs instance I create. Finally, I’ve put it all togheter, adding locale settings to every dayjs instance I have. No matter what, it doesn’t give me ‘nl’ as timezone. I left all code in my example below.
This is my serverside code:
import { PrismaClient } from "@prisma/client";
import { v4 as uuidv4 } from "uuid";
import dayjs from "dayjs";
import "dayjs/locale/nl";
import isSameOrBefore from "dayjs/plugin/isSameOrBefore.js";
import isSameOrAfter from "dayjs/plugin/isSameOrAfter.js";
import weekday from "dayjs/plugin/weekday.js";
dayjs.locale("nl");
dayjs.extend(isSameOrBefore);
dayjs.extend(isSameOrAfter);
dayjs.extend(weekday);
const createRepeatedBookingWeek = (data, body) => {
return new Promise(async (resolve, reject) => {
const prisma = new PrismaClient();
const bookingGroup = uuidv4();
dayjs.locale("nl");
const writeActionlog = async () => {
const performingUserEmail = body.auth.currentUser.email;
const performingUser = await prisma.User.findUnique({
where: { email: performingUserEmail },
select: { id: true },
});
if (performingUser) {
await prisma.ActionLog.create({
data: {
actionOfUser: { connect: { id: performingUser.id } },
performedAction: {
connect: { name: data.actionName },
},
},
});
await prisma.$disconnect();
return true;
} else {
return {
body: JSON.stringify({
snackbar: {
type: "error", //success || error || warning || info
title: "Foutcode CRBW39",
text: "De gebruiker is niet in de database gevonden.",
},
}),
};
}
};
const clashingBookings = [];
const checkForOverlappingBookings = async (query) => {
for (const room of body.details.rooms) {
await prisma.Booking.findMany({
where: {
rooms: {
some: {
id: room.id,
},
},
OR: query,
},
}).then((booking) => {
booking.forEach((element) => {
clashingBookings.push({ ...element, room: room });
});
});
}
};
const excludedDates = [];
if (body.details.excludedDates && body.details.excludedDates.length != 0) {
body.details.excludedDates.map((d) => {
excludedDates.push(dayjs(d).locale("nl"));
});
}
const checkIfExcluded = (f, t) => {
let value = false;
excludedDates.map((ed) => {
if (ed.isSame(f, "day") || ed.isSame(t, "day")) {
value = true;
}
});
return value;
};
if (
!body.details ||
body.details.name == "" ||
body.details.dateFrom == "" ||
body.details.dateTo == ""
) {
return resolve({
body: JSON.stringify({
snackbar: {
type: "error", //success || error || warning || info
title: "Foutcode CRBW98",
text: "Invoervelden mogen niet leeg zijn.",
},
}),
});
}
dayjs.locale("nl");
const bookingStart = dayjs(
`${body.details.dateFrom} ${body.details.timeFrom}`,
"YYYY-MM-DD HH:mm",
"nl"
)
.locale("nl")
.set("second", 0)
.set("millisecond", 0);
const bookingStartTS = "" + bookingStart.valueOf();
const bookingStartOfDay = bookingStart.startOf("day");
const bookingEnd = dayjs(
`${body.details.dateTo} ${body.details.timeTo}`,
"YYYY-MM-DD HH:mm",
"nl"
)
.locale("nl")
.set("second", 0)
.set("millisecond", 0);
const bookingEndTS = "" + bookingEnd.valueOf();
const repeatEnd = dayjs(
body.details.repeatOptions.repeatUntil,
"YYYY-MM-DD",
"nl"
)
.locale("nl")
.set("hour", 23)
.set("minute", 59)
.set("second", 59)
.set("millisecond", 999);
const repeatEndTS = "" + repeatEnd.valueOf();
const bookingDifference = bookingEndTS - bookingStartTS;
let dayToCheck = dayjs(bookingStart).locale("nl");
const orConditions = [];
const dateRanges = [];
try {
while (dayToCheck.isSameOrBefore(repeatEnd)) {
let firstDayOfWeek = dayToCheck.startOf("week").locale("nl");
const lastDayOfWeek = dayToCheck.endOf("week").locale("nl");
console.log("locale", dayjs.locale());
console.log("firstDayOfWeek", firstDayOfWeek);
while (firstDayOfWeek.isSameOrBefore(lastDayOfWeek)) {
if (
body.details.repeatOptions.repeatOn.includes(
firstDayOfWeek.weekday()
)
) {
const shouldBeExcluded = checkIfExcluded(
firstDayOfWeek,
firstDayOfWeek
);
if (
!shouldBeExcluded &&
firstDayOfWeek.isSameOrAfter(bookingStartOfDay)
) {
dateRanges.push(firstDayOfWeek);
}
}
firstDayOfWeek = firstDayOfWeek.add(1, "day");
}
dayToCheck = dayToCheck.add(
body.details.repeatOptions.interval,
"week"
);
}
// Loop through each date range
dateRanges.forEach((dateRange) => {
// Extract fromTS and toTS from the current date range
const fH = body.details.timeFrom.slice(0, 2);
const fI = body.details.timeFrom.slice(3, 5);
const fromTS = dayjs(dateRange)
.locale("nl")
.set("hour", +fH)
.set("minute", +fI)
.valueOf();
const toTS = dayjs(fromTS)
.locale("nl")
.add(bookingDifference, "ms")
.valueOf();
// Push into the OR conditions array
orConditions.push({
AND: [
{ tsFrom: { lte: "" + fromTS } },
{ tsTo: { gt: "" + fromTS } },
],
});
orConditions.push({
AND: [{ tsFrom: { lt: "" + toTS } }, { tsTo: { gte: "" + toTS } }],
});
orConditions.push({
AND: [{ tsFrom: { gte: "" + fromTS } }, { tsTo: { lte: "" + toTS } }],
});
});
await checkForOverlappingBookings(orConditions);
if (clashingBookings.length > 0) {
let clashDates = "";
let i = 1;
clashingBookings.map((b) => {
clashDates += `${b.dateFd}-${b.dateFm}-${b.dateFy} (${b.name})`;
if (i != clashingBookings.length) {
clashDates += ", ";
}
i++;
});
return resolve({
body: JSON.stringify({
snackbar: {
type: "error", //success || error || warning || info
title: "Foutcode CRBW220",
text: `De reservering heeft een overlap met ${
clashingBookings.length == 1
? "een bestaande boeking"
: "bestaande boekingen"
} op ${clashDates}.`,
},
}),
});
} else {
(async () => {
for (const dateRange of dateRanges) {
const fH = body.details.timeFrom.slice(0, 2);
const fI = body.details.timeFrom.slice(3, 5);
// Convert dayjs back to prisma format:
const fromTS = dayjs(dateRange)
.locale("nl")
.set("hour", +fH)
.set("minute", +fI)
.valueOf();
const toTS = dayjs(fromTS)
.locale("nl")
.add(bookingDifference, "ms")
.valueOf();
const newFrom = dayjs(fromTS).locale("nl");
const newTo = dayjs(toTS).locale("nl");
let newFday = newFrom.get("date");
let newFmonth = newFrom.get("month") + 1;
let newFyear = newFrom.get("year");
let newTday = newTo.get("date");
let newTmonth = newTo.get("month") + 1;
let newTyear = newTo.get("year");
// create the booking
await prisma.Booking.create({
data: {
name: body.details.name,
description: body.details.description,
tsFrom: "" + fromTS,
dateFd: `${String(newFday).padStart(2, "0")}`,
dateFm: `${String(newFmonth).padStart(2, "0")}`,
dateFy: "" + newFyear,
dateFh: body.details.timeFrom.slice(0, 2),
dateFi: body.details.timeFrom.slice(3, 5),
tsTo: "" + toTS,
dateTd: `${String(newTday).padStart(2, "0")}`,
dateTm: `${String(newTmonth).padStart(2, "0")}`,
dateTy: "" + newTyear,
dateTh: body.details.timeTo.slice(0, 2),
dateTi: body.details.timeTo.slice(3, 5),
},
}).then(async () => {
await prisma.$disconnect();
});
// Pause the loop
await new Promise((resolve) => setTimeout(resolve, 300));
}
})();
}
await writeActionlog();
return resolve({
body: JSON.stringify({
snackbar: {
type: "success", //success || error || warning || info
title: "Succes",
text: "De reserveringen zijn aangemaakt.",
},
}),
});
} catch (error) {
console.log(error);
await prisma.$disconnect();
return {
body: JSON.stringify({
snackbar: {
type: "error", //success || error || warning || info
title: "Foutcode CRBW320",
text: "De reservering kon niet worden aangemaakt.",
},
}),
};
}
});
};
export default createRepeatedBookingWeek;
UPDATE
I’ve created a minified version, still the same issue
import { PrismaClient } from "@prisma/client";
import checkAuth from "./utils/auth";
import dayjs from "dayjs";
import "dayjs/locale/nl";
dayjs.locale("nl");
export default defineEventHandler(async (event) => {
const prisma = new PrismaClient();
const body = await readBody(event);
let response = (async (result) => {
// Else perform main logic here
try {
const el = dayjs();
console.log("el: ", el);
return {
body: JSON.stringify({
snackbar: {
type: "success", //success || error || warning || info
title: "Succes",
text: "De wijzigingen zijn opgeslagen.",
},
}),
};
} catch (error) {
console.log(error);
return {
body: JSON.stringify({
snackbar: {
type: "error", //success || error || warning || info
title: "---",
text: "De wijzigingen konden niet worden opgeslagen.",
},
}),
};
}
})();
return response;
});
Also here, el
is returning ‘en’ as locale.
2
Answers
I think I found the solution.
When exploring the dayjs folder in node_modules, I found out that the locale method is expecting three parameters. So I changed my code to
instead of
and this creates a Dutch dayjs object.
When reading the docs, only the not working version (with only 1 param) is documented. This should be updated!
Reading the documentation here you change the locale locally:
In your context it will be
nl
instead onde
in the example. As you can see you have to include the correct locale before using itIf you want to change it globally you can see here and you will notice you just need to do the require part