Skip to content

Commit 906dc67

Browse files
committed
convert everything to UTC
1 parent c940169 commit 906dc67

File tree

5 files changed

+35
-32
lines changed

5 files changed

+35
-32
lines changed

apps/sim/lib/billing/core/billing-periods.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ describe('Billing Period Calculations', () => {
7676

7777
const period = calculateBillingPeriod()
7878

79-
expect(period.start.getFullYear()).toBe(2024)
80-
expect(period.start.getMonth()).toBe(6) // July (0-indexed)
81-
expect(period.start.getDate()).toBe(1)
82-
expect(period.end.getFullYear()).toBe(2024)
83-
expect(period.end.getMonth()).toBe(6) // July (0-indexed)
84-
expect(period.end.getDate()).toBe(31)
79+
expect(period.start.getUTCFullYear()).toBe(2024)
80+
expect(period.start.getUTCMonth()).toBe(6) // July (0-indexed)
81+
expect(period.start.getUTCDate()).toBe(1)
82+
expect(period.end.getUTCFullYear()).toBe(2024)
83+
expect(period.end.getUTCMonth()).toBe(6) // July (0-indexed)
84+
expect(period.end.getUTCDate()).toBe(31)
8585
})
8686
})
8787

@@ -103,8 +103,8 @@ describe('Billing Period Calculations', () => {
103103
const nextPeriod = calculateNextBillingPeriod(periodEnd)
104104

105105
expect(nextPeriod.start).toEqual(periodEnd)
106-
// JavaScript's setMonth handles overflow: Jan 31 + 1 month = Mar 2 (Feb 29 + 2 days in 2024)
107-
expect(nextPeriod.end.getMonth()).toBe(2) // March (0-indexed) due to overflow
106+
// JavaScript's setUTCMonth handles overflow: Jan 31 + 1 month = Mar 2 (Feb 29 + 2 days in 2024)
107+
expect(nextPeriod.end.getUTCMonth()).toBe(2) // March (0-indexed) due to overflow
108108
})
109109
})
110110

@@ -150,7 +150,7 @@ describe('Billing Period Calculations', () => {
150150
vi.setSystemTime(today)
151151

152152
const endingTomorrow = new Date(today)
153-
endingTomorrow.setDate(endingTomorrow.getDate() + 1)
153+
endingTomorrow.setUTCDate(endingTomorrow.getUTCDate() + 1)
154154

155155
const shouldBill = endingTomorrow.toDateString() === today.toDateString()
156156

@@ -162,7 +162,7 @@ describe('Billing Period Calculations', () => {
162162
vi.setSystemTime(today)
163163

164164
const endedYesterday = new Date(today)
165-
endedYesterday.setDate(endedYesterday.getDate() - 1)
165+
endedYesterday.setUTCDate(endedYesterday.getUTCDate() - 1)
166166

167167
const shouldBill = endedYesterday.toDateString() === today.toDateString()
168168

apps/sim/lib/billing/core/billing-periods.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ export function calculateBillingPeriod(
7474

7575
// Fallback: Default monthly billing period (1st to last day of month)
7676
// This should only be used for users without proper subscription data
77-
const start = new Date(now.getFullYear(), now.getMonth(), 1)
78-
const end = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999)
77+
const start = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1))
78+
const end = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 0, 23, 59, 59, 999))
7979

