Feature
This library supports Moment.js and Globalize.js for localization. I was wondering if you had any plans to add other localization libraries, specifically date-fns. Moment is a very powerful library, but it does not offer the same bundle size optimizations as date-fns. There's a great discussion on the differences here. The main benefits of date-fns over Moment are performance and a more optimized bundle.
If this isn't really on your radar, no worries. I may still make an attempt at a PR if that's the case.
@amkoehler I think it's a good idea to allow other alternatives like date-fns. I like date-fns as well and use it with this library outside of the initial setup with moment. It will be nice to see a PR on this if you get around to it!
@amkoehler @arecvlohe I tried to implement RBC localizer for date-fns v1.29.0. I've found the next issues:
Therefore probably it's better to wait for date-fns v2. Let's help date-fns community to update locales for v2: https://github.com/date-fns/date-fns/blob/master/outdatedLocales.json
I would also really like to see support for different packages. I need to use luxon, which is going to be moment's predecessor. Moment.js is taboo here because of optimization..
We aren't likely to support a lot of options out of box, but the API is pluggable specifically so folks can use whatever they want @GavinThomas1192 can you give a Luxon localizer a shot and if there are api failings please report back.
Yes, this will be my priority tomorrow! Iβve spent about a week implementing a super custom react big calendar and would really like to be able to use all of my work. So this is a high priority. My company absolutely wonβt allow me to use moment
Inspired by some conversation in #118, Here's a first swag at a luxon localizer. Hasn't been tested enough for me to call it bulletproof, but it seems to work so far in a quick smoke test.
import { set } from 'react-big-calendar/lib/formats'
import { set as setLocalizer } from 'react-big-calendar/lib/localizer'
import dates from 'react-big-calendar/lib/utils/dates'
const dateRangeFormat = ({ start, end }, culture, local) =>
`${local.format(start, 'D', culture)} β ${local.format(end, 'D', culture)}`
const timeRangeFormat = ({ start, end }, culture, local) =>
`${local.format(start, 't', culture)} β ${local.format(end, 't', culture)}`
const timeRangeStartFormat = ({ start }, culture, local) =>
`${local.format(start, 't', culture)} β `
const timeRangeEndFormat = ({ end }, culture, local) => ` β ${local.format(end, 't', culture)}`
const weekRangeFormat = ({ start, end }, culture, local) =>
`${local.format(start, 'MMMM dd', culture)} - ${local.format(
end,
dates.eq(start, end, 'month') ? 'dd' : 'MMMM dd',
culture
)}`
export const formats = {
dateFormat: 'dd',
dayFormat: 'dd EEE',
weekdayFormat: 'ccc',
selectRangeFormat: timeRangeFormat,
eventTimeRangeFormat: timeRangeFormat,
eventTimeRangeStartFormat: timeRangeStartFormat,
eventTimeRangeEndFormat: timeRangeEndFormat,
timeGutterFormat: 't',
monthHeaderFormat: 'MMMM yyyy',
dayHeaderFormat: 'dddd MMM dd',
dayRangeHeaderFormat: weekRangeFormat,
agendaHeaderFormat: dateRangeFormat,
agendaDateFormat: 'EEE MMM dd',
agendaTimeFormat: 't',
agendaTimeRangeFormat: timeRangeFormat,
}
export default function(DateTime, { firstDayOfWeek }) {
const locale = (d, c) => (c ? d.reconfigure(c) : d)
set(formats)
return setLocalizer({
firstOfWeek() {
return firstDayOfWeek
},
parse(value, format, culture) {
return locale(DateTime.fromFormat(value, format), culture).toJSDate()
},
format(value, format, culture) {
return locale(DateTime.fromJSDate(value), culture).toFormat(format)
},
})
}
LuxonLocalizer(DateTime, { firstDayOfWeek: 0 })
Thank you @ltegman, really hoping this works well. I really would love to be able to display a calendar based on a set time zone, and not the time zone of the client's browser. (ie. issue #118)
Could you please provide a bit more detail about how exactly you use this with react-big-calendar?
Right now I am using moment like this:
import moment from 'moment';
import BigCalendar from 'react-big-calendar';
import 'react-big-calendar/lib/css/react-big-calendar.css';
const localizer = BigCalendar.momentLocalizer(moment);
then on my calendar component:
<BigCalendar
localizer={localizer}
events={this.state.events}
startAccessor="start"
endAccessor="end"
/>
How exactly would I import the code and attach the LuxonLocalizer as per your example above?
Thanks for the help if possible. π
@adueck I'm also interested in date-fns support. There is a pull request you can look at, they are waiting for date-fns v2 to come out of alpha before they merge it, but it has been in alpha for so long, they can just as well add it. https://github.com/intljusticemission/react-big-calendar/pull/855
@steph4nc Not sure how clean this, but I actually made a work around that works great for me. I am adjusting the date/times in all the events based on the offset from the the timezone in the client's browser.
function calculateTimeDifference() {
const testDate = new Date();
const timezoneOffset = testDate.getTimezoneOffset();
const calendarTimeOffset = -120; // THE TIMEZONE OFFSET FROM THE TIMEZONE YOU WANT THE CALENDAR TO DISPLAY IN
return (timezoneOffset - calendarTimeOffset) / 60;
}
const timeDifference = calculateTimeDifference();
this.setState({ timeDifference: timeDifference });
// Adjust all the events in state according to the client's difference in time from desired calendar time
this.setState(prevState => {
const adjusted = prevState.events;
adjusted.forEach(event => {
event.start = new Date(event.start.setHours(event.start.getHours() + timeDifference));
event.end = new Date(event.end.setHours(event.end.getHours() + timeDifference));
});
return { events: adjusted };
});
This can also be applied to the clicking and dragging creation of events, to adjust their times accordingly
handleSelect({start, end}) {
const title = window.prompt('New Event name');
if (title) {
// Add event to db (compensating for users timezone offset)
const eventToSubmit = {
title: title,
start: new Date(start.setHours(start.getHours() - this.state.timeDifference)),
end: new Date(end.setHours(end.getHours() - this.state.timeDifference))
};
fetch(`${apiUrl}events`,
{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(eventToSubmit),
credentials: "include"
}).then((res) => res.json())
.then((res) => {
// Add event to state - with id for event returned from db
const _id = res._id
const adjustedStart = new Date(start.setHours(start.getHours() + this.state.timeDifference));
const adjustedEnd = new Date(end.setHours(end.getHours() + this.state.timeDifference));
this.setState({ events: [...this.state.events,
{
start,
end,
title,
_id
},],});
});
}
}
Can't personally vouch for it but have read about Day.Js as an alternative
β° Day.js 2KB immutable date library alternative to Moment.js with the same modern API
https://github.com/iamkun/dayjs
reference: moment/moment#2373 (comment)
@xxyuk We are planning to migrate to https://github.com/dmtrKovalenko/date-io as interop layer which supports day.js and date-fns.
@TrySound do you have a timeline on that?
Not yet. Would you like to help?
I do have a day week our company donates to open source :) How big of a project is it?
Are there plans to support Luxon for localization?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
PR for Luxon localizer is RFR here: https://github.com/intljusticemission/react-big-calendar/pull/1574
Can't say whether it will be merged or not, but wanted to point this conversation to it.
@jquense I don't know what your availability is but I would love to see this PR reviewed and released! (just a nudge to help get it over the finish line)
Most helpful comment
Inspired by some conversation in #118, Here's a first swag at a luxon localizer. Hasn't been tested enough for me to call it bulletproof, but it seems to work so far in a quick smoke test.