add time formats
This commit is contained in:
@@ -527,7 +527,8 @@ export default {
|
||||
try {
|
||||
return this.formatDate(
|
||||
this.modelValue === '{{date}}' ? new Date() : new Date(this.modelValue),
|
||||
this.field.preferences?.format || (this.locale.endsWith('-US') ? 'MM/DD/YYYY' : 'DD/MM/YYYY')
|
||||
this.field.preferences?.format || (this.locale.endsWith('-US') ? 'MM/DD/YYYY' : 'DD/MM/YYYY'),
|
||||
{ withTimePlaceholders: this.modelValue === '{{date}}' }
|
||||
)
|
||||
} catch {
|
||||
return this.modelValue
|
||||
@@ -646,36 +647,55 @@ export default {
|
||||
return number
|
||||
}
|
||||
},
|
||||
formatDate (date, format) {
|
||||
const monthFormats = {
|
||||
M: 'numeric',
|
||||
MM: '2-digit',
|
||||
MMM: 'short',
|
||||
MMMM: 'long'
|
||||
}
|
||||
formatDate (date, format, { withTimePlaceholders = false } = {}) {
|
||||
const monthFormats = { M: 'numeric', MM: '2-digit', MMM: 'short', MMMM: 'long' }
|
||||
const dayFormats = { D: 'numeric', DD: '2-digit' }
|
||||
const yearFormats = { YYYY: 'numeric', YYY: 'numeric', YY: '2-digit' }
|
||||
const hourFormats = { H: 'numeric', HH: '2-digit', h: 'numeric', hh: '2-digit' }
|
||||
const minuteFormats = { m: 'numeric', mm: '2-digit' }
|
||||
const secondFormats = { s: 'numeric', ss: '2-digit' }
|
||||
|
||||
const dayFormats = {
|
||||
D: 'numeric',
|
||||
DD: '2-digit'
|
||||
}
|
||||
const hasTime = /[HhAasz]/.test(format)
|
||||
|
||||
const yearFormats = {
|
||||
YYYY: 'numeric',
|
||||
YYY: 'numeric',
|
||||
YY: '2-digit'
|
||||
}
|
||||
|
||||
const parts = new Intl.DateTimeFormat([], {
|
||||
const opts = {
|
||||
day: dayFormats[format.match(/D+/)],
|
||||
month: monthFormats[format.match(/M+/)],
|
||||
year: yearFormats[format.match(/Y+/)],
|
||||
timeZone: 'UTC'
|
||||
}).formatToParts(date)
|
||||
year: yearFormats[format.match(/Y+/)]
|
||||
}
|
||||
|
||||
return format
|
||||
.replace(/D+/, parts.find((p) => p.type === 'day').value)
|
||||
.replace(/M+/, parts.find((p) => p.type === 'month').value)
|
||||
.replace(/Y+/, parts.find((p) => p.type === 'year').value)
|
||||
if (format.match(/H+/)) { opts.hour = hourFormats[format.match(/H+/)[0]]; opts.hour12 = false }
|
||||
if (format.match(/h+/)) { opts.hour = hourFormats[format.match(/h+/)[0]]; opts.hour12 = true }
|
||||
if (/[Aa]/.test(format) && opts.hour12 === undefined) opts.hour12 = true
|
||||
if (format.match(/m+/)) opts.minute = minuteFormats[format.match(/m+/)[0]]
|
||||
if (format.match(/s+/)) opts.second = secondFormats[format.match(/s+/)[0]]
|
||||
if (/z/.test(format)) opts.timeZoneName = 'short'
|
||||
if (!hasTime) opts.timeZone = 'UTC'
|
||||
|
||||
const partTypes = {
|
||||
M: 'month',
|
||||
D: 'day',
|
||||
Y: 'year',
|
||||
H: 'hour',
|
||||
h: 'hour',
|
||||
m: 'minute',
|
||||
s: 'second',
|
||||
z: 'timeZoneName',
|
||||
A: 'dayPeriod',
|
||||
a: 'dayPeriod'
|
||||
}
|
||||
|
||||
const parts = new Intl.DateTimeFormat([], opts).formatToParts(date)
|
||||
|
||||
return format.replace(/MMMM|MMM|MM|M|DD|D|YYYY|YYY|YY|HH|hh|H|h|mm|m|ss|s|A|a|z/g, (token) => {
|
||||
if (withTimePlaceholders && /^(HH|hh|H|h|mm|m|ss|s|A|a)$/.test(token)) return '--'
|
||||
|
||||
const value = parts.find((p) => p.type === partTypes[token[0]])?.value
|
||||
|
||||
if (token === 'A') return (value || '').toUpperCase()
|
||||
if (token === 'a') return (value || '').toLowerCase()
|
||||
|
||||
return value
|
||||
})
|
||||
},
|
||||
updateMultipleSelectValue (value) {
|
||||
if (this.modelValue?.includes(value)) {
|
||||
|
||||
@@ -56,12 +56,18 @@
|
||||
class="base-input !text-2xl text-center w-full"
|
||||
:required="field.required"
|
||||
:aria-describedby="field.description ? field.uuid + '-desc' : undefined"
|
||||
type="date"
|
||||
:name="`values[${field.uuid}]`"
|
||||
:type="inputType"
|
||||
:name="formatType === 'datetime' ? undefined : `values[${field.uuid}]`"
|
||||
@keydown.enter="onEnter"
|
||||
@focus="$emit('focus')"
|
||||
@paste="onPaste"
|
||||
>
|
||||
<input
|
||||
v-if="formatType === 'datetime'"
|
||||
type="hidden"
|
||||
:name="`values[${field.uuid}]`"
|
||||
:value="modelValue"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -97,14 +103,19 @@ export default {
|
||||
},
|
||||
emits: ['update:model-value', 'focus', 'submit'],
|
||||
computed: {
|
||||
formatType () {
|
||||
const format = this.field.preferences?.format || ''
|
||||
|
||||
if (/[HhAasz]/.test(format)) return 'datetime'
|
||||
if (format && !/[Dd]/.test(format)) return 'month'
|
||||
|
||||
return 'date'
|
||||
},
|
||||
inputType () {
|
||||
return { datetime: 'datetime-local', month: 'month', date: 'date' }[this.formatType]
|
||||
},
|
||||
dateNowString () {
|
||||
const today = new Date()
|
||||
|
||||
const yyyy = today.getFullYear()
|
||||
const mm = String(today.getMonth() + 1).padStart(2, '0')
|
||||
const dd = String(today.getDate()).padStart(2, '0')
|
||||
|
||||
return `${yyyy}-${mm}-${dd}`
|
||||
return this.formatDateValue(new Date())
|
||||
},
|
||||
validationMin () {
|
||||
if (this.field.validation?.min) {
|
||||
@@ -121,6 +132,8 @@ export default {
|
||||
}
|
||||
},
|
||||
withToday () {
|
||||
if (this.formatType === 'datetime') return false
|
||||
|
||||
const todayDate = new Date().setHours(0, 0, 0, 0)
|
||||
|
||||
if (this.validationMin) {
|
||||
@@ -137,9 +150,25 @@ export default {
|
||||
},
|
||||
value: {
|
||||
set (value) {
|
||||
if (this.formatType === 'datetime' && value) {
|
||||
const d = new Date(value)
|
||||
|
||||
if (!isNaN(d)) {
|
||||
this.$emit('update:model-value', d.toISOString())
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
this.$emit('update:model-value', value)
|
||||
},
|
||||
get () {
|
||||
if (this.formatType === 'datetime') {
|
||||
const d = new Date(this.modelValue)
|
||||
|
||||
return isNaN(d) ? '' : this.formatDateValue(d)
|
||||
}
|
||||
|
||||
return this.modelValue
|
||||
}
|
||||
}
|
||||
@@ -163,20 +192,32 @@ export default {
|
||||
|
||||
const parsedDate = new Date(pasteData)
|
||||
|
||||
if (!isNaN(parsedDate)) {
|
||||
const inputEl = this.$refs.input
|
||||
if (isNaN(parsedDate)) return
|
||||
|
||||
inputEl.valueAsDate = new Date(parsedDate.getTime() - parsedDate.getTimezoneOffset() * 60000)
|
||||
|
||||
inputEl.dispatchEvent(new Event('input', { bubbles: true }))
|
||||
}
|
||||
this.setInputValue(parsedDate)
|
||||
},
|
||||
setCurrentDate () {
|
||||
this.setInputValue(new Date())
|
||||
},
|
||||
setInputValue (date) {
|
||||
const inputEl = this.$refs.input
|
||||
|
||||
inputEl.valueAsDate = new Date(new Date().getTime() - new Date().getTimezoneOffset() * 60000)
|
||||
if (this.formatType === 'date') {
|
||||
inputEl.valueAsDate = new Date(date.getTime() - date.getTimezoneOffset() * 60000)
|
||||
} else {
|
||||
inputEl.value = this.formatDateValue(date)
|
||||
}
|
||||
|
||||
inputEl.dispatchEvent(new Event('input', { bubbles: true }))
|
||||
},
|
||||
formatDateValue (date) {
|
||||
const pad = (n) => String(n).padStart(2, '0')
|
||||
const ymd = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
|
||||
|
||||
if (this.formatType === 'month') return ymd.slice(0, 7)
|
||||
if (this.formatType === 'datetime') return `${ymd}T${pad(date.getHours())}:${pad(date.getMinutes())}`
|
||||
|
||||
return ymd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
<span
|
||||
v-else-if="field.default_value === '{{date}}'"
|
||||
>
|
||||
{{ t('signing_date') }}
|
||||
{{ /[HhAasz]/.test(field.preferences?.format || '') ? t('signing_date_and_time') : t('signing_date') }}
|
||||
</span>
|
||||
<div
|
||||
v-else-if="field.type === 'cells' && field.default_value"
|
||||
|
||||
@@ -669,6 +669,7 @@ export default {
|
||||
locale: this.locale,
|
||||
baseFetch: this.baseFetch,
|
||||
fieldTypes: this.fieldTypes,
|
||||
dateFormats: this.dateFormats,
|
||||
backgroundColor: this.backgroundColor,
|
||||
withPhone: this.withPhone,
|
||||
withVerification: this.withVerification,
|
||||
@@ -823,6 +824,11 @@ export default {
|
||||
required: false,
|
||||
default: () => []
|
||||
},
|
||||
dateFormats: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => []
|
||||
},
|
||||
defaultSubmitters: {
|
||||
type: Array,
|
||||
required: false,
|
||||
@@ -1030,6 +1036,8 @@ export default {
|
||||
return isMobileSafariIos || /android|iphone|ipad/i.test(navigator.userAgent)
|
||||
},
|
||||
defaultDateFormat () {
|
||||
if (this.dateFormats.length) return this.dateFormats[0]
|
||||
|
||||
const isUsBrowser = Intl.DateTimeFormat().resolvedOptions().locale.endsWith('-US')
|
||||
const isUsTimezone = new Intl.DateTimeFormat('en-US', { timeZoneName: 'short' }).format(new Date()).match(/\s(?:CST|CDT|PST|PDT|EST|EDT)$/)
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
@change="[schema.format = $event.target.value, save()]"
|
||||
>
|
||||
<option
|
||||
v-for="format in dateFormats"
|
||||
v-for="format in availableDateFormats"
|
||||
:key="format"
|
||||
:value="format"
|
||||
>{{ formatDate(new Date(), format) }}</option>
|
||||
@@ -248,7 +248,7 @@ export default {
|
||||
FieldType,
|
||||
IconSettings
|
||||
},
|
||||
inject: ['t', 'save', 'backgroundColor'],
|
||||
inject: ['t', 'save', 'backgroundColor', 'dateFormats'],
|
||||
provide () {
|
||||
return {
|
||||
fieldTypes: ['text', 'number', 'date', 'checkbox', 'radio', 'select']
|
||||
@@ -318,20 +318,23 @@ export default {
|
||||
'space'
|
||||
]
|
||||
},
|
||||
dateFormats () {
|
||||
const formats = [
|
||||
'MM/DD/YYYY',
|
||||
'DD/MM/YYYY',
|
||||
'YYYY-MM-DD',
|
||||
'DD-MM-YYYY',
|
||||
'DD.MM.YYYY',
|
||||
'MMM D, YYYY',
|
||||
'MMMM D, YYYY',
|
||||
'D MMM YYYY',
|
||||
'D MMMM YYYY'
|
||||
]
|
||||
availableDateFormats () {
|
||||
const formats = this.dateFormats.length
|
||||
? [...this.dateFormats]
|
||||
: [
|
||||
'MM/DD/YYYY',
|
||||
'DD/MM/YYYY',
|
||||
'YYYY-MM-DD',
|
||||
'DD-MM-YYYY',
|
||||
'DD.MM.YYYY',
|
||||
'MMM D, YYYY',
|
||||
'MMMM D, YYYY',
|
||||
'MMMM YYYY',
|
||||
'D MMM YYYY',
|
||||
'D MMMM YYYY'
|
||||
]
|
||||
|
||||
if (Intl.DateTimeFormat().resolvedOptions().timeZone?.includes('Seoul') || navigator.language?.startsWith('ko')) {
|
||||
if (!this.dateFormats.length && (Intl.DateTimeFormat().resolvedOptions().timeZone?.includes('Seoul') || navigator.language?.startsWith('ko'))) {
|
||||
formats.push('YYYY년 MM월 DD일')
|
||||
}
|
||||
|
||||
@@ -401,18 +404,47 @@ export default {
|
||||
formatDate (date, format) {
|
||||
const monthFormats = { M: 'numeric', MM: '2-digit', MMM: 'short', MMMM: 'long' }
|
||||
const dayFormats = { D: 'numeric', DD: '2-digit' }
|
||||
const yearFormats = { YYYY: 'numeric', YY: '2-digit' }
|
||||
const yearFormats = { YYYY: 'numeric', YYY: 'numeric', YY: '2-digit' }
|
||||
const hourFormats = { H: 'numeric', HH: '2-digit', h: 'numeric', hh: '2-digit' }
|
||||
const minuteFormats = { m: 'numeric', mm: '2-digit' }
|
||||
const secondFormats = { s: 'numeric', ss: '2-digit' }
|
||||
|
||||
const parts = new Intl.DateTimeFormat([], {
|
||||
const opts = {
|
||||
day: dayFormats[format.match(/D+/)],
|
||||
month: monthFormats[format.match(/M+/)],
|
||||
year: yearFormats[format.match(/Y+/)]
|
||||
}).formatToParts(date)
|
||||
}
|
||||
|
||||
return format
|
||||
.replace(/D+/, parts.find((p) => p.type === 'day').value)
|
||||
.replace(/M+/, parts.find((p) => p.type === 'month').value)
|
||||
.replace(/Y+/, parts.find((p) => p.type === 'year').value)
|
||||
if (format.match(/H+/)) { opts.hour = hourFormats[format.match(/H+/)[0]]; opts.hour12 = false }
|
||||
if (format.match(/h+/)) { opts.hour = hourFormats[format.match(/h+/)[0]]; opts.hour12 = true }
|
||||
if (/[Aa]/.test(format) && opts.hour12 === undefined) opts.hour12 = true
|
||||
if (format.match(/m+/)) opts.minute = minuteFormats[format.match(/m+/)[0]]
|
||||
if (format.match(/s+/)) opts.second = secondFormats[format.match(/s+/)[0]]
|
||||
if (/z/.test(format)) opts.timeZoneName = 'short'
|
||||
|
||||
const partTypes = {
|
||||
M: 'month',
|
||||
D: 'day',
|
||||
Y: 'year',
|
||||
H: 'hour',
|
||||
h: 'hour',
|
||||
m: 'minute',
|
||||
s: 'second',
|
||||
z: 'timeZoneName',
|
||||
A: 'dayPeriod',
|
||||
a: 'dayPeriod'
|
||||
}
|
||||
|
||||
const parts = new Intl.DateTimeFormat([], opts).formatToParts(date)
|
||||
|
||||
return format.replace(/MMMM|MMM|MM|M|DD|D|YYYY|YYY|YY|HH|hh|H|h|mm|m|ss|s|A|a|z/g, (token) => {
|
||||
const value = parts.find((p) => p.type === partTypes[token[0]])?.value
|
||||
|
||||
if (token === 'A') return (value || '').toUpperCase()
|
||||
if (token === 'a') return (value || '').toLowerCase()
|
||||
|
||||
return value
|
||||
})
|
||||
},
|
||||
closeDropdown () {
|
||||
this.$el.getRootNode().activeElement.blur()
|
||||
|
||||
@@ -345,7 +345,7 @@ export default {
|
||||
IconMathFunction,
|
||||
FieldType
|
||||
},
|
||||
inject: ['template', 'backgroundColor', 'selectedAreasRef', 't', 'locale', 'getFieldTypeIndex'],
|
||||
inject: ['template', 'backgroundColor', 'selectedAreasRef', 't', 'locale', 'getFieldTypeIndex', 'dateFormats'],
|
||||
props: {
|
||||
field: {
|
||||
type: Object,
|
||||
@@ -428,7 +428,8 @@ export default {
|
||||
|
||||
if (this.field.type === 'date') {
|
||||
this.field.preferences.format ||=
|
||||
({ 'de-DE': 'DD.MM.YYYY' }[this.locale] || ((Intl.DateTimeFormat().resolvedOptions().locale.endsWith('-US') || new Intl.DateTimeFormat('en-US', { timeZoneName: 'short' }).format(new Date()).match(/\s(?:CST|CDT|PST|PDT|EST|EDT)$/)) ? 'MM/DD/YYYY' : 'DD/MM/YYYY'))
|
||||
this.dateFormats[0] ||
|
||||
({ 'de-DE': 'DD.MM.YYYY' }[this.locale] || ((Intl.DateTimeFormat().resolvedOptions().locale.endsWith('-US') || new Intl.DateTimeFormat('en-US', { timeZoneName: 'short' }).format(new Date()).match(/\s(?:CST|CDT|PST|PDT|EST|EDT)$/)) ? 'MM/DD/YYYY' : 'DD/MM/YYYY'))
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -514,7 +514,7 @@ export default {
|
||||
ContextSubmenu,
|
||||
ContextModal
|
||||
},
|
||||
inject: ['t', 'getFieldTypeIndex', 'template', 'withCustomFields', 'currencies'],
|
||||
inject: ['t', 'getFieldTypeIndex', 'template', 'withCustomFields', 'currencies', 'dateFormats'],
|
||||
props: {
|
||||
contextMenu: {
|
||||
type: Object,
|
||||
@@ -580,7 +580,7 @@ export default {
|
||||
fieldNames: FieldType.computed.fieldNames,
|
||||
fieldLabels: FieldType.computed.fieldLabels,
|
||||
validationOptions: FieldSettings.computed.validations,
|
||||
dateFormats: FieldSettings.computed.dateFormats,
|
||||
availableDateFormats: FieldSettings.computed.availableDateFormats,
|
||||
numberFormats: FieldSettings.computed.numberFormats,
|
||||
prefillableFieldTypes: FieldSettings.computed.prefillableFieldTypes,
|
||||
verificationMethods: FieldSettings.computed.verificationMethods,
|
||||
@@ -686,7 +686,7 @@ export default {
|
||||
},
|
||||
formatOptions () {
|
||||
switch (this.field.type) {
|
||||
case 'date': return this.dateFormats.map(f => ({ value: f, label: this.formatDate(new Date(), f) }))
|
||||
case 'date': return this.availableDateFormats.map(f => ({ value: f, label: this.formatDate(new Date(), f) }))
|
||||
case 'number': return this.numberFormats.map(f => ({ value: f, label: this.formatNumber(123456789.567, f) }))
|
||||
case 'signature': return this.signatureFormats.map(f => ({ value: f, label: this.t(f) }))
|
||||
default: return []
|
||||
|
||||
@@ -290,7 +290,7 @@
|
||||
@change="$emit('save')"
|
||||
>
|
||||
<option
|
||||
v-for="format in dateFormats"
|
||||
v-for="format in availableDateFormats"
|
||||
:key="format"
|
||||
:value="format"
|
||||
>
|
||||
@@ -610,7 +610,7 @@ export default {
|
||||
IconTypography,
|
||||
IconX
|
||||
},
|
||||
inject: ['template', 't'],
|
||||
inject: ['template', 't', 'dateFormats'],
|
||||
props: {
|
||||
field: {
|
||||
type: Object,
|
||||
@@ -701,20 +701,23 @@ export default {
|
||||
'space'
|
||||
]
|
||||
},
|
||||
dateFormats () {
|
||||
const formats = [
|
||||
'MM/DD/YYYY',
|
||||
'DD/MM/YYYY',
|
||||
'YYYY-MM-DD',
|
||||
'DD-MM-YYYY',
|
||||
'DD.MM.YYYY',
|
||||
'MMM D, YYYY',
|
||||
'MMMM D, YYYY',
|
||||
'D MMM YYYY',
|
||||
'D MMMM YYYY'
|
||||
]
|
||||
availableDateFormats () {
|
||||
const formats = this.dateFormats.length
|
||||
? [...this.dateFormats]
|
||||
: [
|
||||
'MM/DD/YYYY',
|
||||
'DD/MM/YYYY',
|
||||
'YYYY-MM-DD',
|
||||
'DD-MM-YYYY',
|
||||
'DD.MM.YYYY',
|
||||
'MMM D, YYYY',
|
||||
'MMMM D, YYYY',
|
||||
'MMMM YYYY',
|
||||
'D MMM YYYY',
|
||||
'D MMMM YYYY'
|
||||
]
|
||||
|
||||
if (Intl.DateTimeFormat().resolvedOptions().timeZone?.includes('Seoul') || navigator.language?.startsWith('ko')) {
|
||||
if (!this.dateFormats.length && (Intl.DateTimeFormat().resolvedOptions().timeZone?.includes('Seoul') || navigator.language?.startsWith('ko'))) {
|
||||
formats.push('YYYY년 MM월 DD일')
|
||||
}
|
||||
|
||||
@@ -819,33 +822,49 @@ export default {
|
||||
return pattern?.match(/^\.{(?<min>\d+),(?<max>\d+)?}$/)?.groups || null
|
||||
},
|
||||
formatDate (date, format) {
|
||||
const monthFormats = {
|
||||
M: 'numeric',
|
||||
MM: '2-digit',
|
||||
MMM: 'short',
|
||||
MMMM: 'long'
|
||||
}
|
||||
const monthFormats = { M: 'numeric', MM: '2-digit', MMM: 'short', MMMM: 'long' }
|
||||
const dayFormats = { D: 'numeric', DD: '2-digit' }
|
||||
const yearFormats = { YYYY: 'numeric', YYY: 'numeric', YY: '2-digit' }
|
||||
const hourFormats = { H: 'numeric', HH: '2-digit', h: 'numeric', hh: '2-digit' }
|
||||
const minuteFormats = { m: 'numeric', mm: '2-digit' }
|
||||
const secondFormats = { s: 'numeric', ss: '2-digit' }
|
||||
|
||||
const dayFormats = {
|
||||
D: 'numeric',
|
||||
DD: '2-digit'
|
||||
}
|
||||
|
||||
const yearFormats = {
|
||||
YYYY: 'numeric',
|
||||
YY: '2-digit'
|
||||
}
|
||||
|
||||
const parts = new Intl.DateTimeFormat([], {
|
||||
const opts = {
|
||||
day: dayFormats[format.match(/D+/)],
|
||||
month: monthFormats[format.match(/M+/)],
|
||||
year: yearFormats[format.match(/Y+/)]
|
||||
}).formatToParts(date)
|
||||
}
|
||||
|
||||
return format
|
||||
.replace(/D+/, parts.find((p) => p.type === 'day').value)
|
||||
.replace(/M+/, parts.find((p) => p.type === 'month').value)
|
||||
.replace(/Y+/, parts.find((p) => p.type === 'year').value)
|
||||
if (format.match(/H+/)) { opts.hour = hourFormats[format.match(/H+/)[0]]; opts.hour12 = false }
|
||||
if (format.match(/h+/)) { opts.hour = hourFormats[format.match(/h+/)[0]]; opts.hour12 = true }
|
||||
if (/[Aa]/.test(format) && opts.hour12 === undefined) opts.hour12 = true
|
||||
if (format.match(/m+/)) opts.minute = minuteFormats[format.match(/m+/)[0]]
|
||||
if (format.match(/s+/)) opts.second = secondFormats[format.match(/s+/)[0]]
|
||||
if (/z/.test(format)) opts.timeZoneName = 'short'
|
||||
|
||||
const partTypes = {
|
||||
M: 'month',
|
||||
D: 'day',
|
||||
Y: 'year',
|
||||
H: 'hour',
|
||||
h: 'hour',
|
||||
m: 'minute',
|
||||
s: 'second',
|
||||
z: 'timeZoneName',
|
||||
A: 'dayPeriod',
|
||||
a: 'dayPeriod'
|
||||
}
|
||||
|
||||
const parts = new Intl.DateTimeFormat([], opts).formatToParts(date)
|
||||
|
||||
return format.replace(/MMMM|MMM|MM|M|DD|D|YYYY|YYY|YY|HH|hh|H|h|mm|m|ss|s|A|a|z/g, (token) => {
|
||||
const value = parts.find((p) => p.type === partTypes[token[0]])?.value
|
||||
|
||||
if (token === 'A') return (value || '').toUpperCase()
|
||||
if (token === 'a') return (value || '').toLowerCase()
|
||||
|
||||
return value
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ const en = {
|
||||
sign_yourself: 'Sign Yourself',
|
||||
set_signing_date: 'Set signing date',
|
||||
signing_date: 'Signing Date',
|
||||
signing_date_and_time: 'Signing Date and Time',
|
||||
send: 'Send',
|
||||
remove: 'Remove',
|
||||
edit: 'Edit',
|
||||
@@ -271,6 +272,7 @@ const es = {
|
||||
with_logo: 'Con logotipo',
|
||||
description: 'Descripción',
|
||||
signing_date: 'Fecha de Firma',
|
||||
signing_date_and_time: 'Fecha y Hora de Firma',
|
||||
display_title: 'Título de visualización',
|
||||
unchecked: 'No marcado',
|
||||
price: 'Precio',
|
||||
@@ -508,6 +510,7 @@ const it = {
|
||||
sign_yourself: 'Firma te stesso',
|
||||
set_signing_date: 'Imposta data di firma',
|
||||
signing_date: 'Data di firma',
|
||||
signing_date_and_time: 'Data e ora di firma',
|
||||
send: 'Invia',
|
||||
remove: 'Rimuovi',
|
||||
edit: 'Modifica',
|
||||
@@ -710,6 +713,7 @@ const pt = {
|
||||
description: 'Descrição',
|
||||
display_title: 'Título de exibição',
|
||||
signing_date: 'Data da Assinatura',
|
||||
signing_date_and_time: 'Data e Hora da Assinatura',
|
||||
unchecked: 'Não marcado',
|
||||
price: 'Preço',
|
||||
equal: 'Igual',
|
||||
@@ -946,6 +950,7 @@ const fr = {
|
||||
sign_yourself: 'Signer vous-même',
|
||||
set_signing_date: 'Définir la date de signature',
|
||||
signing_date: 'Date de signature',
|
||||
signing_date_and_time: 'Date et heure de signature',
|
||||
send: 'Envoyer',
|
||||
remove: 'Supprimer',
|
||||
edit: 'Modifier',
|
||||
@@ -1165,6 +1170,7 @@ const de = {
|
||||
sign_yourself: 'Selbst unterschreiben',
|
||||
set_signing_date: 'Unterzeichnungsdatum festlegen',
|
||||
signing_date: 'Unterzeichnungsdatum',
|
||||
signing_date_and_time: 'Unterzeichnungsdatum und -uhrzeit',
|
||||
send: 'Senden',
|
||||
remove: 'Entfernen',
|
||||
edit: 'Bearbeiten',
|
||||
@@ -1384,6 +1390,7 @@ const nl = {
|
||||
sign_yourself: 'Zelf ondertekenen',
|
||||
set_signing_date: 'Ondertekeningsdatum instellen',
|
||||
signing_date: 'Ondertekeningsdatum',
|
||||
signing_date_and_time: 'Ondertekeningsdatum en -tijd',
|
||||
send: 'Verzenden',
|
||||
remove: 'Verwijderen',
|
||||
edit: 'Bewerken',
|
||||
|
||||
Reference in New Issue
Block a user