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

ISO weeks (start from monday)? #215

Closed
denisinvader opened this issue May 31, 2018 · 32 comments
Closed

ISO weeks (start from monday)? #215

denisinvader opened this issue May 31, 2018 · 32 comments
Labels
enhancement New feature or request released

Comments

@denisinvader
Copy link
Contributor

There are some handy methods in moment.js like .startOf('isoWeek'), .isoWeekday(1). They are very useful when Monday is the first day of week in current locale.

I didn't found any similar methods, are they exists?

@iamkun
Copy link
Owner

iamkun commented Jun 1, 2018

Check isoWeek here https://day.js.org/docs/en/get-set/iso-week


@denisinvader No such feature at the moment. > Monday is the first day of week in current locale I'm not familiar with this. Is that mean `.startOf('isoWeek')` is Monday, while `.startOf('week')` is still Sunday?

@denisinvader
Copy link
Contributor Author

@iamkun yes https://momentjs.com/docs/#/get-set/weekday/

I think it would be nice to define the first day of week globally by locale or plugin

@iamkun
Copy link
Owner

iamkun commented Jun 1, 2018

Should be defined in locale file I think.

@iamkun iamkun added the enhancement New feature or request label Jun 1, 2018
@denisinvader
Copy link
Contributor Author

I could work on this

@iamkun
Copy link
Owner

iamkun commented Jun 1, 2018

That would be nice. What's your plan then?

@denisinvader
Copy link
Contributor Author

let me dive in the code for a couple of days first

@iamkun
Copy link
Owner

iamkun commented Jun 1, 2018

Cool THX.

@hlehmann
Copy link

hlehmann commented Jun 1, 2018

Well regardless of the locale (depending on the user settings), I need to be able to get the start of the week to be monday (like the iso).

In moment: startOf('week') depend on the locale and startOf('isoWeek') is always monday.

But it could be startOf('localeWeek') and startOf('week') (locale should be default)

@denisinvader
Copy link
Contributor Author

@iamkun here is my plan:

  • Add new boolean parameter in locale configuration - for example mondayFirst, false by default;
  • Conditionally change calculation in Dayjs.$set and Dayjs.day methods
  • Conditionally change calculation in Dayjs.startOf method for the C.W case

I think adding new constant isoWeek only for .startOf method is unnecessary, its calculation could depends only on current locale

@hlehmann
Copy link

hlehmann commented Jun 2, 2018

And for those (like me) that want all locale weeks to start on Sunday or Monday they can override the mondayFirst parameter (is it easy ?). That way no need of an isoWeek.

@denisinvader
Copy link
Contributor Author

@hlehmann you mean the case when you want to use texts from some locale that starts from Sunday, but set "mondayFirst" in config (not in the locale)?

@hlehmann
Copy link

hlehmann commented Jun 2, 2018

Yes something like this

  • dayjs.locale('en', {mondayFirst:true})
  • dayjs.locale('en').extendLocale({mondayFirst:true})

@iamkun
Copy link
Owner

iamkun commented Jun 2, 2018

better in locale file monday: 0 or monday:1

Plus, I'm looking for a way to implement this as a plugin, rather in the main code.

@naulacambra
Copy link
Contributor

naulacambra commented Jun 28, 2018

I would suggest to instead of defining an attribute mondayFirst, could be something like startOfWeek and define 0 as sunday or 1 as monday.

@kvolkovich-sc
Copy link

Any news here?

kvolkovich-sc pushed a commit to OpusCapita/react-dates that referenced this issue Aug 6, 2018
Subscribe to this issue to remove ternary operators after it will be
fixed

iamkun/dayjs#215
kvolkovich-sc pushed a commit to OpusCapita/react-dates that referenced this issue Aug 6, 2018
Subscribe to this issue to remove ternary operators after it will be
fixed

iamkun/dayjs#215

Bugfixes
=====

Start week from sunday for "en" locale
kvolkovich-sc added a commit to OpusCapita/react-dates that referenced this issue Aug 6, 2018
Subscribe to this issue to remove ternary operators after it will be
fixed

iamkun/dayjs#215

Bugfixes
=====

Start week from sunday for "en" locale
@frenchbread
Copy link

Any update?

Here is my quick workaround:

const dayjs = require('dayjs')

const current_millis = dayjs().valueOf()
const add_day = (count, millis) => dayjs(millis).add(count, 'day').valueOf()

// ===== the actual "week starts on" stuff =====
const start_of_week = (millis, week_starts_on) => {
  if (week_starts_on === 'sunday') {
    return dayjs(millis).startOf('week').valueOf()
  } else if (week_starts_on === 'monday') {
    return add_day(1, dayjs(millis).subtract(1, 'day').startOf('week').valueOf())
  }
}

const end_of_week = (millis, week_starts_on) => {
  if (week_starts_on === 'sunday') {
    return dayjs(millis).endOf('week').valueOf()
  } else if (week_starts_on === 'monday') {
    return add_day(1, dayjs(millis).subtract(1, 'day').endOf('week').valueOf())
  }
}
// =====

console.log('===== week start =====')

console.log(`week starts on sunday: ${dayjs(start_of_week(current_millis, 'sunday')).format('DD MMM YYYY')}`)
console.log(`week starts on monday: ${dayjs(start_of_week(current_millis, 'monday')).format('DD MMM YYYY')}`)

