Skip to content

Instantly share code, notes, and snippets.

@jesusalc
Created June 21, 2016 15:29
Show Gist options
  • Save jesusalc/c83edabae10a23eed04cfc38d1b65499 to your computer and use it in GitHub Desktop.
Save jesusalc/c83edabae10a23eed04cfc38d1b65499 to your computer and use it in GitHub Desktop.
// insert ES6 code
class DateBase {
constructor(expression = '', locale = 'en') {
this._day = ''
this._month = ''
this._year = ''
this._locale = locale
this._expression = expression
this.parse_date = ''
this._date_object_valid = false
this._reg_ex_valid = false
this._date_object = {}
try {
//noinspection JSAnnotator,JSUnresolvedVariable,JSUnresolvedFunction
this._l10n = new Intl.DateTimeFormat(locale)
} catch (exception) {
//fall through
}
}
validate(expression){
this._expression = expression
// Replace all words for numbers, trim, etc
this.unify()
//Attempt to parse with new Date
this.parseDate()
//Parse with RegEx
this.parseUsingRegex()
}
unify() {
this.expression = this.expression.replace(/[ -\/\.]/g, '/')
this.expression = this.expression.toLowerCase()
this.expression = this.expression.trim()
this.expression = DateBase.replaceMonths(this.expression)
}
static replaceMonths(expression) {
//dates more to addref:
// http://library.princeton.edu/departments/tsd/katmandu/reference/months.html
let from =
[
['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'],
['januar', 'februar', 'märz', 'april', 'mai', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'dezember'],
['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre']
]
let to =
[
['jan', 'feb', 'mar', 'apr', 'may', 'june', 'july', 'aug', 'sept', 'oct', 'nov', 'dec'],
['jän', 'feb', 'mär', 'apr', 'mai', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dez'],
['janv', 'févr', 'mars', 'avril', 'mai', 'juin', 'juil', 'août', 'sept', 'oct', 'nov', 'déc'],
['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'set', 'oct', 'nov', 'dic']
]
let ret = expression
let numericMonth = 0
for (let wholeYear of from) {
for (let month of wholeYear) {
numericMonth = wholeYear.indexOf(month) + 1
ret = ret.replace(month, numericMonth)
}
}
for (let wholeYear of to) {
for (let month of wholeYear) {
numericMonth = wholeYear.indexOf(month) + 1
ret = ret.replace(month, numericMonth)
}
}
return ret
}
static addLeftCero(getDataFromDate, value) {
if (getDataFromDate == value) {
if (typeof value === 'string' && value.length < 2) {
return '0' + value
}
if (typeof value === 'number' && value < 10) {
return '0' + value
} else {
return '' + value
}
}
return ''
}
parseDate() {
try {
let tempDate = new Date(this.expression)
if (tempDate == 'Invalid Date') {
this.parse_date = ''
this.date_object_valid = false
return
}
//noinspection JSUnresolvedFunction
let tempDateFormatted = this.l10n.format(tempDate)
//day
let value = tempDate.getDate()
let d = DateBase.addLeftCero(value, value)
//month
value = tempDate.getMonth() + 1
let m = DateBase.addLeftCero(value, value)
//year
value = tempDate.getFullYear()
let y = DateBase.addLeftCero(value, value)
tempDateFormatted = '' + m + '/' + d + '/' + y
this.parse_date = tempDateFormatted
this.date_object_valid = true
this.date_object = tempDate
this.day = d
this.month = m
this.year = y
} catch (e) {
console.error(e.message)
this.date_object_valid = false
}
}
parseUsingRegex() {
let d = 0
let m = 0
let y = 0
//Case 1 or 2 Does it look a date()?
let separator = '[ -#/#.]'
let digitsOneTwo = '(#d{2}|#d{1})'
let digitsFour = '(#d{4})'
let caseOne = digitsOneTwo + separator + digitsOneTwo + separator + digitsFour
let caseTwo = digitsFour + separator + digitsOneTwo + separator + digitsOneTwo
let caseThree = digitsOneTwo + separator + digitsFour + separator + digitsOneTwo
// Validation 1 Do the numbers make sense 12 - 30 ?
let twelve = '(0?[1-9]|1[0-2])'
let thirty = '(0?[1-9]|1[0-9]|2[0-9]|3[0-1])'
let caseOneTwelve = twelve + separator + thirty + separator + digitsFour
let caseOneThirty = thirty + separator + twelve + separator + digitsFour
let caseTwoTwelve = digitsFour + separator + twelve + separator + thirty
let caseTwoThirty = digitsFour + separator + thirty + separator + twelve
let caseThreeTwelve = twelve + separator + digitsFour + separator + thirty
let caseThreeThirty = thirty + separator + digitsFour + separator + twelve
let _regExOne = '^' + caseOne + '$'
let _regExTwo = '^' + caseTwo + '$'
let _regExThree = '^' + caseThree + '$'
let _regExOneTwelve = '^' + caseOneTwelve + '$'
let _regExOneThirty = '^' + caseOneThirty + '$'
let _regExTwoTwelve = '^' + caseTwoTwelve + '$'
let _regExTwoThirty = '^' + caseTwoThirty + '$'
let _regExThreeTwelve = '^' + caseThreeTwelve + '$'
let _regExThreeThirty = '^' + caseThreeThirty + '$'
//escape backlashes
_regExOne = _regExOne.replace(/#/g,"\\");
_regExTwo = _regExTwo.replace(/#/g,"\\");
_regExThree = _regExThree.replace(/#/g,"\\");
_regExOneTwelve = _regExOneTwelve.replace(/#/g,"\\");
_regExOneThirty = _regExOneThirty.replace(/#/g,"\\");
_regExTwoTwelve = _regExTwoTwelve.replace(/#/g,"\\");
_regExTwoThirty = _regExTwoThirty.replace(/#/g,"\\");
_regExThreeTwelve = _regExThreeTwelve.replace(/#/g,"\\");
_regExThreeThirty = _regExThreeThirty.replace(/#/g,"\\");
//create regular expression
let regExOne = new RegExp(_regExOne );
let regExTwo = new RegExp(_regExTwo );
let regExThree = new RegExp(_regExThree );
let regExOneTwelve = new RegExp(_regExOneTwelve );
let regExOneThirty = new RegExp(_regExOneThirty );
let regExTwoTwelve = new RegExp(_regExTwoTwelve );
let regExTwoThirty = new RegExp(_regExTwoThirty );
let regExThreeTwelve = new RegExp(_regExThreeTwelve );
let regExThreeThirty = new RegExp(_regExThreeThirty );
let matches = false
let found = false
let expression = this.expression
found = false
d = 0
m = 0
y = 0
// ##/##/####
matches = regExOne.exec(expression)
if (matches) {
// 12/31/####
matches = regExOneTwelve.exec(expression)
if (matches) {
found = true
d = matches[2]
m = matches[1]
y = matches[3]
}
// 31/12/####
matches = regExOneThirty.exec(expression)
if (matches) {
found = true
d = matches[1]
m = matches[2]
y = matches[3]
}
}
if (!found) {
// ####/##/##
matches = regExTwo.exec(expression)
if (matches) {
// ####/12/31
matches = regExTwoTwelve.exec(expression)
if (matches) {
found = true
d = matches[3]
m = matches[2]
y = matches[1]
}
// ####/31/12
matches = regExTwoThirty.exec(expression)
if (matches) {
found = true
d = matches[2]
m = matches[3]
y = matches[1]
}
}
}
if (!found) {
// ##/####/##
matches = regExThree.exec(expression)
if (matches) {
// 12/####/31
matches = regExThreeTwelve.exec(expression)
if (matches) {
found = true
d = matches[3]
m = matches[1]
y = matches[2]
}
// 31/####/12
matches = regExThreeThirty.exec(expression)
if (matches) {
found = true
d = matches[1]
m = matches[3]
y = matches[2]
}
}
}
if (found && this.isValidDate(d,(m-1),y)) {
this.reg_ex_valid = true
this.day = DateBase.addLeftCero(d, d)
this.month = DateBase.addLeftCero(m, m)
this.year = y
this.date_object = new Date(y,(m-1),d)
}
}
isValidDate(d,m,y) {
// Assume not leap year by default (note zero index for Jan)
var daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
// If evenly divisible by 4 and not evenly divisible by 100,
// or is evenly divisible by 400, then a leap year
if ( (!(y % 4) && y % 100) || !(y % 400)) {
daysInMonth[1] = 29;
}
return d <= daysInMonth[m]
}
date() {
//Area of growth
switch (this._locale) {
case 'en':
default:
return '' + this._month + '/' + this._day + '/' + this._year
break
}
}
get year() { return this._year }
get month() { return this._month }
get day() { return this._day }
get locale() { return this._locale }
get expression() { return this._expression }
get l10n() { return this._l10n }
get parse_date() { return this._parse_date }
get date_object_valid(){ return this._date_object_valid }
get reg_ex_valid() { return this._reg_ex_valid }
get date_object() { return this._date_object }
set year(value) { this._year =value }
set month(value) { this._month =value }
set day(value) { this._day =value }
set locale(value) { this._locale =value }
set expression(value) { this._expression =value }
set l10n(value) { this._l10n = value }
set parse_date(value) { this._parse_date = value }
set date_object_valid(value){ this._date_object_valid = value }
set reg_ex_valid(value){ this._reg_ex_valid = value }
set date_object(value){ this._date_object = value }
get military() {return '' + this._year + this._month + this._day }
toString() {return this.date()}
}
// We export the DateBase class so it can
// be require()'d in other files.
module.exports = DateBase
// Import chai.
let chai = require('chai'),
path = require('path')
// Tell chai that we'll be using the "should" style assertions.
chai.should()
// Import the dateBase class.
let DateBase = require(path.join(__dirname, '../js/', 'DateBase'));
describe('DateBase', () => {
describe('#different_dates', () => {
let dateBase
beforeEach(() => {
dateBase = new DateBase('2/3/2000', 'en')
})
it('identifies single digit valid 2/3/2000', () => {
dateBase.validate('2/3/2000')
dateBase.reg_ex_valid.should.equal(true)
})
it('return military from 2/3/2000', () => {
dateBase.validate('2/3/2000')
dateBase.military.should.equal('20000302')
})
it('identifies valid 12/31/2000', () => {
dateBase.validate('12/31/2000')
dateBase.reg_ex_valid.should.equal(true)
})
it('identifies invalid February 2/31/2000', () => {
dateBase.validate('2/31/2000')
dateBase.reg_ex_valid.should.equal(false)
})
it('return military from June 30 2000', () => {
dateBase.validate('June 30 2000')
dateBase.military.should.equal('20000630')
})
it('identifies valid date June 30 2000', () => {
dateBase.validate('June 30 2000')
dateBase.reg_ex_valid.should.equal(true)
})
it('identifies single digit valid 2017/2/3', () => {
dateBase.validate('2017/2/3')
dateBase.reg_ex_valid.should.equal(true)
})
it('identifies valid 2017/12/31', () => {
dateBase.validate('2017/12/31')
dateBase.reg_ex_valid.should.equal(true)
})
it('identifies inverse valid 2017/31/12', () => {
dateBase.validate('2017/31/12')
dateBase.reg_ex_valid.should.equal(true)
})
it('identifies invalid February 2017/2/31', () => {
dateBase.validate('2017/2/31')
dateBase.reg_ex_valid.should.equal(false)
})
it('identifies valid date 2017/June 30', () => {
dateBase.validate('2017/June 30')
dateBase.reg_ex_valid.should.equal(true)
})
it('identifies single digit valid 2/2015/3', () => {
dateBase.validate('2/2015/3')
dateBase.reg_ex_valid.should.equal(true)
})
it('identifies valid 12/2015/31', () => {
dateBase.validate('12/2015/31')
dateBase.reg_ex_valid.should.equal(true)
})
it('identifies invalid February 2/2015/31', () => {
dateBase.validate('2/2015/31')
dateBase.reg_ex_valid.should.equal(false)
})
it('identifies valid date June 2015 30', () => {
dateBase.validate('June 2015 30')
dateBase.reg_ex_valid.should.equal(true)
})
it('return military from June 2015 30', () => {
dateBase.validate('June 2015 30')
dateBase.military.should.equal('20150630')
})
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment