首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据计算的算法优化

数据计算的算法优化
EN

Code Review用户
提问于 2014-02-19 10:56:42
回答 1查看 424关注 0票数 3

我需要计算给定日期的日历周。制约因素:

  • 如果周在星期一开始的话,应该根据ISO 8601进行正确的计算
  • 如果这周从周日开始,它应该根据美国的标准来计算
  • 它应该是紧凑和快速的,因为例程经常被调用。
  • 即使年初不是一月(例如,财政年度从10月开始),它也应该有效。

这就是我目前的情况:

代码语言:javascript
复制
Date.prototype.getWeek = function() { // ISO Week

    this.firstDay = 4;  // ISO 8601: Week with the first thursday which contains the 4th of January
    this.thursday = 4;  // 0 = Sunday OR Monday (if WeekStart = "M")

    if ( this.weekStart != 'M' )
    {
        this.firstDay = 1;  // switch to US norm: Week with the 1st of January
        this.thursday = 0;
    }

    // finding the date of the "thursday" in this week
    var donnerstag = function(datum, that) { 
        var Do = new Date(datum.getFullYear(), datum.getMonth(), 
                   datum.getDate() - datum.getDay() + that.thursday, 0, 0, 0);
        return Do;
    };

    // copy date, hourly times set to 0
    var Datum = new Date(this.getFullYear(),this.getMonth(),this.getDate(), 0, 0, 0); 

    var DoDat = donnerstag(Datum, this);        // the date of the first week
    var kwjahr = DoDat.getFullYear();           // the year of that date

    // diff from there to this date
    var DoKW1 = donnerstag(new Date(kwjahr, this.FYStart, this.firstDay), this); 
    //console.log(DoDat + " - " + DoKW1);

    // calculate the week
    var kw = Math.floor(1.5+(DoDat.getTime()-DoKW1.getTime())/86400000/7) 

    // adjust overflow
    if ( kw < 1 )
        kw = 52 + kw;

    return kw;
};

是否还有更紧凑的算法,或者可以从性能的角度进行优化?

EN

回答 1

Code Review用户

发布于 2014-02-20 01:40:28

根据我的经验,对于这个简单的任务来说,Moment.js有点太重了。不久前做了一些分析,库为这个任务做了太多的动作。也许是出于健壮性/可伸缩性/兼容性的目的,但是仍然很重。

直截了当地说,看看这篇博客文章,它演示了他获得ISO周的方法。它将附加一个额外的getWeek方法到本机Date对象。我在我的一个项目中使用了这个函数来替代Moment.js的ISO week函数。

代码语言:javascript
复制
Date.prototype.getWeek = function () {  
    // Create a copy of this date object  
    var target  = new Date(this.valueOf());  

    // ISO week date weeks start on monday so correct the day number  
    var dayNr   = (this.getDay() + 6) % 7;  

    // ISO 8601 states that week 1 is the week with the first thursday of that year.  
    // Set the target date to the thursday in the target week  
    target.setDate(target.getDate() - dayNr + 3);  

    // Store the millisecond value of the target date  
    var firstThursday = target.valueOf();  

    // Set the target to the first thursday of the year  
    // First set the target to january first  
    target.setMonth(0, 1);  
    // Not a thursday? Correct the date to the next thursday  
    if (target.getDay() != 4) target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);  

    // The weeknumber is the number of weeks between the   
    // first thursday of the year and the thursday in the target week  
    return 1 + Math.ceil((firstThursday - target) / 604800000); // 604800000 = 7 * 24 * 3600 * 1000  
}  

至于你的代码:

  • 我建议尽量用简练的英语。对于喜欢冗长、有目的的命名的审查员来说,可读性将是一个问题。
  • 与我所提供的建议代码相比,您的版本创建了更多的Date对象(我数了3个)。如果您在一组表数据上调用此函数,这可能是一个重要的瓶颈。这将消耗内存和CPU时间。
  • “克隆”一个Datevar clone = new Date(original.valueOf());一样简单。不需要单独调用月份、日期等来安装克隆。
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/42131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档