8080
logger.warn('Using fallback calendar month billing period', {
8181
start,

apps/sim/lib/billing/core/billing.test.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,16 @@ describe('Billing Core Functions', () => {
7979
vi.setSystemTime(new Date('2024-07-15T10:00:00Z'))
8080
const result = calculateBillingPeriod()
8181

82-
// Should return current calendar month
82+
// Should return current calendar month (1st to last day of current month)
8383
expect(result.start.getUTCFullYear()).toBe(2024)
8484
expect(result.start.getUTCMonth()).toBe(6) // July (0-indexed)
8585
expect(result.start.getUTCDate()).toBe(1) // Should start on 1st of month
8686
expect(result.end.getUTCFullYear()).toBe(2024)
87-
expect(result.end.getUTCMonth()).toBe(7) // August (0-indexed)
88-
expect(result.end.getUTCDate()).toBe(1) // Should end on 1st of next month
87+
expect(result.end.getUTCMonth()).toBe(6) // July (0-indexed) - ends on last day of current month
88+
expect(result.end.getUTCDate()).toBe(31) // Should end on last day of July
89+
expect(result.end.getUTCHours()).toBe(23) // Should end at 23:59:59.999
90+
expect(result.end.getUTCMinutes()).toBe(59)
91+
expect(result.end.getUTCSeconds()).toBe(59)
8992
})
9093

9194
it.concurrent('handles subscription anniversary date correctly', () => {
@@ -110,18 +113,18 @@ describe('Billing Core Functions', () => {
110113
const currentPeriodEnd = new Date('2024-07-15T23:59:59Z')
111114
const result = calculateNextBillingPeriod(currentPeriodEnd)
112115

113-
expect(result.start.getDate()).toBe(15)
114-
expect(result.start.getMonth()).toBe(6) // July (0-indexed)
115-
expect(result.end.getDate()).toBe(15)
116-
expect(result.end.getMonth()).toBe(7) // August (0-indexed)
116+
expect(result.start.getUTCDate()).toBe(15)
117+
expect(result.start.getUTCMonth()).toBe(6) // July (0-indexed)
118+
expect(result.end.getUTCDate()).toBe(15)
119+
expect(result.end.getUTCMonth()).toBe(7) // August (0-indexed)
117120
})
118121

119122
it.concurrent('handles month boundary correctly', () => {
120123
const currentPeriodEnd = new Date('2024-01-31T23:59:59Z')
121124
const result = calculateNextBillingPeriod(currentPeriodEnd)
122125

123-
expect(result.start.getMonth()).toBe(0) // January
124-
expect(result.end.getMonth()).toBeGreaterThanOrEqual(1) // February or later due to month overflow
126+
expect(result.start.getUTCMonth()).toBe(0) // January
127+
expect(result.end.getUTCMonth()).toBeGreaterThanOrEqual(1) // February or later due to month overflow
125128
})
126129
})
127130

@@ -227,8 +230,8 @@ describe('Billing Core Functions', () => {
227230
const janEnd = new Date('2024-01-31T00:00:00Z')
228231
const result = calculateNextBillingPeriod(janEnd)
229232

230-
expect(result.start.getMonth()).toBe(0) // January
231-
expect(result.end.getMonth()).toBeGreaterThanOrEqual(1) // February or later due to month overflow
233+
expect(result.start.getUTCMonth()).toBe(0) // January
234+
expect(result.end.getUTCMonth()).toBeGreaterThanOrEqual(1) // February or later due to month overflow
232235
})
233236

234237
it.concurrent('handles leap year correctly', () => {
@@ -247,10 +250,10 @@ describe('Billing Core Functions', () => {
247250
const decEnd = new Date('2024-12-15T00:00:00Z')
248251
const result = calculateNextBillingPeriod(decEnd)
249252

250-
expect(result.start.getFullYear()).toBe(2024)
251-
expect(result.start.getMonth()).toBe(11) // December
252-
expect(result.end.getFullYear()).toBe(2025)
253-
expect(result.end.getMonth()).toBe(0) // January
253+
expect(result.start.getUTCFullYear()).toBe(2024)
254+
expect(result.start.getUTCMonth()).toBe(11) // December
255+
expect(result.end.getUTCFullYear()).toBe(2025)
256+
expect(result.end.getUTCMonth()).toBe(0) // January
254257
})
255258

256259
it.concurrent('basic date calculations work', () => {

apps/sim/lib/billing/core/billing.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,9 +452,9 @@ export async function getUsersAndOrganizationsForOverageBilling(): Promise<{
452452
}> {
453453
try {
454454
const today = new Date()
455-
today.setHours(0, 0, 0, 0) // Start of today
455+
today.setUTCHours(0, 0, 0, 0) // Start of today
456456
const tomorrow = new Date(today)
457-
tomorrow.setDate(tomorrow.getDate() + 1) // Start of tomorrow
457+
tomorrow.setUTCDate(tomorrow.getUTCDate() + 1) // Start of tomorrow
458458

459459
logger.info('Checking for subscriptions with billing periods ending today', {
460460
today: today.toISOString(),
@@ -480,7 +480,7 @@ export async function getUsersAndOrganizationsForOverageBilling(): Promise<{
480480

481481
if (sub.periodEnd) {
482482
const periodEnd = new Date(sub.periodEnd)
483-
periodEnd.setHours(0, 0, 0, 0) // Normalize to start of day
483+
periodEnd.setUTCHours(0, 0, 0, 0) // Normalize to start of day
484484

485485
// Bill if the subscription period ends today
486486
if (periodEnd.getTime() === today.getTime()) {
@@ -503,7 +503,7 @@ export async function getUsersAndOrganizationsForOverageBilling(): Promise<{
503503

504504
if (userStatsRecord.length > 0 && userStatsRecord[0].billingPeriodEnd) {
505505
const billingPeriodEnd = new Date(userStatsRecord[0].billingPeriodEnd)
506-
billingPeriodEnd.setHours(0, 0, 0, 0) // Normalize to start of day
506+
billingPeriodEnd.setUTCHours(0, 0, 0, 0) // Normalize to start of day
507507

508508
if (billingPeriodEnd.getTime() === today.getTime()) {
509509
shouldBillToday = true

apps/sim/lib/billing/webhooks/stripe-invoice-webhooks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ async function sendInvoiceNotificationEmail(invoice: Stripe.Invoice, invoiceAmou
288288
const billingPeriod = invoice.metadata?.billingPeriod || 'this month'
289289
const plan = invoice.metadata?.plan || 'your plan'
290290
const dueDate = invoice.due_date
291-
? new Date(invoice.due_date * 1000).toLocaleDateString()
291+
? new Date(invoice.due_date * 1000).toISOString().split('T')[0]
292292
: 'immediately'
293293
const invoiceUrl = invoice.hosted_invoice_url || undefined
294294

0 commit comments

Comments
 (0)