0

I have a script that retrieves weeknumbers and years from an API and converts them to MomentJS date objects. Most of these entries have the correct date, only the last object goes wrong, and I can't see why.

This is the json-structure:

{
    results: {
        years: {
             2013: {
                 weeks: [
                  40, 41, 42, 43
                 ]
             }
        }
    }
}

In Javascript I do the following loop:

for(var i in results.years[year].weeks) {
    var week = parseInt(results.years[year].weeks[i]);
    var startDate = '' + year + '-' + ( (week.toString().length == 1) ? '' + '0' + week : week ) + '-1';
    var eindDate = '' + year + '-' + ( (week.toString().length == 1) ? '0' + week : week ) + '-7';
    console.log(moment(startDate, 'GGGG-WW-E', true)); // returns the right date object
    var startPeriode = moment(startDate, 'GGGG-WW-E');
    console.log(startPeriode); //If week = 43, this returns a date object with date (01 october 2013), rest is all good
    var eindPeriode = moment(eindDate, 'GGGG-W-E', true); //Object is always correct
}

The error currently only occurs when the week is 43 (is the last weeknumber retrieved from the API) and when calculating the startDate (eindDate is flawless currently). The moment object also contains some other variables, these look perfect, P.E.:

startDate._a = [
    '2013',
    9,
    21,
    0,
    0,
    0,
    0
]

I've also tried the following:

  • moment('2013-W43-1');
  • moment('2013-43-1', 'GGGG-W-E');

And making use of some of the elements in the moment object:

var startPeriode = moment('2013-W43-1');
var startDay = new Date(startPeriode._a[0] + '-' + startPeriode._a[1] + '-' + startPeriode._a[2]);
var startPeriode = moment(startDay);

I really don't know how to fix this, and why this goes wrong. Anyone some ideas?

Florent
  • 12,310
  • 10
  • 49
  • 58
  • Side note: Don't use `for-in` to loop array indexes unless you really know what it does and safeguard the loop properly; details [*Myths and realities of `for..in`*](http://blog.niftysnippets.org/2010/11/myths-and-realities-of-forin.html) (and here on SO: [*For each in an array. How to do that in JavaScript?*](http://stackoverflow.com/questions/9329446/for-each-in-an-array-how-to-do-that-in-javascript/9329476#9329476)). – T.J. Crowder Nov 21 '13 at 08:22
  • @T.J.Crowder Thanks! Will implement your tip! – Boite Witte Nov 21 '13 at 08:55
  • 1
    Are you sure that there is no some other changes in between? Because with your json structure and code I am getting correct dates for all of them. For example, for week 43: start date `Mon Oct 21 2013` and end date `Sun Oct 27 2013` – Anto Jurković Nov 21 '13 at 11:06
  • Regarding my previous comment. See [example at jsFiddle](http://jsfiddle.net/22gE3/). To see messages you have to open console. – Anto Jurković Nov 21 '13 at 11:40

1 Answers1

0

I couldn't reproduce your report of week 43 coming back Oct 1. It always came back Oct 21 for me. I tried the latest 2.4.0 version of moment.js, and older versions also, so I'm not sure why this would happen.

However, you may want to makes some changes:

  • The only reason you should create a moment from a string is if you are starting from a string input. Since you are starting from numeric input, it doesn't make sense to build a string just to parse it again.

  • You should not be paying much attention to the internal structure of a moment. The _a property (and others) are not intended for direct consumption. Instead, use one of the output methods, such as format (and others). If you want a JS Date, then just use .toDate() instead of trying assemble a date from parts.

Here is a cleaner version of the code. I'm sure you can adjust it for your purposes.

var weeks = results.years[year].weeks;
for(var i=0; i < weeks.length; i++) {

    var startPeriod = moment().year(year).isoWeek(weeks[i]).isoWeekday(1).startOf('day');
    var endPeriod = startPeriod.clone().isoWeekday(7).endOf('day');

    console.log(startPeriod.format("YYYY-MM-DD HH:mm:ss") + " - " + endPeriod.format("YYYY-MM-DD HH:mm:ss"))
}

Output (after setting the results and year variables)

2013-09-30 00:00:00 - 2013-10-06 23:59:59
2013-10-07 00:00:00 - 2013-10-13 23:59:59
2013-10-14 00:00:00 - 2013-10-20 23:59:59
2013-10-21 00:00:00 - 2013-10-27 23:59:59
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575