Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse month from string in customParseFormat #457

Merged
merged 17 commits into from
Feb 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions .babelrc → babel.config.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{
"env": {
"test": {
"presets": [
"@babel/preset-env"
]
},
"build": {
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"loose": true
}
]
]
}
}
}
module.exports = {
Kreozot marked this conversation as resolved.
Show resolved Hide resolved
"env": {
"test": {
"presets": [
"@babel/preset-env"
]
},
"build": {
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"loose": true
}
]
]
}
}
};
3 changes: 3 additions & 0 deletions docs/en/Plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ dayjs.extend(customParseFormat)

dayjs('05/02/69 1:02:03 PM -05:00', 'MM/DD/YY H:mm:ss A Z')
// Returns an instance containing '1969-05-02T18:02:03.000Z'

dayjs('2018 Enero 15', { format: 'YYYY MMMM DD', locale: es })
// Returns an instance containing '2018-01-15T00:00:00.000Z'
```

#### List of all available format tokens
Expand Down
17 changes: 17 additions & 0 deletions docs/es-es/Plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,23 @@ dayjs.extend(quarterOfYear)
dayjs('2010-04-01').quarter(); // 2
```

### CustomParseFormat
- CustomParseFormat extends `dayjs()` constructor to support custom formats of input strings.

To escape characters, wrap them in square brackets (e.g. `[G]`). Punctuation symbols (-:/.()) do not need to be wrapped.

```javascript
import customParseFormat from 'dayjs/plugin/customParseFormat'

dayjs.extend(customParseFormat)

dayjs('05/02/69 1:02:03 PM -05:00', 'MM/DD/YY H:mm:ss A Z')
// Returns an instance containing '1969-05-02T18:02:03.000Z'

dayjs('2018 Enero 15', { format: 'YYYY MMMM DD', locale: es })
// Returns an instance containing '2018-01-15T00:00:00.000Z'
```

#### List of all available format tokens

| Format | Output | Description |
Expand Down
3 changes: 3 additions & 0 deletions docs/ja/Plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ dayjs.extend(customParseFormat)

dayjs('05/02/69 1:02:03 PM -05:00', 'MM/DD/YY H:mm:ss A Z')
// Returns an instance containing '1969-05-02T18:02:03.000Z'

dayjs('2018 5月 15', { format: 'YYYY MMMM DD', locale: ja })
// Returns an instance containing '2018-05-15T00:00:00.000Z'
```

#### List of all available format tokens
Expand Down
3 changes: 3 additions & 0 deletions docs/ko/Plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ dayjs.extend(customParseFormat)

dayjs('05/02/69 1:02:03 PM -05:00', 'MM/DD/YY H:mm:ss A Z')
// Returns an instance containing '1969-05-02T18:02:03.000Z'

dayjs('2018 5월 15', { format: 'YYYY MMMM DD', locale: ko })
// Returns an instance containing '2018-05-15T00:00:00.000Z'
```

#### List of all available format tokens
Expand Down
3 changes: 3 additions & 0 deletions docs/pt-br/Plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ dayjs.extend(customParseFormat)

dayjs('05/02/69 1:02:03 PM -05:00', 'MM/DD/YY H:mm:ss A Z')
// Returns an instance containing '1969-05-02T18:02:03.000Z'

dayjs('2018 Fevereiro 15', { format: 'YYYY MMMM DD', locale: pt_br })
// Returns an instance containing '2018-02-15T00:00:00.000Z'
```

#### List of all available format tokens
Expand Down
3 changes: 3 additions & 0 deletions docs/zh-cn/Plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ dayjs.extend(customParseFormat)

dayjs('05/02/69 1:02:03 PM -05:00', 'MM/DD/YY H:mm:ss A Z')
// Returns an instance containing '1969-05-02T18:02:03.000Z'

dayjs('2018 五月 15', { format: 'YYYY MMMM DD', locale: zh_cn })
// Returns an instance containing '2018-05-15T00:00:00.000Z'
```

