Moment.js: Получить первый день первой недели данного года

1

Я пытаюсь получить первый день первой недели в указанный день

Правильные результаты:

2017 = 2 января (понедельник)

2016 = 4 января (понедельник)

2015 = 1 января (четверг)

2014 = 1 января (среда)

2013 = 1 января (вторник)

Я могу получить первый день года:

moment().year(year).startOf('year') // All result is 1. jan XXXX

Затем я попробовал: (правильно)

moment().day(1).year(2017).week(1) // 2 Jan (Monday) (correct)

Но когда изменилось до 2016 года: (неверно)

moment().day(1).year(2016).week(1) // 10 Jan (Sunday) (wrong)

Кто-нибудь знает, как получить правильные результаты? (Im открыт для чистой date() JS date() также)

PS: номер недели находится в Норвегии

Игровая площадка: https://jsfiddle.net/6sar7eb4/

  • 0
    это должно быть достигнуто чисто в данный момент. не будет слишком сложно сделать это с помощью цикла
Теги:
date
time
momentjs
week-number

3 ответа

4
Лучший ответ

Нет необходимости использовать цикл, вы можете просто проверить, если номер недели не равен 1 используя week() который дает локализованный вывод

Вывод moment#week будет зависеть от локали для этого момента.

Вы должны установить локаль в момент, используя метод locale() чтобы узнать начало локального языка. Если вам нужно показать результат на английском языке, вы можете изменить локаль локально.

Здесь рабочий образец:

function getFirstDayOfFirstWeekByYear( year ) {
  // Create moment object for the first day of the given year
  let func = moment({year:year})
  // Check if 1st of January is in the first week of the year
  if( func.week() !== 1 ){
    // If not, add a week to the first day of the current week
    func.startOf('week').add(1, 'week');
  }
  // Return result using english locale
  return func.locale('en').format('D. MMMM YYYY (dddd)')
}

// Set Norwegian Bokmål locale globally
moment.locale('nb');

// Tester
[2017, 2016, 2015, 2014, 2013].forEach(function ( year ) {
  let s = '<li>' + getFirstDayOfFirstWeekByYear( year ) + '</li>'
  document.getElementsByTagName('BODY')[0].innerHTML += s
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.min.js"></script>
  • 1
    Вау, спасибо за этот трюк!
  • 0
    Мне бы очень хотелось, чтобы айтишники узнали, что языковой код не определяет локаль , а является неправильным. Кроме того, если смена языка меняет первую неделю года, вам необходимо знать, что два пользователя, сидящих рядом друг с другом, могут увидеть различную первую неделю только потому, что они выбрали другой язык. Первая неделя года по-разному определяется различными администрациями и культурами, вы не можете предположить, что это зависит от используемого языка.
Показать ещё 2 комментария
2

Я пытаюсь получить первый день первой недели в указанный день

Используя moment.js, чтобы получить первый день первой недели года на основе схемы ISO 8601, вы можете просто использовать первый день первой недели года, поскольку неделя ИСО начинается в понедельник:

// Return a moment.js object for the first weekday of the first week
// of the year using ISO 8601 scheme
function firstDay(year) {
  return moment(year + '011', 'GGGGWWE');
}

// Examples
['2015', '2016', '2017', '2018', '2019', '2020']
.forEach(function(year) {
  console.log('ISO First day of ' + year + ': ' +
               firstDay(year).format('dddd D MMMM, YYYY'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

Однако вы, похоже, не хотите использовать схему ISO, поэтому, если вы просто хотите получить первый день года, который не является субботой или воскресенью (т.е. игнорируйте схему ISO 8601), вы можете сделать (без moment.js ):

// Return Date for first day of year that is one of
// Monday to Friday
function firstDay(year) {
  var d = new Date(year, 0, 1);
  var day = d.getDay();
  d.setDate(d.getDate() + (day%6? 0 :  (++day%4)));
  return d;
}

// Examples
['2015', '2016', '2017', '2018', '2019', '2020']
.forEach(function(year) {
  console.log('First weekday of ' + year + ': ' + firstDay(year).toString());
});

обсуждение

Существует много разных схем для первого дня недели и первого дня года. Обычно используемой схемой является ISO 8601, где первый день недели - понедельник, а первая неделя года - та, в которой появляется первый четверг (или первый, который содержит по крайней мере 4 дня недели, тот же результат).

Согласно правилам ISO 8601, первый день первой недели 2019 года - понедельник 31 декабря 2018 года.

Если вы решите поддержать различные схемы (например, в Саудовской Аравии неделя начинается в субботу и заканчивается в пятницу, с рабочих дней с субботы по среду и в США неделя обычно с воскресенья по субботу с рабочими днями с понедельника по пятницу), тогда вам следует четко укажите, какую схему вы поддерживаете, а не просто предполагаете схему, основанную на выбранном пользователем языке. Схемы могут также основываться на других культурных факторах, таких как религия, поэтому не обязательно должны быть региональными или языковыми.

Какую схему следует использовать для английского человека в Саудовской Аравии? Исламский человек в Бутане? В Саудовской Аравии официальным языком для торговли является французский, но большинство международных обсуждений на английском языке, а национальный язык - арабский. Но они используют календарь хиджры, который не согласуется с грузинским календарем, который обычно используется в других местах и не определяется языком, а религией.

Там могут быть различия даже в одном и том же месте, при этом отделы того же правительства выбирают разные схемы, поэтому даже локаль (в правильном смысле этого слова) не является окончательным показателем того, какую схему использовать.

Если вы решили поддержать различные схемы, гораздо лучше принять стандартную схему (например, ISO 8601), и пусть изменить пользователь его на тот, который они предпочитают, если они хотят (и какие предпочтения в моем компьютере и календарное приложение позволяет мне делать),

  • 0
    Спасибо за ответ и хорошее описание!
  • 0
    moment('2017-01-02').isoWeek() это возвращение 1 и его правильно, но это правильный способ вернуть правильный номер недели в качестве моего вопроса?
Показать ещё 2 комментария
2

В любом случае, если вы счастливы сделать это в цикле, это работает

function getFirstDayOfFirstWeekByYear( year ){
  let D = 1;
  x = 0;
  while(x !== 1){
   x = moment('${year}-01-${D}').isoWeek();
   if(x === 1 ){
    return moment('${year}-01-${D}').format('D. MMMM YYYY (dddd)')
   }
   D++;
  };
}

Результаты

2. January 2017 (Monday)
4. January 2016 (Monday)
1. January 2015 (Thursday)
1. January 2014 (Wednesday)
1. January 2013 (Tuesday)
  • 0
    Спасибо, но это не так, результаты должны быть такими, как я написал (желтый фон)
  • 0
    Во всяком случае, я открыт для всех трюков: D
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню