Weird collection's date bug!

Hello everone :raised_hand_with_fingers_splayed:

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.

Any thoughts? Is it a bug or what?

Thanks in advance.
Ahmad

It’s probably a matter of time zone.

Hey @jonatandor35 :raised_hand_with_fingers_splayed: Thank you for your reply!

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?

console log the birthday column value directly with console.log(birthday)

If it shows a string like ā€˜Indian Standard Time’ then as JD said, its about timezone.

@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.

Hey Shan, thank you for your reply!

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.

You are definitely stumbling over time zone issues.

First, in the site settings, you can pick UTC times or local times for the collection DATE/TIME entries. I highly recommend to use UTC.

Then, get the user’s browser time offset from UTC.
https://www.w3schools.com/JSREF/jsref_gettimezoneoffset.asp

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.

Good luck.

Where can i select UTC as Date and Time format for Collections?

Looked for it, and all I found was this updated setting, which I suppose covers the time zone that all collections on the site use:

Dashboard > Settings > Language & Region > Site Region > Time Zone