#### List of all available format tokens
Expand Down
6 changes: 3 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,16 @@ const parseDate = (date) => {

class Dayjs {
constructor(cfg) {
this.$L = this.$L || parseLocale(cfg.locale, null, true) || L
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to make locale available in parse() function

this.parse(cfg) // for plugin
}

parse(cfg) {
this.$d = parseDate(cfg.date)
this.init(cfg)
this.init()
}

init(cfg) {
init() {
const { $d } = this
this.$y = $d.getFullYear()
this.$M = $d.getMonth()
Expand All @@ -82,7 +83,6 @@ class Dayjs {
this.$m = $d.getMinutes()
this.$s = $d.getSeconds()
this.$ms = $d.getMilliseconds()
this.$L = this.$L || parseLocale(cfg.locale, null, true) || L
}

// eslint-disable-next-line class-methods-use-this
Expand Down
24 changes: 23 additions & 1 deletion src/plugin/customParseFormat/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const formattingTokens = /(\[[^[]*\])|([-:/.()\s]+)|(A|a|YYYY|YY?|MM?|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g
const formattingTokens = /(\[[^[]*\])|([-:/.()\s]+)|(A|a|YYYY|YY?|MM?M?M?|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g

const match1 = /\d/ // 0 - 9
const match2 = /\d\d/ // 00 - 99
Expand All @@ -9,6 +9,9 @@ const matchUpperCaseAMPM = /[AP]M/
const matchLowerCaseAMPM = /[ap]m/
const matchSigned = /[+-]?\d+/ // -inf - inf
const matchOffset = /[+-]\d\d:?\d\d/ // +00:00 -00:00 +0000 or -0000
const matchWord = /\d*[^\s\d]+/ // Word

let locale

Kreozot marked this conversation as resolved.
Show resolved Hide resolved
function offsetFromString(string) {
const parts = string.match(/([+-]|\d\d)/g)
Expand Down Expand Up @@ -55,6 +58,24 @@ const expressions = {
DD: [match2, addInput('day')],
M: [match1to2, addInput('month')],
MM: [match2, addInput('month')],
MMM: [matchWord, function (input) {
const { months, monthsShort } = locale
const matchIndex = monthsShort
? monthsShort.findIndex(month => month === input)
: months.findIndex(month => month.substr(0, 3) === input)
if (matchIndex < 0) {
throw new Error()
}
this.month = matchIndex + 1
}],
MMMM: [matchWord, function (input) {
const { months } = locale
const matchIndex = months.indexOf(input)
if (matchIndex < 0) {
throw new Error()
}
this.month = matchIndex + 1
}],
Y: [matchSigned, addInput('year')],
YY: [match2, function (input) {
input = +input
Expand Down Expand Up @@ -143,6 +164,7 @@ export default (o, C) => {
proto.parse = function (cfg) {
const { date: input, format } = cfg
if (format) {
locale = this.$locale()
this.$d = parseFormattedInput(input, format)
this.init(cfg)
} else {
Expand Down
54 changes: 54 additions & 0 deletions test/plugin/customParseFormat.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import MockDate from 'mockdate'
import moment from 'moment'
import dayjs from '../../src'
import customParseFormat from '../../src/plugin/customParseFormat'
import uk from '../../src/locale/uk'

dayjs.extend(customParseFormat)

Expand Down Expand Up @@ -72,3 +73,56 @@ it('fails with an invalid format', () => {
expect(dayjs(input, format).format().toLowerCase())
.toBe(moment(input, format).format().toLowerCase())
})

it('parse month from string', () => {
const input = '2018 February 03'
const format = 'YYYY MMMM DD'
expect(dayjs(input, format).valueOf()).toBe(moment(input, format).valueOf())
})

it('parse month from short string', () => {
const input = '2018 Feb 03'
const format = 'YYYY MMM DD'
expect(dayjs(input, format).valueOf()).toBe(moment(input, format).valueOf())
})

it('parse month from string with locale in config', () => {
const input = '2018 лютий 03'
const format = 'YYYY MMMM DD'

expect(dayjs(input, { format, locale: uk }).valueOf()).toBe(moment(input, format, 'uk').valueOf())
})

it('parse month from short string with locale in config', () => {
const input = '2018 трав 03'
const format = 'YYYY MMM DD'
expect(dayjs(input, { format, locale: uk }).valueOf()).toBe(moment(input, format, 'uk').valueOf())
})

it('return Invalid Date when parse corrupt string', () => {
const input = '2018 Turnip 03'
const format = 'YYYY MMMM DD'
expect(dayjs(input, format).format()).toBe('Invalid Date')
Kreozot marked this conversation as resolved.
Show resolved Hide resolved
})

it('return Invalid Date when parse corrupt short string', () => {
const input = '2018 Dog 03'
const format = 'YYYY MMM DD'
expect(dayjs(input, format).format()).toBe('Invalid Date')
})

it('correctly parse month from string after changing locale globally', () => {
const input = '2018 лютий 03'
const format = 'YYYY MMMM DD'

const dayjsLocale = dayjs().$locale()
const momentLocale = moment.locale()
try {
dayjs.locale(uk)
moment.locale('uk')
expect(dayjs(input, format).valueOf()).toBe(moment(input, format).valueOf())
} finally {
dayjs.locale(dayjsLocale)
moment.locale(momentLocale)
}
})