|
| 1 | +import { |
| 2 | + addDaysToYmd, |
| 3 | + getUtcForZonedTime, |
| 4 | + getZonedParts, |
| 5 | + type ZonedDateParts, |
| 6 | +} from '../util/zoned-time' |
| 7 | + |
1 | 8 | /** |
2 | 9 | * Models a freebuff user can pick between in the waiting-room model selector. |
3 | 10 | * |
@@ -31,18 +38,14 @@ export const FREEBUFF_GLM_MODEL_ID = 'z-ai/glm-5.1' |
31 | 38 | export const FREEBUFF_KIMI_MODEL_ID = 'moonshotai/kimi-k2.6' |
32 | 39 | export const FREEBUFF_MINIMAX_MODEL_ID = 'minimax/minimax-m2.7' |
33 | 40 | export const FREEBUFF_PREMIUM_SESSION_LIMIT = 5 |
34 | | -export const FREEBUFF_PREMIUM_SESSION_WINDOW_HOURS = 20 |
| 41 | +export const FREEBUFF_PREMIUM_SESSION_RESET_TIMEZONE = 'America/Los_Angeles' |
| 42 | +export const FREEBUFF_PREMIUM_SESSION_PERIOD = 'pacific_day' |
| 43 | +/** Deprecated wire compatibility field. Premium usage now resets at midnight |
| 44 | + * Pacific time rather than using a rolling hourly window. */ |
| 45 | +export const FREEBUFF_PREMIUM_SESSION_WINDOW_HOURS = 24 |
35 | 46 | const FREEBUFF_EASTERN_TIMEZONE = 'America/New_York' |
36 | 47 | const FREEBUFF_PACIFIC_TIMEZONE = 'America/Los_Angeles' |
37 | 48 |
|
38 | | -interface ZonedDateParts { |
39 | | - year: number |
40 | | - month: number |
41 | | - day: number |
42 | | - hour: number |
43 | | - minute: number |
44 | | -} |
45 | | - |
46 | 49 | interface LocalTimeFormatOptions { |
47 | 50 | locale?: string |
48 | 51 | timeZone?: string |
@@ -165,79 +168,6 @@ export function getFreebuffModel(id: string): FreebuffModelOption { |
165 | 168 | ) |
166 | 169 | } |
167 | 170 |
|
168 | | -function getZonedParts(date: Date, timeZone: string): ZonedDateParts { |
169 | | - const parts = new Intl.DateTimeFormat('en-US', { |
170 | | - timeZone, |
171 | | - year: 'numeric', |
172 | | - month: '2-digit', |
173 | | - day: '2-digit', |
174 | | - hour: '2-digit', |
175 | | - minute: '2-digit', |
176 | | - hourCycle: 'h23', |
177 | | - }).formatToParts(date) |
178 | | - const value = (type: string) => |
179 | | - parts.find((part) => part.type === type)?.value |
180 | | - const year = Number(value('year') ?? 0) |
181 | | - const month = Number(value('month') ?? 1) |
182 | | - const day = Number(value('day') ?? 1) |
183 | | - const hour = Number(value('hour') ?? 0) |
184 | | - const minute = Number(value('minute') ?? 0) |
185 | | - return { |
186 | | - year, |
187 | | - month, |
188 | | - day, |
189 | | - hour, |
190 | | - minute, |
191 | | - } |
192 | | -} |
193 | | - |
194 | | -function addDaysToYmd( |
195 | | - year: number, |
196 | | - month: number, |
197 | | - day: number, |
198 | | - days: number, |
199 | | -): Pick<ZonedDateParts, 'year' | 'month' | 'day'> { |
200 | | - const next = new Date(Date.UTC(year, month - 1, day)) |
201 | | - next.setUTCDate(next.getUTCDate() + days) |
202 | | - return { |
203 | | - year: next.getUTCFullYear(), |
204 | | - month: next.getUTCMonth() + 1, |
205 | | - day: next.getUTCDate(), |
206 | | - } |
207 | | -} |
208 | | - |
209 | | -function getUtcForZonedTime( |
210 | | - parts: Pick<ZonedDateParts, 'year' | 'month' | 'day'>, |
211 | | - timeZone: string, |
212 | | - hour: number, |
213 | | - minute: number, |
214 | | -): Date { |
215 | | - let guess = new Date( |
216 | | - Date.UTC(parts.year, parts.month - 1, parts.day, hour, minute), |
217 | | - ) |
218 | | - |
219 | | - for (let i = 0; i < 3; i++) { |
220 | | - const actual = getZonedParts(guess, timeZone) |
221 | | - const desiredUtc = Date.UTC( |
222 | | - parts.year, |
223 | | - parts.month - 1, |
224 | | - parts.day, |
225 | | - hour, |
226 | | - minute, |
227 | | - ) |
228 | | - const actualUtc = Date.UTC( |
229 | | - actual.year, |
230 | | - actual.month - 1, |
231 | | - actual.day, |
232 | | - actual.hour, |
233 | | - actual.minute, |
234 | | - ) |
235 | | - guess = new Date(guess.getTime() + (desiredUtc - actualUtc)) |
236 | | - } |
237 | | - |
238 | | - return guess |
239 | | -} |
240 | | - |
241 | 171 | function getNextFreebuffDeploymentStart(now: Date): Date { |
242 | 172 | const easternNow = getZonedParts(now, FREEBUFF_EASTERN_TIMEZONE) |
243 | 173 | const isBeforeTodayOpen = easternNow.hour < 9 |
|
0 commit comments