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

Remove dependency on Moment.js #309

Closed
machawk1 opened this issue Sep 15, 2020 · 12 comments
Closed

Remove dependency on Moment.js #309

machawk1 opened this issue Sep 15, 2020 · 12 comments

Comments

@machawk1
Copy link
Owner

machawk1 commented Sep 15, 2020

The project has moved to be a legacy project and the maintainer recommend to replace it. Other relevant literature (from source):

The source also recommends some alternatives (e.g., Luxon, Day.js, date-fns).

This issue will track the degree of coupling with the dependency.

@machawk1
Copy link
Owner Author

machawk1 commented Sep 15, 2020

In one instance within displayMinkUI.js (~line 409), moment is used with an input string (e.g.,
2016-04-26T17:52:33Z) and the numerical year and month name checked to determine if they match the drilldown UI selection and if not, abort the function. Month names (monthNames) are three-letter abbreviations in a global array.

JS's built-in date formatting can likely extract this value.

String parsing will exacerbate an existing problem of relying on Locale, so this might be a good opportunity to adapt the code to not be hard-coded with English month names.

@machawk1
Copy link
Owner Author

One way to get the month abbreviation:

const d = new Date()
d.toLocaleDateString('default', { month: 'short' })
> "Sep"

month takes long, short, and narrow. A utility function could be created to iterate from 1 to 12 and get the abbreviation for the locale. Caveat: is the abbreviated month string in HTTP headers relative to the locale of the client or the server?

@machawk1
Copy link
Owner Author

machawk1 commented Sep 15, 2020

This could probably be optimized but is a clear way to get an array of short month names:

function getMonthNames() {
  const months = []
  for (let m=0; m<12; m++) {
    months.push((new Date(2020, m)).toLocaleDateString('default', {month: 'short'}))
  }
  return months
}

console.log(getMonthNames())
> [
  'Jan', 'Feb', 'Mar',
  'Apr', 'May', 'Jun',
  'Jul', 'Aug', 'Sep',
  'Oct', 'Nov', 'Dec'
]

@machawk1
Copy link
Owner Author

machawk1 commented Sep 15, 2020

https://tools.ietf.org/html/rfc7231#section-7.1.1.1 specifies HTTP dates should be of the form "Jan", "Feb", "Nov", etc., so en-us (or equivalent) should be set for the locale string instead of relying on the browser/client's locale, cf.

function getMonthNames() {
  const months = []
  for (let m=0; m<12; m++) {
    months.push((new Date(2020, m)).toLocaleDateString('ar-EG', {month: 'short'}))
  }
  return months
}

console.log(getMonthNames())
> [
  'يناير',  'فبراير',
  'مارس',   'أبريل',
  'مايو',   'يونيو',
  'يوليو',  'أغسطس',
  'سبتمبر', 'أكتوبر',
  'نوفمبر', 'ديسمبر'
]

@ibnesayeed
Copy link
Contributor

Caveat: is the abbreviated month string in HTTP headers relative to the locale of the client or the server?

If you are talking about Date, Accept-Datetime, Memento-Datetime, and other alike headers, then the answer is a BIG FAT NO!!!. These are not affected by the locale, neither for the tokens nor for the timezone.

@machawk1
Copy link
Owner Author

machawk1 commented Sep 15, 2020

Slightly more succinct:

function getMonthNames() {
  const months = []
  Array.from({length: 12}, (_, m) => 
    months.push((new Date(2020, m)).toLocaleDateString('en-us', {month: 'short'}))
  )
  return months
}

@ibnesayeed, I figured that but wanted to be sure, so provided the above reference.

@ibnesayeed
Copy link
Contributor

function getMonths(locale, format){
    const formatter = new Intl.DateTimeFormat(locale, {month: format})
    return [...Array(12).keys()].map(m => formatter.format(new Date(2020, m)))
}

getMonths('ar', 'long')
// ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"]

getMonths('en', 'long')
// ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]

getMonths('en', 'short')
// ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

getMonths('es', 'short')
// ["ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sept.", "oct.", "nov.", "dic."]

getMonths('hi', 'short')
// ["जन॰", "फ़र॰", "मार्च", "अप्रैल", "मई", "जून", "जुल॰", "अग॰", "सित॰", "अक्तू॰", "नव॰", "दिस॰"]

@ibnesayeed
Copy link
Contributor

Here is a one-liner function definition:

const getMonths = (locale, format) => [...Array(12).keys()].map(m => (new Date(2020, m).toLocaleDateString(locale, {month: format})))

getMonths3('es', 'short')
// ["ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sept.", "oct.", "nov.", "dic."]

@machawk1
Copy link
Owner Author

@ibnesayeed Thanks for the revision.

I was testing with the spread operator in Node and was getting odd syntactic results. Using map is a good alternate solution, but the en locale is required to match up with the month in the HTTP Date header.

@ibnesayeed
Copy link
Contributor

ibnesayeed commented Sep 15, 2020

but the en locale is required to match up with the month in the HTTP Date header.

That's why I made it a parameterized function, you can call the function twice to create a list of months in the specific locale for use in the UI and one with en locale to deal with HTTP headers.

machawk1 added a commit that referenced this issue Sep 15, 2020
Co-authored-by: Sawood Alam <ibnesayeed@gmail.com>
@machawk1
Copy link
Owner Author

@ibnesayeed Thanks! Your contribution was noted in 3537420.

@machawk1
Copy link
Owner Author

machawk1 commented Sep 15, 2020

Adapting the UI to the user's locale should be a different issue but your function will be useful there (#311). This issue is to work toward removing moment.js, for which month name comparison is related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants