Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Time Zone support using localizer date math #2023

Merged
merged 39 commits into from
Sep 28, 2021
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f7b48fe
Merge pull request #1 from intljusticemission/master
cutterbl May 6, 2019
50f71cb
Merge pull request #3 from intljusticemission/master
cutterbl May 7, 2019
681bedc
Merge pull request #4 from intljusticemission/master
cutterbl May 7, 2019
2e5a585
Merge pull request #5 from intljusticemission/master
cutterbl May 8, 2019
310b1f2
Merge pull request #6 from intljusticemission/master
cutterbl May 9, 2019
c738deb
Merge pull request #7 from intljusticemission/master
cutterbl May 9, 2019
8fb4b14
Merge remote-tracking branch 'upstream/master'
cutterbl Feb 6, 2020
90a5afb
Merge remote-tracking branch 'upstream/master'
cutterbl Feb 18, 2020
41b3333
Merge remote-tracking branch 'upstream/master'
cutterbl Sep 25, 2020
f94992c
Merge remote-tracking branch 'upstream/master'
cutterbl Aug 17, 2021
851937e
full timezone support with moment
cutterbl Aug 26, 2021
f2a9da8
chore: remove comment
cutterbl Aug 26, 2021
9207d21
chore: Add timeswitching example
cutterbl Aug 26, 2021
364cc5d
chore: continued tz efforts
cutterbl Aug 27, 2021
0ab14e6
chore(timezones): Finalize core bits for handling timezones
cutterbl Sep 8, 2021
683756c
docs: Add documentation
cutterbl Sep 8, 2021
a10ec3b
chore: CI tests don't like modern syntax
cutterbl Sep 8, 2021
ef98246
chore: Move DST calculations in to the localizers
cutterbl Sep 8, 2021
94b9934
chore: Further refine math from localizer
cutterbl Sep 9, 2021
345e709
chore: Further refine localizer date math around same date comparison
cutterbl Sep 9, 2021
eb0a156
chore: Finalize all date methods being called from localizer
cutterbl Sep 9, 2021
0d6f27d
chore: Corrections to momentLocalizer getEventRange
cutterbl Sep 9, 2021
fdaaaff
chore: Refine and use moment comparison operations
cutterbl Sep 9, 2021
f6de14e
chore: general cleanup
cutterbl Sep 9, 2021
c922e49
chore: Rebuild examples
cutterbl Sep 9, 2021
5ecee40
fix: Correct moment localizer range() method, to ensure all dates han…
cutterbl Sep 10, 2021
e8f2144
chore: Use clearer variable name
cutterbl Sep 10, 2021
c62ec6d
fix: Correct method return
cutterbl Sep 10, 2021
da6c037
fix: Correct usages of let and const for better GC and immutability
cutterbl Sep 10, 2021
6b46e43
feat: Add a new luxonLocalizer and expand documentation
cutterbl Sep 10, 2021
1374714
tests: Tested for the new luxonLocalizer
cutterbl Sep 10, 2021
389c8fa
chore: Bundle examples
cutterbl Sep 10, 2021
d290734
chore: Reset the examples script from local ip usage
cutterbl Sep 10, 2021
77de5b8
fix: startOfWeek/endOfWeek calculations
cutterbl Sep 15, 2021
490e0c8
chore: fix comment
cutterbl Sep 15, 2021
d30eee4
fix: Remove that localIp bit again
cutterbl Sep 15, 2021
72c817a
chore: General cleanup
cutterbl Sep 17, 2021
6d17ef9
fix: Correct luxon endOfWeek
cutterbl Sep 17, 2021
2865f76
fix: Correct endOfDTWeek
cutterbl Sep 19, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions .size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
{
"./dist/react-big-calendar.js": {
"bundled": 497580,
"minified": 153472,
"gzipped": 47831
"bundled": 514520,
"minified": 159064,
"gzipped": 49416
},
"./dist/react-big-calendar.min.js": {
"bundled": 428485,
"minified": 132196,
"gzipped": 42237
"bundled": 444958,
"minified": 137402,
"gzipped": 43760
},
"dist/react-big-calendar.esm.js": {
"bundled": 185554,
"minified": 87500,
"gzipped": 21669,
"bundled": 200687,
"minified": 92979,
"gzipped": 23164,
"treeshaked": {
"rollup": {
"code": 62542,
"import_statements": 1590
"code": 63894,
"import_statements": 1556
},
"webpack": {
"code": 67195
"code": 67481
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions examples/App.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import Api from './Api'
import Intro from './Intro.md'
import TimezoneIntro from './Timezones.md'
import { render } from 'react-dom'
import Layout from 'react-tackle-box/Layout'

Expand All @@ -20,6 +21,8 @@ import BackgroundEvents from './demos/backgroundEvents'
import Selectable from './demos/selectable'
import CreateEventWithNoOverlap from './demos/createEventWithNoOverlap'
import Cultures from './demos/cultures'
import Timezones from './demos/timezones'
import Luxon from './demos/luxon'
import Popup from './demos/popup'
import Rendering from './demos/rendering'
import CustomView from './demos/customView'
Expand All @@ -40,7 +43,9 @@ const EXAMPLES = {
basic: 'Basic Calendar',
selectable: 'Create events',
createEventWithNoOverlap: 'Create events with no-overlap algorithm',
timezones: 'Timezones',
cultures: 'Localization',
luxon: 'Luxon Localizer',
popup: 'Show more via a popup',
timeslots: 'Custom Time Grids',
rendering: 'Customized Component Rendering',
Expand Down Expand Up @@ -78,7 +83,9 @@ class Example extends React.Component {
basic: Basic,
backgroundEvents: BackgroundEvents,
selectable: Selectable,
timezones: Timezones,
cultures: Cultures,
luxon: Luxon,
popup: Popup,
rendering: Rendering,
customView: CustomView,
Expand Down Expand Up @@ -163,6 +170,9 @@ class Example extends React.Component {
<div className="contain section">
<Intro />
</div>
<div className="contain section">
<TimezoneIntro />
</div>
<Api className="contain section" />
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions examples/Intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ element has a height, or the calendar won't be visible (see why below).

Date internationalization and localization is **hard** and `react-big-calendar` doesn't even attempt to
solve that problem. Instead you can use one of the many excellent solutions already
out there, via adapters called "localizers". Big Calendar comes with two localizers for use
with [Globalize.js](https://github.com/jquery/globalize) or [Moment.js](http://momentjs.com/).
out there, via adapters called "localizers". Big Calendar comes with three localizers for use
with [Globalize.js](https://github.com/jquery/globalize), [Moment.js](http://momentjs.com/) or [Luxon](https://moment.github.io/luxon).

Choose the localizer that best suits your needs, or write your own. Whatever you do, you'll need to set it up
before you can use the calendar (you only need to set it up once).
Expand All @@ -24,7 +24,7 @@ before you can use the calendar (you only need to set it up once).
import { Calendar, momentLocalizer } from 'react-big-calendar'
import moment from 'moment'

// Setup the localizer by providing the moment (or globalize) Object
// Setup the localizer by providing the moment (or globalize, or Luxon) Object
// to the correct localizer.
const localizer = momentLocalizer(moment) // or globalizeLocalizer

Expand Down
48 changes: 48 additions & 0 deletions examples/TimezoneSelect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react'
import PropTypes from 'prop-types'
import Layout from 'react-tackle-box/Layout'
import moment from 'moment'
import 'moment-timezone'

import ExampleControlSlot from './ExampleControlSlot'

const allZones = moment.tz.names()
allZones.unshift('clear')

export default function TimezoneSelect({
title,
defaultTZ = moment.tz.guess(),
timezone,
setTimezone,
}) {
const onChange = ({ target: { value } }) =>
setTimezone(value ? value : defaultTZ)

return (
<ExampleControlSlot.Entry waitForOutlet>
<Layout direction="column" align="center">
{title ? <h4>{title}</h4> : null}
<label>Select a Timezone</label>{' '}
<select
className="form-control"
style={{ width: 200, display: 'inline-block' }}
value={timezone}
onChange={onChange}
>
{allZones.map((c, idx) => (
<option key={idx} value={c !== 'clear' ? c : ''}>
{c}
</option>
))}
</select>
</Layout>
</ExampleControlSlot.Entry>
)
}

TimezoneSelect.propTypes = {
title: PropTypes.string,
defaultTZ: PropTypes.string,
timezone: PropTypes.string,
setTimezone: PropTypes.func,
}
33 changes: 33 additions & 0 deletions examples/Timezones.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# <a id='timezonesIntro' href='#timezoneIntro'>Dealing With Time Zones</a>

Time Zones are... **hard**, and while changing the `culture` will help with internationalization and localization, it does not adjust the dates for a specific time zone. Javascript Date objects don't really support time zone switching natively, and date math gets **very** complicated. Thankfully `react-big-calender` does support `moment` as a localizer, so if you use [moment-timezone](https://momentjs.com/timezone/) you can get your events to display relevant to a time zone other than the browser native.

To change your events to display as a specific time zone, you must [change moment's default timezone](https://momentjs.com/timezone/docs/#/using-timezones/default-timezone/) for all dates, **using an IANA time zone**.

```jsx
import { Calendar, momentLocalizer } from 'react-big-calendar'
import moment from 'moment'
import 'moment-timezone' // or 'moment-timezone/builds/moment-timezone-with-data[-datarange].js'. See their docs

// Set the IANA time zone you want to use
moment.tz.setDefault('Europe/Paris')

// Setup the localizer by providing the moment Object
// to the correct localizer.
const localizer = momentLocalizer(moment) // or globalizeLocalizer

const MyCalendar = props => (
<div>
<Calendar
localizer={localizer}
events={myEventsList}
startAccessor="start"
endAccessor="end"
/>
</div>
)
```

The `momentLocalizer` will now handle all dates and date math as if the date is in the timezone you specified. It is important to note that [changing moment's default timezone](https://momentjs.com/timezone/docs/#/using-timezones/default-timezone/) affects all dates, created by moment, from that point forward, so you may want to reset the default when your component unmounts. And, if switching timezones 'on-the-fly', you want to update your 'localizer' and any Date based props (min, max, getNow, etc) at the same time.

**Note:** The new `luxonLocalizer` operates in a similar fashion. View the 'Luxon Localizer' demo and view it's source for an example of it's usage.
Loading