diff --git a/format/date.js b/format/date.js index 37e910fa..45091a34 100644 --- a/format/date.js +++ b/format/date.js @@ -1,9 +1,12 @@ 'use strict' -const moment = require('moment-timezone') +const {DateTime} = require('luxon') const formatDate = (profile, when) => { - return moment(when).tz(profile.timezone).format('YYYYMMDD') + return DateTime.fromMillis(+when, { + locale: profile.locale, + zone: profile.timezone + }).toFormat('yyyyMMdd') } module.exports = formatDate diff --git a/format/time.js b/format/time.js index 348f402d..d16b2e8c 100644 --- a/format/time.js +++ b/format/time.js @@ -1,9 +1,12 @@ 'use strict' -const moment = require('moment-timezone') +const {DateTime} = require('luxon') const formatTime = (profile, when) => { - return moment(when).tz(profile.timezone).format('HHmmss') + return DateTime.fromMillis(+when, { + locale: profile.locale, + zone: profile.timezone + }).toFormat('HHmmss') } module.exports = formatTime diff --git a/p/db/index.js b/p/db/index.js index d87fbd23..02210b9d 100644 --- a/p/db/index.js +++ b/p/db/index.js @@ -135,6 +135,7 @@ const formatProducts = (products) => { // todo: find option for absolute number of results const dbProfile = { + locale: 'de-DE', timezone: 'Europe/Berlin', endpoint: 'https://reiseauskunft.bahn.de/bin/mgate.exe', transformReqBody, diff --git a/p/vbb/index.js b/p/vbb/index.js index 355f1189..9cb44899 100644 --- a/p/vbb/index.js +++ b/p/vbb/index.js @@ -116,6 +116,7 @@ const formatProducts = (products) => { } const vbbProfile = { + locale: 'de-DE', timezone: 'Europe/Berlin', endpoint: 'https://fahrinfo.vbb.de/bin/mgate.exe', transformReqBody, diff --git a/package.json b/package.json index e50170d0..546888c9 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "dependencies": { "fetch-ponyfill": "^4.1.0", "lodash": "^4.17.4", - "moment-timezone": "^0.5.13", + "luxon": "^0.2.7", "pinkie-promise": "^2.0.1", "query-string": "^5.0.0", "slugg": "^1.2.0", @@ -41,7 +41,6 @@ "co": "^4.6.0", "db-stations": "^1.25.0", "is-roughly-equal": "^0.1.0", - "luxon": "^0.2.7", "tap-spec": "^4.1.1", "tape": "^4.8.0", "tape-promise": "^2.0.1", diff --git a/parse/date-time.js b/parse/date-time.js index 4c913e1c..4ff6900d 100644 --- a/parse/date-time.js +++ b/parse/date-time.js @@ -1,16 +1,28 @@ 'use strict' -const moment = require('moment-timezone') +const {DateTime} = require('luxon') -const parseDateTime = (timezone, date, time) => { - let offset = 0 // in days - if (time.length > 6) { - offset = +time.slice(0, -6) - time = time.slice(-6) +const validDate = /^(\d{4})-(\d{2})-(\d{2})$/ + +const parseDateTime = (profile, date, time) => { + const pDate = [date.substr(-8, 4), date.substr(-4, 2), date.substr(-2, 2)] + if (!pDate[0] || !pDate[1] || !pDate[2]) { + throw new Error('invalid date format: ' + date) } - return moment.tz(date + 'T' + time, timezone) - .add(offset, 'days') + const pTime = [time.substr(-6, 2), time.substr(-4, 2), time.substr(-2, 2)] + if (!pTime[0] || !pTime[1] || !pTime[2]) { + throw new Error('invalid time format: ' + time) + } + + const offset = time.length > 6 ? parseInt(time.slice(0, -6)) : 0 + + console.error(pDate, pTime, offset) + const dt = DateTime.fromISO(pDate.join('-') + 'T' + pTime.join(':'), { + locale: profile.locale, + zone: profile.timezone + }) + return offset > 0 ? dt.plus({days: offset}) : dt } module.exports = parseDateTime diff --git a/parse/departure.js b/parse/departure.js index 42978a35..7ded8c06 100644 --- a/parse/departure.js +++ b/parse/departure.js @@ -8,11 +8,10 @@ // todo: d.freq, d.freq.jnyL, see https://github.com/derhuerst/hafas-client/blob/9203ed1481f08baacca41ac5e3c19bf022f01b0b/parse.js#L115 const createParseDeparture = (profile, stations, lines, remarks) => { - const tz = profile.timezone const findRemark = rm => remarks[parseInt(rm.remX)] || null const parseDeparture = (d) => { - const when = profile.parseDateTime(tz, d.date, d.stbStop.dTimeR || d.stbStop.dTimeS) + const when = profile.parseDateTime(profile, d.date, d.stbStop.dTimeR || d.stbStop.dTimeS) const res = { journeyId: d.jid, station: stations[parseInt(d.stbStop.locX)] || null, @@ -24,8 +23,8 @@ const createParseDeparture = (profile, stations, lines, remarks) => { } if (d.stbStop.dTimeR && d.stbStop.dTimeS) { - const realtime = profile.parseDateTime(tz, d.date, d.stbStop.dTimeR) - const planned = profile.parseDateTime(tz, d.date, d.stbStop.dTimeS) + const realtime = profile.parseDateTime(profile, d.date, d.stbStop.dTimeR) + const planned = profile.parseDateTime(profile, d.date, d.stbStop.dTimeS) res.delay = Math.round((realtime - planned) / 1000) } else res.delay = null diff --git a/parse/journey-part.js b/parse/journey-part.js index f2483277..a2468067 100644 --- a/parse/journey-part.js +++ b/parse/journey-part.js @@ -5,19 +5,17 @@ const parseDateTime = require('./date-time') const clone = obj => Object.assign({}, obj) const createParseJourneyPart = (profile, stations, lines, remarks) => { - const tz = profile.timezone - const parseStopover = (j, st) => { const res = { station: stations[parseInt(st.locX)] } if (st.aTimeR || st.aTimeS) { - const arr = parseDateTime(tz, j.date, st.aTimeR || st.aTimeS) - res.arrival = arr.format() + const arr = parseDateTime(profile, j.date, st.aTimeR || st.aTimeS) + res.arrival = arr.toISO() } if (st.dTimeR || st.dTimeS) { - const dep = parseDateTime(tz, j.date, st.dTimeR || st.dTimeS) - res.departure = dep.format() + const dep = parseDateTime(profile, j.date, st.dTimeR || st.dTimeS) + res.departure = dep.toISO() } return res @@ -31,18 +29,18 @@ const createParseJourneyPart = (profile, stations, lines, remarks) => { // todo: what is pt.jny.dirFlg? // todo: how does pt.freq work? const parseJourneyPart = (j, pt) => { // j = journey, pt = part - const dep = profile.parseDateTime(tz, j.date, pt.dep.dTimeR || pt.dep.dTimeS) - const arr = profile.parseDateTime(tz, j.date, pt.arr.aTimeR || pt.arr.aTimeS) + const dep = profile.parseDateTime(profile, j.date, pt.dep.dTimeR || pt.dep.dTimeS) + const arr = profile.parseDateTime(profile, j.date, pt.arr.aTimeR || pt.arr.aTimeS) const res = { origin: clone(stations[parseInt(pt.dep.locX)]) || null, destination: clone(stations[parseInt(pt.arr.locX)]), - departure: dep.format(), - arrival: arr.format() + departure: dep.toISO(), + arrival: arr.toISO() } if (pt.dep.dTimeR && pt.dep.dTimeS) { - const realtime = profile.parseDateTime(tz, j.date, pt.dep.dTimeR) - const planned = profile.parseDateTime(tz, j.date, pt.dep.dTimeS) + const realtime = profile.parseDateTime(profile, j.date, pt.dep.dTimeR) + const planned = profile.parseDateTime(profile, j.date, pt.dep.dTimeS) res.delay = Math.round((realtime - planned) / 1000) } @@ -66,10 +64,10 @@ const createParseJourneyPart = (profile, stations, lines, remarks) => { if (pt.jny.freq && pt.jny.freq.jnyL) { const parseAlternative = (a) => { // todo: realtime - const when = profile.parseDateTime(tz, j.date, a.stopL[0].dTimeS) + const when = profile.parseDateTime(profile, j.date, a.stopL[0].dTimeS) return { line: lines[parseInt(a.prodX)] || null, - when: when.format() + when: when.toISO() } } res.alternatives = pt.jny.freq.jnyL diff --git a/parse/journey.js b/parse/journey.js index 21d0f124..7e66d5d3 100644 --- a/parse/journey.js +++ b/parse/journey.js @@ -1,6 +1,5 @@ 'use strict' -const parseDateTime = require('./date-time') const createParseJourneyPart = require('./journey-part') const clone = obj => Object.assign({}, obj) diff --git a/parse/movement.js b/parse/movement.js index 67e3d591..0cd4d1ba 100644 --- a/parse/movement.js +++ b/parse/movement.js @@ -1,8 +1,6 @@ 'use strict' const createParseMovement = (profile, locations, lines, remarks) => { - const tz = profile.timezone - // todo: what is m.dirGeo? maybe the speed? // todo: what is m.stopL? // todo: what is m.proc? wut? @@ -13,10 +11,10 @@ const createParseMovement = (profile, locations, lines, remarks) => { const parseMovement = (m) => { const parseNextStop = (s) => { const dep = s.dTimeR || s.dTimeS - ? profile.parseDateTime(tz, m.date, s.dTimeR || s.dTimeS) + ? profile.parseDateTime(profile, m.date, s.dTimeR || s.dTimeS) : null const arr = s.aTimeR || s.aTimeS - ? profile.parseDateTime(tz, m.date, s.aTimeR || s.aTimeS) + ? profile.parseDateTime(profile, m.date, s.aTimeR || s.aTimeS) : null return { diff --git a/parse/stopover.js b/parse/stopover.js index 09b6a80b..3a0e05d8 100644 --- a/parse/stopover.js +++ b/parse/stopover.js @@ -1,18 +1,16 @@ 'use strict' const createParseStopover = (profile, stations, lines, remarks, connection) => { - const tz = profile.timezone - const parseStopover = (st) => { const res = { station: stations[parseInt(st.locX)] || null } if (st.aTimeR || st.aTimeS) { - const arr = profile.parseDateTime(tz, connection.date, st.aTimeR || st.aTimeS) + const arr = profile.parseDateTime(profile, connection.date, st.aTimeR || st.aTimeS) res.arrival = arr.format() } if (st.dTimeR || st.dTimeS) { - const dep = profile.parseDateTime(tz, connection.date, st.dTimeR || st.dTimeS) + const dep = profile.parseDateTime(profile, connection.date, st.dTimeR || st.dTimeS) res.departure = dep.format() } return res