Skip to content
39 changes: 34 additions & 5 deletions common/src/__tests__/freebuff-peak-hours.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { describe, expect, test } from 'bun:test'

import {
DEEPSEEK_EXPENSIVE_WINDOW_UTC,
DEEPSEEK_WEEKEND_OFFPEAK_EFFECTIVE_AT_UTC,
deepSeekExpensiveWindowEndsAt,
deepseekPricingWindow,
formatDeepSeekExpensiveWindowLocal,
formatDeepSeekExpensiveWindowReturn,
formatDeepSeekOffPeakWindowLocal,
isBeijingWeekend,
isDeepSeekExpensiveWindow,
} from '../constants/freebuff-peak-hours'

Expand Down Expand Up @@ -67,6 +69,38 @@ describe('the expensive window', () => {
})
})

describe('the Beijing weekend boundary', () => {
test.each([
['2026-08-28T15:00:00Z', false],
['2026-08-28T16:00:00Z', true],
['2026-08-30T15:00:00Z', true],
['2026-08-30T16:00:00Z', false],
])('%s isBeijingWeekend=%p', (instant, weekend) => {
expect(isBeijingWeekend(new Date(instant as string))).toBe(
weekend as boolean,
)
})

test('does not apply the weekend rule before its effective instant', () => {
expect(DEEPSEEK_WEEKEND_OFFPEAK_EFFECTIVE_AT_UTC).toBe(
Date.parse('2026-08-22T16:00:00Z'),
)
expect(deepseekPricingWindow(new Date('2026-08-22T09:59:59Z'))).toBe('peak')
expect(isDeepSeekExpensiveWindow(new Date('2026-08-22T02:00:00Z'))).toBe(
true,
)
})

test('applies the weekend rule from its effective instant onward', () => {
expect(deepseekPricingWindow(new Date('2026-08-23T01:30:00Z'))).toBe(
'off-peak',
)
expect(isDeepSeekExpensiveWindow(new Date('2026-08-23T02:00:00Z'))).toBe(
false,
)
})
})

test.each(['2026-08-29T02:00:00Z', '2026-08-30T02:00:00Z'])(
'%s uses weekend rates in Beijing',
(instant) => {
Expand Down Expand Up @@ -98,8 +132,6 @@ describe('every window names the clock it is quoted in', () => {
insideWindow,
'Europe/Berlin',
)
// The whole bug in one assertion: the digits differ from the UTC rendering,
// so a string that named no zone was wrong for this reader by two hours.
expect(berlin).toContain('12:00 PM')
expect(berlin).not.toContain('10:00 AM')
expect(berlin).toMatch(/GMT\+2|CEST/)
Expand All @@ -118,9 +150,6 @@ describe('every window names the clock it is quoted in', () => {
})

test('an unknown zone falls back to UTC rather than to the host process', () => {
// `timeZone: undefined` resolves to whatever the PROCESS runs in, which is
// the reader in a browser and a Render container on the server. Only the
// explicit argument is deterministic, which is why the server passes one.
expect(formatDeepSeekExpensiveWindowReturn(insideWindow, 'UTC')).toBe(
formatDeepSeekExpensiveWindowReturn(insideWindow, 'Etc/UTC'),
)
Expand Down
43 changes: 38 additions & 5 deletions common/src/constants/freebuff-peak-hours.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
/**
* Peak hours, from api-docs.deepseek.com/quick_start/pricing (read 2026-08-16):
* "Peak hours are 01:00 - 04:00 and 06:00 - 10:00 UTC (all other hours are
* off-peak)." These windows apply Monday-Friday Beijing time; weekends are
* always off-peak.
* off-peak)." These windows apply Monday-Friday Beijing time; from
* `DEEPSEEK_WEEKEND_OFFPEAK_EFFECTIVE_AT_UTC` onward, weekends are off-peak.
*
* Half-open [start, end): 04:00:00 UTC itself is already off-peak. TWO
* disjoint windows, not one — the 04:00-06:00 gap between them is exactly what
Expand All @@ -29,11 +29,40 @@ export const DEEPSEEK_PEAK_HOUR_RANGES_UTC: ReadonlyArray<

export type DeepSeekPricingWindow = 'peak' | 'off-peak'

function isBeijingWeekend(at: Date): boolean {
/**
* DeepSeek announced on its Models & Pricing page that weekend off-peak billing
* would become effective at 00:00 Beijing time on 2026-08-23. Issue #1090
* records that vendor notice and its UTC conversion; the current vendor page
* documents the resulting Monday-Friday peak rule:
* https://api-docs.deepseek.com/quick_start/pricing/
*
* Keep this as an instant rather than a local date so historical billing and
* availability checks use the same boundary in every runtime timezone.
*/
export const DEEPSEEK_WEEKEND_OFFPEAK_EFFECTIVE_AT_UTC = Date.parse(
'2026-08-22T16:00:00Z',
)

/**
* Whether `at` falls on Saturday or Sunday in Beijing time.
*
* China has not observed daylight saving time since 1991, so Beijing's fixed
* UTC+8 offset is intentional here. Do not generalize this arithmetic to zones
* whose UTC offset changes seasonally.
*/
export function isBeijingWeekend(at: Date): boolean {
const beijingDay = new Date(at.getTime() + 8 * 60 * 60 * 1000).getUTCDay()
return beijingDay === 0 || beijingDay === 6
}

/** Whether the all-weekend off-peak rule is active for this instant. */
function isWeekendOffPeakEligible(at: Date): boolean {
return (
at.getTime() >= DEEPSEEK_WEEKEND_OFFPEAK_EFFECTIVE_AT_UTC &&
isBeijingWeekend(at)
)
}

/**
* Which rate card applies at `at`.
*
Expand All @@ -42,7 +71,9 @@ function isBeijingWeekend(at: Date): boolean {
* ceiling), and a hidden `new Date()` would make both untestable.
*/
export function deepseekPricingWindow(at: Date): DeepSeekPricingWindow {
if (isBeijingWeekend(at)) return 'off-peak'
if (isWeekendOffPeakEligible(at)) {
return 'off-peak'
}
const hour = at.getUTCHours()
const peak = DEEPSEEK_PEAK_HOUR_RANGES_UTC.some(
([startHour, endHour]) => hour >= startHour && hour < endHour,
Expand Down Expand Up @@ -86,7 +117,9 @@ export const DEEPSEEK_EXPENSIVE_WINDOW_UTC: readonly [number, number] = [
/** Whether `at` falls in the window above. Half-open like the peak check, so
* the closing hour is already outside it. */
export function isDeepSeekExpensiveWindow(at: Date): boolean {
if (isBeijingWeekend(at)) return false
if (isWeekendOffPeakEligible(at)) {
return false
}
const [start, end] = DEEPSEEK_EXPENSIVE_WINDOW_UTC
const hour = at.getUTCHours()
return hour >= start && hour < end
Expand Down
Loading