Skip to content

Commit

Permalink
Fix early bird utc problem
Browse files Browse the repository at this point in the history
  • Loading branch information
oglimmer committed Mar 22, 2024
1 parent 75cd1f6 commit c7bc924
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 91 deletions.
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"dotenv": "^16.0.3",
"google-auth-library": "^8.7.0",
"googleapis": "^110.0.0",
"moment-timezone": "^0.5.45",
"node-fetch": "^3.3.0",
"node-schedule": "^2.1.1",
"sqlite3": "^5.1.6",
Expand Down
37 changes: 10 additions & 27 deletions src/service/eliteEarlyBirdService.test.ts
Original file line number Diff line number Diff line change
@@ -1,92 +1,75 @@
import { expect, test } from '@jest/globals'
import { parse } from './eliteEarlyBirdService'
import moment = require('moment-timezone')

test('full time - at 13:37', async () => {
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
const result = parse('13:37:37.137')
expect(result).toBeDefined()
if (result) {
expect(result - midnight).toBe(13 * 60 * 60 * 1000 + 37 * 60 * 1000 + 37 * 1000 + 137)
expect(result).toBe(moment.tz('13:37:37.137', 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf())
}
})

test('full time - early morning', async () => {
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
const result = parse('2:37:37.137')
expect(result).toBeDefined()
if (result) {
expect(result - midnight).toBe(2 * 60 * 60 * 1000 + 37 * 60 * 1000 + 37 * 1000 + 137)
expect(result).toBe(moment.tz('02:37:37.137', 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf())
}
})

test('full time - early morning - single digits', async () => {
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
const result = parse('2:02:02.1')
expect(result).toBeDefined()
if (result) {
expect(result - midnight).toBe(2 * 60 * 60 * 1000 + 2 * 60 * 1000 + 2 * 1000 + 100)
expect(result).toBe(moment.tz('02:02:02.100', 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf())
}
})

test('time without millis - early morning - single digits', async () => {
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
const result = parse('2:02:02')
expect(result).toBeDefined()
if (result) {
expect(result - midnight).toBe(2 * 60 * 60 * 1000 + 2 * 60 * 1000 + 2 * 1000)
expect(result).toBe(moment.tz('02:02:02', 'hh:mm:ss', 'Europe/Berlin').valueOf())
}
})

test('time without hour - single digits', async () => {
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
const result = parse('2:02')
expect(result).toBeDefined()
if (result) {
expect(result - midnight).toBe(13 * 60 * 60 * 1000 + 2 * 60 * 1000 + 2 * 1000)
expect(result).toBe(moment.tz('13:02:02', 'hh:mm:ss', 'Europe/Berlin').valueOf())
}
})

test('time just in seconcs', async () => {
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
const result = parse('37')
expect(result).toBeDefined()
if (result) {
expect(result - midnight).toBe(13 * 60 * 60 * 1000 + 37 * 60 * 1000 + 37 * 1000)
expect(result).toBe(moment.tz('13:37:37', 'hh:mm:ss', 'Europe/Berlin').valueOf())
}
})

test('time just in seconcs and millis(3 digit pending 0)', async () => {
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
const result = parse('3.370')
expect(result).toBeDefined()
if (result) {
expect(result - midnight).toBe(13 * 60 * 60 * 1000 + 37 * 60 * 1000 + 3 * 1000 + 370)
expect(result).toBe(moment.tz('13:37:03.370', 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf())
}
})

test('time just in seconcs and millis(2 digits)', async () => {
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
const result = parse('3.37')
expect(result).toBeDefined()
if (result) {
expect(result - midnight).toBe(13 * 60 * 60 * 1000 + 37 * 60 * 1000 + 3 * 1000 + 370)
expect(result).toBe(moment.tz('13:37:03.37', 'hh:mm:ss.SS', 'Europe/Berlin').valueOf())
}
})

test('time just in seconcs and millis(3 digits, leading 0)', async () => {
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
const result = parse('3.037')
expect(result).toBeDefined()
if (result) {
expect(result - midnight).toBe(13 * 60 * 60 * 1000 + 37 * 60 * 1000 + 3 * 1000 + 37)
expect(result).toBe(moment.tz('13:37:03.037', 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf())
}
})
92 changes: 28 additions & 64 deletions src/service/eliteEarlyBirdService.ts
Original file line number Diff line number Diff line change
@@ -1,91 +1,55 @@
import moment from "moment-timezone"

/**
* Converts a time string in German format to UTC time in millis since epoc
*
* @param dateToParse must be a string to parse in German format for the German timezone, e.g. 13:37:37.137
* @returns time in UTC in millis since epoc e.g. 1710419768333 for 13.03.2024 23:05
*/
export function parse(dateToParse: string | number | boolean): undefined | number {
if (typeof dateToParse !== 'string') {
return undefined
}
const now = new Date()
const midnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0).getTime()
if (/^\d{1,2}:\d{1,2}:\d{1,2}\.\d{1,3}$/g.test(dateToParse)) {
const splitByColon = dateToParse.split(':')
if (splitByColon.length !== 3) {
return undefined
}
const hours = parseInt(splitByColon[0])
const minutes = parseInt(splitByColon[1])
const seconds = parseFloat(splitByColon[2])
if (hours < 0 || hours > 23) {
return undefined
}
if (minutes < 0 || minutes > 59) {
return undefined
}
if (seconds < 0 || seconds >= 60) {
return undefined
}
return midnight + (seconds * 1000) + (minutes * 60 * 1000) + (hours * 60 * 60 * 1000)
return moment.tz(dateToParse, 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf()
}
if (/^\d{1,2}:\d{1,2}:\d{1,2}$/g.test(dateToParse)) {
const splitByColon = dateToParse.split(':')
if (splitByColon.length !== 3) {
return undefined
}
const hours = parseInt(splitByColon[0])
const minutes = parseInt(splitByColon[1])
const seconds = parseInt(splitByColon[2])
if (hours < 0 || hours > 23) {
return undefined
}
if (minutes < 0 || minutes > 59) {
return undefined
}
if (seconds < 0 || seconds > 59) {
return undefined
}
return midnight + (seconds * 1000) + (minutes * 60 * 1000) + (hours * 60 * 60 * 1000)
return moment.tz(`${dateToParse}.000`, 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf()
}
if (/^\d{1,2}:\d{1,2}$/g.test(dateToParse)) {
const splitByColon = dateToParse.split(':')
if (splitByColon.length !== 2) {
return undefined
}
const minutes = parseInt(splitByColon[0])
const seconds = parseInt(splitByColon[1])
if (minutes < 0 || minutes > 59) {
return undefined
}
if (seconds < 0 || seconds > 59) {
return undefined
}
return midnight + (seconds * 1000) + (minutes * 60 * 1000) + (13 * 60 * 60 * 1000)
return moment.tz(`13:${dateToParse}.000`, 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf()
}
if (/^\d{1,2}\.\d{1,3}$/g.test(dateToParse)) {
const seconds = parseFloat(dateToParse)
if (seconds < 0 || seconds >= 60) {
return undefined
}
return midnight + (seconds * 1000) + (37 * 60 * 1000) + (13 * 60 * 60 * 1000)
return moment.tz(`13:37:${dateToParse}`, 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf()
}
if (/^\d{1,2}$/g.test(dateToParse)) {
const seconds = parseInt(dateToParse)
if (seconds < 0 || seconds > 59) {
return undefined
}
return midnight + seconds * 1000 + (37 * 60 * 1000) + (13 * 60 * 60 * 1000)
return moment.tz(`13:37:${dateToParse}.000`, 'hh:mm:ss.SSS', 'Europe/Berlin').valueOf()
}
return undefined
}

/**
* Add the penalty time to the playTime (maybe in UTC or any other timezone, so result will be in the same timezone)
*
* @param playTime time in millis since epoc e.g. 1710419768333 for 13.03.2024 23:05
* @returns the valid starting time in millis since epoc e.g. 1710419768333 for 13.03.2024 23:05
*/
export function calcValidFrom(playTime: number): number {
const now = new Date()
if (playTime < 32472190800) {
// playTime is in seconds (and less than 1.1.2999)
playTime = playTime * 1000
}
const now = new Date(Date.now()) // now in UTC date
const berlinDate = new Date(now.toLocaleString('en-US', { timeZone: 'Europe/Berlin' }))
let offset = 999
// rules: Mitternacht tippt sind es 65s, wenn man um 8 Uhr tippt 30s, um 12 Uhr -> 7s, 13 Uhr -> 3s, ab 13:37 dann 0s
if (now.getHours() >= 0 && now.getHours() <= 7) {
if (berlinDate.getHours() >= 0 && berlinDate.getHours() <= 7) {
offset = 65
} else if (now.getHours() >= 8 && now.getHours() <= 11) {
} else if (berlinDate.getHours() >= 8 && berlinDate.getHours() <= 11) {
offset = 30
} else if (now.getHours() === 12) {
} else if (berlinDate.getHours() === 12) {
offset = 7
} else if (now.getHours() === 13) {
} else if (berlinDate.getHours() === 13) {
offset = 3
}
return playTime + offset * 1000
Expand Down

0 comments on commit c7bc924

Please sign in to comment.