Skip to content

Commit ed48e48

Browse files
authored
Fix outlook day groups in different timezone (#170)
1 parent f2c241a commit ed48e48

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

src/features/outlook/OutlookTable.tsx

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { addDays, eachHourOfInterval, startOfDay } from "date-fns";
22
import { findValue, NWSWeather } from "../../services/nwsWeather";
3-
import { Weather } from "../weather/weatherSlice";
3+
import { timeZoneSelector, Weather } from "../weather/weatherSlice";
44
import { OpenMeteoWeather } from "../../services/openMeteo";
55
import { useMemo } from "react";
66
import OutlookRow from "./OutlookRow";
77
import compact from "lodash/fp/compact";
88
import styled from "@emotion/styled";
99
import Day from "./Day";
10+
import { TZDate } from "@date-fns/tz";
11+
import { useAppSelector } from "../../hooks";
1012

1113
const Rows = styled.div``;
1214

@@ -15,6 +17,7 @@ interface OutlookTableProps {
1517
}
1618

1719
function getOutlook(
20+
timeZone: string,
1821
mapFn: (hour: Date, index: number) => React.ReactNode | undefined,
1922
) {
2023
const hours = eachHourOfInterval({
@@ -27,26 +30,41 @@ function getOutlook(
2730
);
2831

2932
return Object.entries(
30-
Object.groupBy(data, ({ hour }) => startOfDay(hour).getTime()),
33+
Object.groupBy(data, ({ hour }) =>
34+
startOfDay(new TZDate(hour, timeZone)).getTime(),
35+
),
3136
).map(([timeStr, hours]) => ({
3237
date: new Date(+timeStr),
3338
hours: hours!.map(({ node }) => node),
3439
}));
3540
}
3641

3742
export default function OutlookTable({ weather }: OutlookTableProps) {
43+
const timeZone = useAppSelector(timeZoneSelector);
44+
if (!timeZone) throw new Error("timeZone needed");
45+
3846
const rows = (() => {
39-
if ("properties" in weather) return <NWSOutlookRows weather={weather} />;
40-
return <OpenMeteoOutlookRows weather={weather} />;
47+
if ("properties" in weather)
48+
return <NWSOutlookRows weather={weather} timeZone={timeZone} />;
49+
return <OpenMeteoOutlookRows weather={weather} timeZone={timeZone} />;
4150
})();
4251

4352
return <Rows>{rows}</Rows>;
4453
}
4554

46-
function NWSOutlookRows({ weather }: { weather: NWSWeather }) {
55+
interface BaseOutlookRowsProps {
56+
timeZone: string;
57+
}
58+
59+
function NWSOutlookRows({
60+
weather,
61+
timeZone,
62+
}: BaseOutlookRowsProps & {
63+
weather: NWSWeather;
64+
}) {
4765
const days = useMemo(
4866
() =>
49-
getOutlook((hour, index) => {
67+
getOutlook(timeZone, (hour, index) => {
5068
const windDirection = findValue(
5169
hour,
5270
weather.properties.windDirection,
@@ -80,17 +98,23 @@ function NWSOutlookRows({ weather }: { weather: NWSWeather }) {
8098
/>
8199
);
82100
}),
83-
[weather],
101+
[weather, timeZone],
84102
);
85103

86104
return days.map(({ date, hours }, index) => (
87105
<Day key={index} date={date} hours={hours} />
88106
));
89107
}
90-
function OpenMeteoOutlookRows({ weather }: { weather: OpenMeteoWeather }) {
108+
109+
function OpenMeteoOutlookRows({
110+
weather,
111+
timeZone,
112+
}: BaseOutlookRowsProps & {
113+
weather: OpenMeteoWeather;
114+
}) {
91115
const days = useMemo(
92116
() =>
93-
getOutlook((hour, index) => {
117+
getOutlook(timeZone, (hour, index) => {
94118
const data = weather.byUnixTimestamp[hour.getTime() / 1_000];
95119

96120
if (!data) return;
@@ -108,7 +132,7 @@ function OpenMeteoOutlookRows({ weather }: { weather: OpenMeteoWeather }) {
108132
/>
109133
);
110134
}),
111-
[weather],
135+
[weather, timeZone],
112136
);
113137

114138
return days.map(({ date, hours }, index) => (

0 commit comments

Comments
 (0)