feat: convert from using dst offsets to use timezone code
feat: select timezones from current selected country
This commit is contained in:
parent
cc8c48ff4c
commit
7d6fb17158
16 changed files with 86 additions and 117 deletions
10
lib/logs.js
10
lib/logs.js
|
|
@ -1,5 +1,6 @@
|
||||||
const _ = require('lodash/fp')
|
const _ = require('lodash/fp')
|
||||||
const moment = require('moment')
|
const { format } = require('date-fns')
|
||||||
|
const { zonedTimeToUtc, utcToZonedTime } = require('date-fns-tz')
|
||||||
|
|
||||||
const db = require('./db')
|
const db = require('./db')
|
||||||
const pgp = require('pg-promise')()
|
const pgp = require('pg-promise')()
|
||||||
|
|
@ -112,10 +113,13 @@ function simpleGetMachineLogs (deviceId, from = new Date(0).toISOString(), until
|
||||||
}
|
}
|
||||||
|
|
||||||
function logDateFormat (timezone, logs, fields) {
|
function logDateFormat (timezone, logs, fields) {
|
||||||
const offset = timezone.split(':')[1]
|
|
||||||
|
|
||||||
return _.map(log => {
|
return _.map(log => {
|
||||||
const values = _.map(field => moment.utc(log[field]).utcOffset(parseInt(offset)).format('YYYY-MM-DDTHH:mm:ss.SSS'), fields)
|
const values = _.map(
|
||||||
|
field =>
|
||||||
|
format(utcToZonedTime(zonedTimeToUtc(log[field], process.env.TZ), timezone), 'yyyy-MM-ddTHH:mm:ss.SSS'),
|
||||||
|
fields
|
||||||
|
)
|
||||||
const fieldsToOverride = _.zipObject(fields, values)
|
const fieldsToOverride = _.zipObject(fields, values)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ function plugins (settings, deviceId) {
|
||||||
const localeConfig = configManager.getLocale(deviceId, settings.config)
|
const localeConfig = configManager.getLocale(deviceId, settings.config)
|
||||||
const fiatCode = localeConfig.fiatCurrency
|
const fiatCode = localeConfig.fiatCurrency
|
||||||
const cryptoCodes = localeConfig.cryptoCurrencies
|
const cryptoCodes = localeConfig.cryptoCurrencies
|
||||||
const timezone = localeConfig.timezone.split(':')
|
const timezone = localeConfig.timezone
|
||||||
|
|
||||||
const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c))
|
const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c))
|
||||||
const balancePromises = cryptoCodes.map(c => fiatBalance(fiatCode, c))
|
const balancePromises = cryptoCodes.map(c => fiatBalance(fiatCode, c))
|
||||||
|
|
@ -239,13 +239,12 @@ function plugins (settings, deviceId) {
|
||||||
const currentConfigVersionPromise = fetchCurrentConfigVersion()
|
const currentConfigVersionPromise = fetchCurrentConfigVersion()
|
||||||
const currentAvailablePromoCodes = loyalty.getNumberOfAvailablePromoCodes()
|
const currentAvailablePromoCodes = loyalty.getNumberOfAvailablePromoCodes()
|
||||||
const supportsBatchingPromise = cryptoCodes.map(c => wallet.supportsBatching(settings, c))
|
const supportsBatchingPromise = cryptoCodes.map(c => wallet.supportsBatching(settings, c))
|
||||||
const timezoneObj = { utcOffset: timezone[0], dstOffset: timezone[1] }
|
|
||||||
|
|
||||||
const promises = [
|
const promises = [
|
||||||
buildAvailableCassettes(),
|
buildAvailableCassettes(),
|
||||||
pingPromise,
|
pingPromise,
|
||||||
currentConfigVersionPromise,
|
currentConfigVersionPromise,
|
||||||
timezoneObj
|
timezone
|
||||||
].concat(
|
].concat(
|
||||||
supportsBatchingPromise,
|
supportsBatchingPromise,
|
||||||
tickerPromises,
|
tickerPromises,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ const { getCustomerById } = require('../customers')
|
||||||
const machineLoader = require('../machine-loader')
|
const machineLoader = require('../machine-loader')
|
||||||
const { loadLatestConfig } = require('../new-settings-loader')
|
const { loadLatestConfig } = require('../new-settings-loader')
|
||||||
|
|
||||||
|
const { zonedTimeToUtc, utcToZonedTime } = require('date-fns-tz')
|
||||||
|
|
||||||
function updateCustomer (req, res, next) {
|
function updateCustomer (req, res, next) {
|
||||||
const id = req.params.id
|
const id = req.params.id
|
||||||
const machineVersion = req.query.version
|
const machineVersion = req.query.version
|
||||||
|
|
@ -129,14 +131,12 @@ function buildSms (data, receiptOptions) {
|
||||||
.then(([customer, deviceConfig]) => {
|
.then(([customer, deviceConfig]) => {
|
||||||
const formattedTx = _.mapKeys(_.camelCase)(tx)
|
const formattedTx = _.mapKeys(_.camelCase)(tx)
|
||||||
const localeConfig = configManager.getLocale(formattedTx.deviceId, config)
|
const localeConfig = configManager.getLocale(formattedTx.deviceId, config)
|
||||||
const timezone = localeConfig.timezone.split(':')
|
const timezone = localeConfig.timezone
|
||||||
const dstOffset = timezone[1]
|
|
||||||
|
|
||||||
const cashInCommission = new BN(1).plus(new BN(formattedTx.commissionPercentage))
|
const cashInCommission = new BN(1).plus(new BN(formattedTx.commissionPercentage))
|
||||||
|
|
||||||
const rate = new BN(formattedTx.rawTickerPrice).multipliedBy(cashInCommission).decimalPlaces(2)
|
const rate = new BN(formattedTx.rawTickerPrice).multipliedBy(cashInCommission).decimalPlaces(2)
|
||||||
const date = new Date()
|
const date = utcToZonedTime(zonedTimeToUtc(new Date(), process.env.TZ), timezone)
|
||||||
date.setMinutes(date.getMinutes() + parseInt(dstOffset))
|
|
||||||
const dateString = `${date.toISOString().replace('T', ' ').slice(0, 19)}`
|
const dateString = `${date.toISOString().replace('T', ' ').slice(0, 19)}`
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
|
|
|
||||||
10
new-lamassu-admin/package-lock.json
generated
10
new-lamassu-admin/package-lock.json
generated
|
|
@ -10465,6 +10465,16 @@
|
||||||
"whatwg-url": "^8.0.0"
|
"whatwg-url": "^8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"date-fns": {
|
||||||
|
"version": "2.26.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.26.0.tgz",
|
||||||
|
"integrity": "sha512-VQI812dRi3cusdY/fhoBKvc6l2W8BPWU1FNVnFH9Nttjx4AFBRzfSVb/Eyc7jBT6e9sg1XtAGsYpBQ6c/jygbg=="
|
||||||
|
},
|
||||||
|
"date-fns-tz": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.1.6.tgz",
|
||||||
|
"integrity": "sha512-nyy+URfFI3KUY7udEJozcoftju+KduaqkVfwyTIE0traBiVye09QnyWKLZK7drRr5h9B7sPJITmQnS3U6YOdQg=="
|
||||||
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
"classnames": "2.2.6",
|
"classnames": "2.2.6",
|
||||||
"countries-and-timezones": "^2.4.0",
|
"countries-and-timezones": "^2.4.0",
|
||||||
"d3": "^6.2.0",
|
"d3": "^6.2.0",
|
||||||
|
"date-fns": "^2.26.0",
|
||||||
|
"date-fns-tz": "^1.1.6",
|
||||||
"downshift": "3.3.4",
|
"downshift": "3.3.4",
|
||||||
"file-saver": "2.0.2",
|
"file-saver": "2.0.2",
|
||||||
"formik": "2.2.0",
|
"formik": "2.2.0",
|
||||||
|
|
@ -36,8 +38,8 @@
|
||||||
"react": "^16.12.0",
|
"react": "^16.12.0",
|
||||||
"react-copy-to-clipboard": "^5.0.2",
|
"react-copy-to-clipboard": "^5.0.2",
|
||||||
"react-dom": "^16.10.2",
|
"react-dom": "^16.10.2",
|
||||||
"react-material-ui-carousel": "^2.2.7",
|
|
||||||
"react-dropzone": "^11.4.2",
|
"react-dropzone": "^11.4.2",
|
||||||
|
"react-material-ui-carousel": "^2.2.7",
|
||||||
"react-number-format": "^4.4.1",
|
"react-number-format": "^4.4.1",
|
||||||
"react-otp-input": "^2.3.0",
|
"react-otp-input": "^2.3.0",
|
||||||
"react-router-dom": "5.1.2",
|
"react-router-dom": "5.1.2",
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,12 @@ const GraphTooltip = ({
|
||||||
formatDate(
|
formatDate(
|
||||||
dateInterval[1],
|
dateInterval[1],
|
||||||
null,
|
null,
|
||||||
period.code === 'day' ? 'MMM D, HH:mm' : 'MMM D'
|
period.code === 'day' ? 'MMM d, HH:mm' : 'MMM d'
|
||||||
),
|
),
|
||||||
formatDate(
|
formatDate(
|
||||||
dateInterval[0],
|
dateInterval[0],
|
||||||
null,
|
null,
|
||||||
period.code === 'day' ? 'HH:mm' : 'MMM D'
|
period.code === 'day' ? 'HH:mm' : 'MMM d'
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Box } from '@material-ui/core'
|
import { Box } from '@material-ui/core'
|
||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
|
import { getTimezoneOffset } from 'date-fns-tz'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
|
|
@ -47,7 +48,7 @@ const HourOfDayBarGraphHeader = ({
|
||||||
cashOut: <div className={classes.cashOutIcon}></div>
|
cashOut: <div className={classes.cashOutIcon}></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
const offset = parseInt(timezone.split(':')[1]) * MINUTE
|
const offset = getTimezoneOffset(timezone)
|
||||||
|
|
||||||
const txsPerWeekday = R.reduce(
|
const txsPerWeekday = R.reduce(
|
||||||
(acc, value) => {
|
(acc, value) => {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import * as d3 from 'd3'
|
import * as d3 from 'd3'
|
||||||
|
import { getTimezoneOffset } from 'date-fns-tz'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react'
|
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react'
|
||||||
|
|
@ -38,7 +39,7 @@ const Graph = ({
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
const offset = parseInt(timezone.split(':')[1]) * MINUTE
|
const offset = getTimezoneOffset(timezone)
|
||||||
|
|
||||||
const getTickIntervals = (domain, interval) => {
|
const getTickIntervals = (domain, interval) => {
|
||||||
const ticks = []
|
const ticks = []
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import * as d3 from 'd3'
|
import * as d3 from 'd3'
|
||||||
|
import { getTimezoneOffset } from 'date-fns-tz'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react'
|
import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react'
|
||||||
|
|
@ -40,7 +41,7 @@ const Graph = ({
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
const offset = parseInt(timezone.split(':')[1]) * MINUTE
|
const offset = getTimezoneOffset(timezone)
|
||||||
const NOW = Date.now() + offset
|
const NOW = Date.now() + offset
|
||||||
|
|
||||||
const periodDomains = {
|
const periodDomains = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import * as d3 from 'd3'
|
import * as d3 from 'd3'
|
||||||
|
import { getTimezoneOffset } from 'date-fns-tz'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import React, { useEffect, useRef, useCallback } from 'react'
|
import React, { useEffect, useRef, useCallback } from 'react'
|
||||||
|
|
||||||
|
|
@ -11,7 +12,7 @@ const RefScatterplot = ({ data: realData, timeFrame, timezone }) => {
|
||||||
const margin = { top: 25, right: 0, bottom: 25, left: 15 }
|
const margin = { top: 25, right: 0, bottom: 25, left: 15 }
|
||||||
const width = 555 - margin.left - margin.right
|
const width = 555 - margin.left - margin.right
|
||||||
const height = 150 - margin.top - margin.bottom
|
const height = 150 - margin.top - margin.bottom
|
||||||
const dstOffset = parseInt(timezone.split(':')[1])
|
const offset = getTimezoneOffset(timezone)
|
||||||
// finds maximum value for the Y axis. Minimum value is 100. If value is multiple of 1000, add 100
|
// finds maximum value for the Y axis. Minimum value is 100. If value is multiple of 1000, add 100
|
||||||
// (this is because the Y axis looks best with multiples of 100)
|
// (this is because the Y axis looks best with multiples of 100)
|
||||||
const findMaxY = () => {
|
const findMaxY = () => {
|
||||||
|
|
@ -32,7 +33,7 @@ const RefScatterplot = ({ data: realData, timeFrame, timezone }) => {
|
||||||
default:
|
default:
|
||||||
return moment
|
return moment
|
||||||
.utc(v)
|
.utc(v)
|
||||||
.add(dstOffset, 'minutes')
|
.add(offset, 'minutes')
|
||||||
.format('HH:mm')
|
.format('HH:mm')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,8 @@ const Locales = ({ name: SCREEN_KEY }) => {
|
||||||
setValue(curr)
|
setValue(curr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('config', config)
|
||||||
|
|
||||||
const onEditingDefault = (it, editing) => setEditingDefault(editing)
|
const onEditingDefault = (it, editing) => setEditingDefault(editing)
|
||||||
const onEditingOverrides = (it, editing) => setEditingOverrides(editing)
|
const onEditingOverrides = (it, editing) => setEditingOverrides(editing)
|
||||||
|
|
||||||
|
|
@ -187,7 +189,7 @@ const Locales = ({ name: SCREEN_KEY }) => {
|
||||||
save={handleSave}
|
save={handleSave}
|
||||||
validationSchema={LocaleSchema}
|
validationSchema={LocaleSchema}
|
||||||
data={R.of(locale)}
|
data={R.of(locale)}
|
||||||
elements={mainFields(data, onChangeCoin)}
|
elements={mainFields(data, onChangeCoin, R.of(locale))}
|
||||||
setEditing={onEditingDefault}
|
setEditing={onEditingDefault}
|
||||||
forceDisable={isEditingOverrides}
|
forceDisable={isEditingOverrides}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
import * as ct from 'countries-and-timezones'
|
import * as ct from 'countries-and-timezones'
|
||||||
|
// import { useFormikContext } from 'formik'
|
||||||
import * as R from 'ramda'
|
import * as R from 'ramda'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
|
|
||||||
import Autocomplete from 'src/components/inputs/formik/Autocomplete.js'
|
import Autocomplete from 'src/components/inputs/formik/Autocomplete.js'
|
||||||
import { getTzLabels } from 'src/utils/timezones'
|
// import { getTzLabels } from 'src/utils/timezones'
|
||||||
|
|
||||||
const getFields = (getData, names, onChange, auxElements = []) => {
|
const getFields = (getData, names, onChange, auxElements = [], locale) => {
|
||||||
return R.filter(
|
return R.filter(
|
||||||
it => R.includes(it.name, names),
|
it => R.includes(it.name, names),
|
||||||
allFields(getData, onChange, auxElements)
|
allFields(getData, onChange, auxElements, locale)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const allFields = (getData, onChange, auxElements = []) => {
|
const allFields = (getData, onChange, auxElements = [], locale) => {
|
||||||
const getView = (data, code, compare) => it => {
|
const getView = (data, code, compare) => it => {
|
||||||
if (!data) return ''
|
if (!data) return ''
|
||||||
|
|
||||||
|
|
@ -33,14 +34,19 @@ const allFields = (getData, onChange, auxElements = []) => {
|
||||||
const suggestionFilter = it =>
|
const suggestionFilter = it =>
|
||||||
R.differenceWith((x, y) => x.deviceId === y, it, overridenMachines)
|
R.differenceWith((x, y) => x.deviceId === y, it, overridenMachines)
|
||||||
|
|
||||||
|
const localeData = (locale && locale[0]) || {}
|
||||||
|
|
||||||
const machineData = getData(['machines'])
|
const machineData = getData(['machines'])
|
||||||
const countryData = getData(['countries'])
|
const countryData = getData(['countries'])
|
||||||
const currencyData = getData(['currencies'])
|
const currencyData = getData(['currencies'])
|
||||||
const languageData = getData(['languages'])
|
const languageData = getData(['languages'])
|
||||||
const cryptoData = getData(['cryptoCurrencies'])
|
const cryptoData = getData(['cryptoCurrencies'])
|
||||||
const timezonesData = R.values(ct.getAllTimezones())
|
|
||||||
|
|
||||||
const tzLabels = getTzLabels(timezonesData)
|
const countryTimezones = ct.getTimezonesForCountry(localeData?.country) ?? []
|
||||||
|
const timezonesData =
|
||||||
|
R.values(
|
||||||
|
countryTimezones.map(it => ({ label: it.name, code: it.name })) ?? []
|
||||||
|
) ?? []
|
||||||
|
|
||||||
const findSuggestion = it => {
|
const findSuggestion = it => {
|
||||||
const machine = R.find(R.propEq('deviceId', it.machine))(machineData)
|
const machine = R.find(R.propEq('deviceId', it.machine))(machineData)
|
||||||
|
|
@ -117,10 +123,10 @@ const allFields = (getData, onChange, auxElements = []) => {
|
||||||
name: 'timezone',
|
name: 'timezone',
|
||||||
width: 320,
|
width: 320,
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
view: getView(tzLabels, 'label'),
|
view: getView(timezonesData, 'label'),
|
||||||
input: Autocomplete,
|
input: Autocomplete,
|
||||||
inputProps: {
|
inputProps: {
|
||||||
options: tzLabels,
|
options: timezonesData,
|
||||||
valueProp: 'code',
|
valueProp: 'code',
|
||||||
labelProp: 'label'
|
labelProp: 'label'
|
||||||
}
|
}
|
||||||
|
|
@ -128,13 +134,15 @@ const allFields = (getData, onChange, auxElements = []) => {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const mainFields = (auxData, configureCoin) => {
|
const mainFields = (auxData, configureCoin, locale) => {
|
||||||
const getData = R.path(R.__, auxData)
|
const getData = R.path(R.__, auxData)
|
||||||
|
|
||||||
return getFields(
|
return getFields(
|
||||||
getData,
|
getData,
|
||||||
['country', 'fiatCurrency', 'languages', 'cryptoCurrencies', 'timezone'],
|
['country', 'fiatCurrency', 'languages', 'cryptoCurrencies', 'timezone'],
|
||||||
configureCoin
|
configureCoin,
|
||||||
|
undefined,
|
||||||
|
locale
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ const Transactions = () => {
|
||||||
{
|
{
|
||||||
header: 'Date (UTC)',
|
header: 'Date (UTC)',
|
||||||
view: it =>
|
view: it =>
|
||||||
timezone && formatDate(it.created, timezone, 'YYYY-MM-DD HH:mm:ss'),
|
timezone && formatDate(it.created, timezone, 'yyyy-MM-dd HH:mm:ss'),
|
||||||
textAlign: 'right',
|
textAlign: 'right',
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
width: 195
|
width: 195
|
||||||
|
|
|
||||||
|
|
@ -1,89 +1,23 @@
|
||||||
import moment from 'moment'
|
import { format } from 'date-fns'
|
||||||
import * as R from 'ramda'
|
import { zonedTimeToUtc, utcToZonedTime } from 'date-fns-tz'
|
||||||
|
// import moment from 'moment'
|
||||||
|
// import * as R from 'ramda'
|
||||||
|
|
||||||
const getPossibleUTCDSTPairs = timezones =>
|
// const buildLabel = tz => {
|
||||||
R.map(
|
// return `(UTC${tz.utcOffsetStr}) ${R.map(it => it.city, tz.cities).join(', ')}`
|
||||||
it => ({
|
// }
|
||||||
utcOffset: it.utcOffset,
|
|
||||||
dstOffset: it.dstOffset,
|
|
||||||
utcOffsetStr: it.utcOffsetStr,
|
|
||||||
dstOffsetStr: it.dstOffsetStr
|
|
||||||
}),
|
|
||||||
R.uniqBy(
|
|
||||||
it => [it.utcOffset, it.dstOffset, it.utcOffsetStr, it.dstOffsetStr],
|
|
||||||
timezones
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
const getFormattedTimezones = timezones =>
|
const formatDate = (date, timezone, pattern) => {
|
||||||
R.sort(
|
const browserTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone
|
||||||
R.ascend(R.prop('utcOffset')),
|
const newDate = utcToZonedTime(
|
||||||
R.map(
|
zonedTimeToUtc(date, browserTimezone),
|
||||||
it => ({
|
timezone
|
||||||
utcOffset: it.utcOffset,
|
|
||||||
dstOffset: it.dstOffset,
|
|
||||||
utcOffsetStr: it.utcOffsetStr,
|
|
||||||
dstOffsetStr: it.dstOffsetStr,
|
|
||||||
cities: R.map(
|
|
||||||
ite => {
|
|
||||||
const regionCityPair = R.split('/', ite.name)
|
|
||||||
return {
|
|
||||||
region: regionCityPair[0],
|
|
||||||
city: R.replace(/_/g, ' ', regionCityPair[1]),
|
|
||||||
country: ite.country
|
|
||||||
}
|
|
||||||
},
|
|
||||||
R.filter(
|
|
||||||
itx =>
|
|
||||||
R.eqProps('utcOffset', it, itx) &&
|
|
||||||
R.eqProps('dstOffset', it, itx) &&
|
|
||||||
!R.isNil(itx.country) &&
|
|
||||||
!R.includes('Etc', itx.name) &&
|
|
||||||
R.includes('/', itx.name),
|
|
||||||
timezones
|
|
||||||
)
|
)
|
||||||
)
|
return format(newDate, pattern)
|
||||||
}),
|
|
||||||
getPossibleUTCDSTPairs(timezones)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
const getFinalTimezones = timezones => {
|
|
||||||
const formattedTimezones = getFormattedTimezones(timezones)
|
|
||||||
const nonEmptyTimezones = R.filter(
|
|
||||||
it => !R.isEmpty(it.cities),
|
|
||||||
formattedTimezones
|
|
||||||
)
|
|
||||||
const nonDuplicateCities = R.map(
|
|
||||||
it => ({
|
|
||||||
...it,
|
|
||||||
cities: R.uniqBy(R.prop('country'), R.uniqBy(R.prop('city'), it.cities))
|
|
||||||
}),
|
|
||||||
nonEmptyTimezones
|
|
||||||
)
|
|
||||||
return nonDuplicateCities
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildLabel = tz => {
|
const formatDateNonUtc = (date, pattern) => {
|
||||||
return `(UTC${tz.utcOffsetStr}) ${R.map(it => it.city, tz.cities).join(', ')}`
|
return format(date, pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getTzLabels = timezones =>
|
export { formatDate, formatDateNonUtc }
|
||||||
R.map(
|
|
||||||
it => ({ label: buildLabel(it), code: `${it.utcOffset}:${it.dstOffset}` }),
|
|
||||||
getFinalTimezones(timezones)
|
|
||||||
)
|
|
||||||
|
|
||||||
const formatDate = (date, timezoneCode, format) => {
|
|
||||||
const dstOffset = timezoneCode?.split(':')[1] ?? 0
|
|
||||||
return moment
|
|
||||||
.utc(date)
|
|
||||||
.utcOffset(parseInt(dstOffset))
|
|
||||||
.format(format)
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatDateNonUtc = (date, format) => {
|
|
||||||
return moment(date).format(format)
|
|
||||||
}
|
|
||||||
|
|
||||||
export { getTzLabels, formatDate, formatDateNonUtc }
|
|
||||||
|
|
|
||||||
12
package-lock.json
generated
12
package-lock.json
generated
|
|
@ -8464,10 +8464,14 @@
|
||||||
"integrity": "sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ=="
|
"integrity": "sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ=="
|
||||||
},
|
},
|
||||||
"date-fns": {
|
"date-fns": {
|
||||||
"version": "2.16.1",
|
"version": "2.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz",
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.26.0.tgz",
|
||||||
"integrity": "sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ==",
|
"integrity": "sha512-VQI812dRi3cusdY/fhoBKvc6l2W8BPWU1FNVnFH9Nttjx4AFBRzfSVb/Eyc7jBT6e9sg1XtAGsYpBQ6c/jygbg=="
|
||||||
"dev": true
|
},
|
||||||
|
"date-fns-tz": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.1.6.tgz",
|
||||||
|
"integrity": "sha512-nyy+URfFI3KUY7udEJozcoftju+KduaqkVfwyTIE0traBiVye09QnyWKLZK7drRr5h9B7sPJITmQnS3U6YOdQg=="
|
||||||
},
|
},
|
||||||
"date-time": {
|
"date-time": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
"cookie-parser": "^1.4.3",
|
"cookie-parser": "^1.4.3",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dataloader": "^2.0.0",
|
"dataloader": "^2.0.0",
|
||||||
|
"date-fns": "^2.26.0",
|
||||||
|
"date-fns-tz": "^1.1.6",
|
||||||
"ethereumjs-tx": "^1.3.3",
|
"ethereumjs-tx": "^1.3.3",
|
||||||
"ethereumjs-util": "^5.2.0",
|
"ethereumjs-util": "^5.2.0",
|
||||||
"ethereumjs-wallet": "^0.6.3",
|
"ethereumjs-wallet": "^0.6.3",
|
||||||
|
|
@ -68,8 +70,8 @@
|
||||||
"pify": "^3.0.0",
|
"pify": "^3.0.0",
|
||||||
"pretty-ms": "^2.1.0",
|
"pretty-ms": "^2.1.0",
|
||||||
"promise-sequential": "^1.1.1",
|
"promise-sequential": "^1.1.1",
|
||||||
"request-promise": "^4.2.6",
|
|
||||||
"queue-promise": "^2.2.1",
|
"queue-promise": "^2.2.1",
|
||||||
|
"request-promise": "^4.2.6",
|
||||||
"semver": "^7.1.3",
|
"semver": "^7.1.3",
|
||||||
"serve-static": "^1.12.4",
|
"serve-static": "^1.12.4",
|
||||||
"socket.io": "^2.0.3",
|
"socket.io": "^2.0.3",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue