I have an app that collects the birthdays of people and represent it in a repeater, the problem is that exctracted value from the date always differ that what it actually is, hereās what I mean.
Hereās the code that produces this:
let birthdayToday = [];
const today = new Date();
const day = today.toLocaleDateString('en-US', {day: 'numeric'})
const month = today.toLocaleDateString('en-US', {month: 'short'})
console.warn(`Today is ${day} ${month} 2020`)
contacts.items.forEach(contact => {
let contactDay = contact.birthday.toLocaleDateString('en-US', {day: 'numeric'})
let contactMon = contact.birthday.toLocaleDateString('en-US', {month: 'short'})
console.log(`Contact birthday: ${contactDay} ${contactMon}`)
if ( (day === contactDay) && (month === contactMon) ) { birthdayToday.push(contact) }
})
console.info(birthdayToday)
The first three (3) items in the database have their day to 9, which is today, but when getting their value they become 8 is in the console, and obviously, not items were pushed in the new array.
I did also the getDate() and getMonth() methods but they gave the same weird behaviour - a one month before (notice the picture below).
Also notice that the day that was assigned by code (not extracted from the collection) was correct in both methods. The issue occure when pulling data from the database.
I donāt think it has anything to do with time zone since all of the dates were converted to local date strings, so regardless of the time zone of each date, all of them should displayed in the correct format of the specified time zone (en-IL), am I correct?
@ahmadnasriya I really believe itās a matter of timezone.
The time as you see it in database is probably UTC while the time logged to the console is your timezone.
As youāre located in GMT + 3 (itās daylight savings time), you can try, for the sake of the experiment to change the hour in the database to 3:00 am and see if itās still happening.
@jonatandor35 Yes youāre right, I used a regular data selector to collect birthdays, and indeed theyāre saved in UTC format.
If thatās the case, how can site visitors submit dates in their local time zone? If thatās even possible of course.
UPDATE : The difference between the UTC and my time zone is 3 hours at the moment (daylight saving), while the standard time is GMT+2, which what Wix used when I inserted these test birthdays, if Wix handled the date added in the correct time zone value (3 hours) - GMT+3 - instead of 2 hours, then everything would have worked.
As a way around, I checked if the current time zone is in daylight saving or not, if it is then I add a one hour when checking the values to the birthday.
The original birthday is not saved as a local date, it doesnāt have any ā standard timeā or something, here are all the birthdays logged to the console as they are in the database.
However, it wasnāt completely about the time zones themselvese, Wix added 2 hours to the UTC date when adding the date into the database, but when getting todayās Date() it returnes the the correct current time zone, which is GMT+3.
So all birthdays were registered as 02:00am, and when comparing with the current time zone they were considered yesterdays, adding one hour to the registered time to become 03:00am solves the issue, but itās not practical to edit each entry indivisually.
One idea I came up with is to add an after insert hook to add that one hour, or add it when checking the values.
The getTimezoneOffset() method returns the time difference between UTC time and local time, in minutes.
Adjust the collection DATE/TIME object with the getTimezoneOffset() minutes.
So, for each DOB you want to use , youād have to do something like this:
(you can abbreviate this code as needed - complete breakdown for demo)
// ======================================================
// get user dob
// ======================================================
// user.dob is the value from the collection
let userDob1 = new Date(user.dob);
//console.log("stored user dob from db: " + userDob1);
// set dob utc
let dob = new Date(userDob1);
let offsetMinutesDOB = dob.getTimezoneOffset();
let offsetHoursDOB = offsetMinutesDOB/60;
let utcYearDOB = dob.getUTCFullYear();
let utcMonthDOB = dob.getUTCMonth(); // 0 index
let utcDateDOB = dob.getUTCDate();
let utcHoursDOB = dob.getUTCHours();
let utcMinutesDOB = dob.getUTCMinutes();
var utcDOB = new Date(Date.UTC(utcYearDOB,utcMonthDOB,utcDateDOB,offsetHoursDOB));
user.dob = utcDOB;
// ================== end of get DOB ================
This way, no matter what time zone your user is in, you are always displaying the correct dates:
UTC from collection + UTC time zone offset
(for DOB, etc.).
When writing dates to the collection, you can ensure proper time offset with a before insert hook.
For testing with a Windows machine, change the OS time and observe how the browser time changes. With the proper offset applied, the intended date does not change.