Timezone Switching and TimeGutter Slots
See original GitHub issueSo, I’m trying to write support for timezone switching for my calendar. I have a lot of things working, based on comments in an issue. The one thing I cannot get though is the proper min/max time display in the TimeGutter, and a current now
. I’m using the momentLocalizer like so:
// in util file
export const getMoment = timezone => {
const m = (...args) => moment.tz(...args, timezone);
m.localeData = moment.localeData;
return m;
};
// in my calendar wrapper
const moment = getMoment(timezone);
const localizer = momentLocalizer(moment);
// ...
<Calendar
localizer={localizer}
This covers a good chunk of what I’m trying to do. When I switch timezones, my events shift accordingly to their proper timeslot. What fails is in using min
and max
to set the starting and ending hour timeslots on my day
and week
views. These take JS date objects, even though it only appears to need the ‘time’ (and really the 24 hour hour
). Initially I set these like so:
min={new Date(1970,1,1,7,0)}
max={new Date(1970,1,1,18,0)}
I also use getNow
to set the current datetime at render. This also takes a JS date object, and thoughts were that you needed to convert this to the timezone as well:
const convert = m => new Date(m.year(), m.month(), m.date(), m.hour(), m.minute());
...
getNow={() => convert(moment())} // remember, moment now does tz automatically ^
That didn’t do it either. I then saw someone referenced using defaultDate
instead of getNow
:
defaultDate={convert(moment())}
No such luck. What I see is that ‘right now’ it’s October 3rd in Chicago, but ‘right now’ is October 4th in Japan. No matter what I do the highlighted date is always ‘my’ (Chicago) ‘right now’.
So back to times. I then thought that maybe I needed to convert my min
and max
, using the timezone, and then set the hour
:
min={moment().hour(5).minute(0).toDate()}
max={moment().hour(18).minute(0).toDate()}
and that caused complete chaos. Seems to be unnecessary. Especially once I started looking at code…
I got into TimeGrid
and found that dates.merge()
was going to create a new Date object to pass to the TimeGutter
, and in the TimeGutter
I found that the slotMetrics
set up each group. So I went to find out how the slotMetrics
were built and found how it adjusted for DST offset (which is based on the JS Date object, and always relative to current browser date in it’s offset).
So, my localizer couldn’t help me. Or, if it can I have no idea how. The localizer isn’t used for any of these calculations, so they become moot. Or so it seems. If there is a way to do this, I haven’t found it yet. Can anyone help? What combination of settings and localizer solve all of these issues?
General Real-World Use Case: I have an organization that manages scheduling clinic appointments for multiple clinics in multiple timezones. The scheduler managing that scheduling must see a clinic’s schedule in that clinic’s timezone. So if the clinic is in Knoxville (Eastern Time), and is open from 7AM to 5PM, the scheduler (sitting in Memphis, which is Central Time) must see that clinic’s hours as 7AM - 5AM. Should Happen: user views Knoxville clinic schedule, and hours are 7am-5pm Currently Happens: user views Knoxville clinic (which automatically switches tz to Eastern time) and the hours show 8am - 4pm
Issue Analytics
- State:
- Created 4 years ago
- Comments:14 (4 by maintainers)
Top GitHub Comments
OK, I was close ^, unless your
start
andend
occur across different days. To give you a good example of what I mean:let’s say I want to show 24 hours of slots on my
Calendar
, I can do this:and, if my
timezone
is the same as my browser local I am perfectly fine. That’s because my date conversions make:But let’s say I want to set my
timezone
toAmerica/Los Angeles
. This then gives me:Looking at the
date
portion, you see we now span across two separate days. But that’s alright, right? Well, no. As you can see below, this totally messes with the TimeGrid: I had to really dig, to see what was happening, and finally came up with the culprit.TimeGrid
, in it’srenderEvents()
method, includes theDayColumn
and theTimeGutter
with the following attributes:In this the
date
is the currentrange
array item value, andmin
andmax
are what you see above. The problem lies in thedates.merge()
that comes fromutils/dates.js
. It ‘merges’ a date, and a time, without allowing for offset. So changing thetimezone
setsmin
andmax
correctly, but theDayColumn
components gets:As you can see, without the offset this is very, very wrong. These values hit the
TimeSlot.js
getSlotMetrics()
method and blow it all up.@Gaurav7004 Yes, using the dayLayoutAlgorithm prop