console.log('===== week end =====')

console.log(`week ends on sunday: ${dayjs(end_of_week(current_millis, 'sunday')).format('DD MMM YYYY')}`)
console.log(`week ends on monday: ${dayjs(end_of_week(current_millis, 'monday')).format('DD MMM YYYY')}`)

@iamkun
Copy link
Owner

iamkun commented Feb 5, 2019

🎉 This issue has been resolved in version 1.8.4 🎉

The release is available on:

Your semantic-release bot 📦🚀

@iamkun iamkun added the released label Feb 5, 2019
@dantodev
Copy link

I found 2 solutions to override the weekStart globally (per locale). I don't know if this is the best way but maybe this helps somebody else too:

Solution 1:

import 'dayjs' from 'dayjs';
dayjs.Ls.en.weekStart = 1;

Solution 2:

import 'dayjs' from 'dayjs';
import en from 'dayjs/locale/en';
dayjs.locale({
    ...en,
    weekStart: 1,
});

@hoodwink73
Copy link

Hello @iamkun

Thank your efforts and helping me out here.

Will you be open to a PR where I add a section (basically what @dantodev has posted above) in the API reference of the startOf method?

@iamkun
Copy link
Owner

iamkun commented Apr 15, 2019

@hoodwink73 Thanks. But seems we don't have to mention this, do we?

@dantodev
Copy link

I had to dig in the source code to find this two solutions. Adding this to the docs would be better. Some one who needs this feature may not have the time, patience or skills to search in the soure code and may decide to use another library.

But which of my solutions is better for documentation? The first one is shorter but I don't think that the Ls variable should be used/documented as public API. The second solution is a bit more code but you could also override other locale settings at the same time.

@iamkun
Copy link
Owner

iamkun commented Apr 15, 2019

Solution 2 is better I think.

However, a new plugin 'isoWeek' should be made to fix this issue is better than the temporary solution above.

@dantodev
Copy link

A plugin would be a suitable solution as well. But it should still have the option to set different isoWeek values for different locales.

@ghost
Copy link

ghost commented Apr 15, 2019

According to moment.js, Gets or sets the ISO day of the week with 1 being Monday and 7 being Sunday. There's no other option cause it's ISO standard.

@denisinvader
Copy link
Contributor Author

I think the current solution is great and if you need to redefine weekStart for some reason, merging locale fits perfectly in the current API (as in the example above)

dayjs.locale({
    ...en,
    weekStart: 1,
});

@kirillgroshkov
Copy link

Also needed .isoWeekday plugin. Quickly made smth like this:

import { Dayjs, PluginFunc } from 'dayjs'

declare module 'dayjs' {
  interface Dayjs {
    /**
     * 1: Monday
     * ...
     * 6: Saturday
     * 7: Sunday
     */
    isoWeekday (): number
  }
}

const isoWeekday: PluginFunc = (_opt, dayjsClass) => {
  dayjsClass.prototype.isoWeekday = function (this: Dayjs) {
    const { $W } = this as any
    return $W <= 0 ? $W + 7 : $W
  }
}

export default isoWeekday

@briefguo
Copy link

Hello @iamkun.
I think that, both of them should be supported. 'isoWeek' is not only a regional thing we can use dayjs.locale({ ...zh }); to implement, but also a regional-less thing we can use both isoWeek and week.

I approved that it should be handled in local(), but it also could be a single accessible method

@iamkun
Copy link
Owner

iamkun commented Mar 2, 2020

add support isoWeek #811

@mariusa
Copy link

mariusa commented Apr 8, 2020

Hi, question: in all locales/settings

  1. dayjs().day(7) is always Sunday?

  2. dayjs().day() is either 0 or 7, depending on locale ?

@robertwt7
Copy link

I think the current solution is great and if you need to redefine weekStart for some reason, merging locale fits perfectly in the current API (as in the example above)

dayjs.locale({
    ...en,
    weekStart: 1,
});

This one works perfectly, will be very helpful for react app where I need to load it globally on beginning. While using the plugin doesn't seem to work on my other calendar if defined at the top level app

@simeonpashley
Copy link

I found 2 solutions to override the weekStart globally (per locale). I don't know if this is the best way but maybe this helps somebody else too:

Solution 1:

import 'dayjs' from 'dayjs';
dayjs.Ls.en.weekStart = 1;

Solution 2:

import 'dayjs' from 'dayjs';
import en from 'dayjs/locale/en';
dayjs.locale({
    ...en,
    weekStart: 1,
});

With dayJS v1.10.7, following Solution 2 breaks support for ordinals "Do" (?st, ?nd, ?rd) when formatting with the error ordinal is not a function in advancedFormat.

Using Solution 1 retains ordinal functionality and shifts the weekday to Monday.

@axelthat
Copy link

axelthat commented May 27, 2022

A better way to update:

import dayjs from 'dayjs'
import updateLocale from 'dayjs/plugin/updateLocale'

dayjs.extend(updateLocale)
dayjs.updateLocale('en', {
    weekStart: 1,
})

https://day.js.org/docs/en/customization/customization

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request released
Projects
None yet
Development

No branches or pull requests