如何在javascript中处理时区

如何在javascript中处理时区,javascript,node.js,date,Javascript,Node.js,Date,我正在做一个从控制台运行的应用程序,它计算每个月在通过日期之间的星期日数,并且只输出有5个星期日的月份。所以在最后,如果有6个月有5个星期天,它会输出6。我以这种格式输入日期:2014年1月至2014年6月,参数以txt文件形式作为参数传递。我用php做的,非常简单,但在NodeJS中,我很痛苦。CES或CEST要杀了我。我试图只使用UTC日期,但我无法控制它,而且我有奇怪的输出。例如,如果我介绍“2014年1月-2014年6月”,我会得到两个月,但当我介绍“2016年6月-2017年2月”时,

我正在做一个从控制台运行的应用程序,它计算每个月在通过日期之间的星期日数,并且只输出有5个星期日的月份。所以在最后,如果有6个月有5个星期天,它会输出6。我以这种格式输入日期:2014年1月至2014年6月,参数以txt文件形式作为参数传递。我用php做的,非常简单,但在NodeJS中,我很痛苦。CES或CEST要杀了我。我试图只使用UTC日期,但我无法控制它,而且我有奇怪的输出。例如,如果我介绍“2014年1月-2014年6月”,我会得到两个月,但当我介绍“2016年6月-2017年2月”时,我会得到4个月,应该是3个月。 当程序计算五个星期日时,我放置了一个console.log(date),我得到了这些日期:

Sun Mar 30 2014 00:00:00 GMT+0100 (CET)
Sun Jun 01 2014 01:00:00 GMT+0200 (CEST)
2 //the output of months that have 5 sundays

Sun Jul 31 2016 00:00:00 GMT+0200 (CEST)
Sun Oct 30 2016 00:00:00 GMT+0200 (CEST)
Sat Dec 31 2016 23:00:00 GMT+0100 (CET)
Sat Feb 04 2017 23:00:00 GMT+0100 (CET)
4  //the output of months that have 5 sundays
如你所见,有两个星期六,23:00:00 GMT+0100(CET)。这个输出非常奇怪,我真的不知道如何处理这个问题。任何帮助都将不胜感激

// Make sure we got a filename on the command line.
if (process.argv.length < 3) {
  console.log('Usage: node ' + process.argv[1] + ' FILENAME');
  process.exit(1);
}
// Read the file and print its contents.
var fs = require('fs'), filename = process.argv[2];
fs.readFile(filename, 'utf8', function(err, data) {
    if (err) throw err;
    //split by carriage return
    data = data.split(/[\n\r]+/g);

    data.forEach(function(value){
        var secureDate = securizeData(value);
        var totalDays = getDaysBetweenDates(secureDate[0],secureDate[1],secureDate[2],secureDate[3]);
        calculateSundays(totalDays, secureDate[0],secureDate[1])    
    });

});

/**
 * Description: checks the data and returns it as an array
 * @param {string} data
 * @return {array} data
 */
function securizeData(data){

    //Looks for two strings (months) and two int ( year) matches with regexp 
    var matchCount = data.match(/([a-z]+ [0-9]{4})/g);
    if(matchCount == 0){
        process.exit('Insert a valid input');
    }

    //clean carriage return
    data = data.replace(/[\n\r]+/g,' ',data);
    //clean left over blank spaces
    data = data.replace(/  +/g,' ',data);


    //split data in an array
    data = data.split(' ');

    //check array length
    var nIndex = data.length;

    //returns an array which it's total index number is a pair number or else error
    if(nIndex%2==0){
        return (data);
    }else{
        process.exit('Insert a valid input');
    }
}

/**
 * Description:
 * @param {string} firstMonth
 * @param {int} firstYear
 * @param {string} secondMonth
 * @param {int} secondYear 
 */
function getDaysBetweenDates(firstMonth, firstYear, secondMonth, secondYear){

        var daysFirstDate = getDaysFirstDate(firstMonth, firstYear);
        var daysSecondDate =  getDaysSecondDate(secondMonth,secondYear);
        var daysBetweenDates = substractDays(daysFirstDate,daysSecondDate);
        return daysBetweenDates; 
}

/**
 * Description: substraction of two given unix dates
 * @param {int} daysFirstDate
 * @param {int} daysSecondDate
 * @return {int} days in unix format. Error if first date is later than second 
 */
function substractDays(daysFirstDate,daysSecondDate){

    if(daysFirstDate>daysSecondDate){
        process.exit('First date must be earlier than second date');
    }else{
        var datediff = daysSecondDate-daysFirstDate;
        datediff = datediff/(60*60*24)/1000;
        var roundedNumber = Math.floor(datediff)
        return (roundedNumber);
    }   
}

/**
 * Description: get the first date from day one in unix format
 * @param {string} @firstMonth
 * @param {int} @firstYear
 * @return {int} @date
 */
function getDaysFirstDate(firstMonth,firstYear){
    var month = getMonthFromString(firstMonth,firstYear);
    return (Date.UTC(firstYear, month ,01));
}

/**
 * Description: get the second date from last day of it's month in unix format
 * @param {string} @secondMonth
 * @param {int} @secondYear
 * @return {int} @date2
 */
function getDaysSecondDate(secondMonth,secondYear){

        var secondMonthNumber = getMonthFromString(secondMonth,secondYear);

        //Get last day of the month
        var lastDayMonth = getLastDayOfTheMonth(secondMonthNumber,secondYear);

        //Add last day of the month to secondDate
        return (Date.parse(secondMonth + ' ' + lastDayMonth +', ' + secondYear));

}

/**
 * Description: get month number from a month string
 * @param {string} @month
 * @return {int} @month
 */
function getMonthFromString(mon,year){
   return new Date(Date.parse(mon +" 1, "+year)).getMonth();
}

/**
 * Description: get the Last day of the Month given in params
 * @param {int} @secondYear
 * @param {int} @secondMonthNumber
 * @return {int} UTCDate
 *
 */
function getLastDayOfTheMonth(secondMonthNumber, secondYear){
    var lastDay = new Date(secondYear, secondMonthNumber +1, 0);
    return(lastDay.getUTCDate());
}

/**
 * Description:
 * @param {int} totalDays
 * @param {array} tempDate
 */
function calculateSundays(totalDays,month, year){

    var sundays={ num: '0' , output: '0' };
    var intMonth = { val: new Date(Date.parse(month + year)).getMonth() };
    intMonth.previousVal = intMonth.val;

    var d = Math.floor((new Date(year, intMonth.val,1)).getTime());
/// console.log(e);
//  process.exit();

    var d = new Date(year, intMonth.val, 1);
    var dayOfTheWeek = d.getUTCDay();

    for(var day = 2;day<=totalDays;day++)
    {

        resetSundaysIfMonthIncrease(intMonth, sundays);

        //update sundays
        if(dayOfTheWeek == 6) {
            sundays.num++;
        }

        //if there is 5 days in a month increase output
        if(sundays.num == 5)
        {
            sundays.output++;
            sundays.num = 0;
            console.log(d);
        }

        //increment date
        d.setUTCDate(d.getUTCDate() + 1);

        //update Day of the week
        dayOfTheWeek = d.getUTCDay();

        //update Month
        intMonth.val = d.getUTCMonth();
    }

    if(sundays.output == 0)process.exit("Please enter more than one month distance between dates \n");
    else console.log(sundays.output + "\n");
}  

/**
 * description: reset sunday counter to 0 if current month is greater than previous month 
 * @param {Object} intMonth
 * @param {Object} sundays
 */
function resetSundaysIfMonthIncrease(intMonth, sundays)
{   
    if(intMonth.val>intMonth.previousVal)
    {
        intMonth.previousVal = intMonth.val;
        sundays.num = 0;
    }
}
//确保命令行上有文件名。
如果(进程argv.length<3){
log('Usage:node'+process.argv[1]+'FILENAME');
过程。退出(1);
}
//读取文件并打印其内容。
var fs=require('fs'),filename=process.argv[2];
fs.readFile(文件名'utf8',函数(错误,数据){
如果(错误)抛出错误;
//按回车分开
data=data.split(/[\n\r]+/g);
data.forEach(函数(值){
var secureDate=securizeData(值);
var totalDays=GetDaysBetween日期(secureDate[0]、secureDate[1]、secureDate[2]、secureDate[3]);
计算星期日(总天数、secureDate[0]、secureDate[1])
});
});
/**
*描述:检查数据并将其作为数组返回
*@param{string}数据
*@return{array}数据
*/
函数securizeData(数据){
//使用regexp查找两个字符串(月)和两个int(年)匹配项
var matchCount=data.match(/([a-z]+[0-9]{4})/g);
如果(匹配计数==0){
process.exit('Insert a valid input');
}
//清洁车厢返回
数据=数据。替换(/[\n\r]+/g',,数据);
//清理剩余的空白
数据=数据。替换(/+/g',,数据);
//在数组中拆分数据
data=data.split(“”);
//检查数组长度
var nIndex=data.length;
//返回一个数组,该数组的总索引号为对号,否则返回错误
如果(索引%2==0){
返回(数据);
}否则{
process.exit('Insert a valid input');
}
}
/**
*说明:
*@param{string}firstMonth
*@param{int}第一年
*@param{string}secondMonth
*@param{int}第二年
*/
函数GetDaysBetween Dates(第一个月、第一年、第二个月、第二年){
var daysFirstDate=getDaysFirstDate(第一个月,第一年);
var daysSecondDate=getDaysSecondDate(第二个月,第二年);
var DaysBetween Dates=减去天数(daysFirstDate、daysSecondDate);
返回日期之间的日期;
}
/**
*描述:两个给定unix日期的减法
*@param{int}daysFirstDate
*@param{int}daysSecondDate
*unix格式的@return{int}天。如果第一个日期晚于第二个日期,则出错
*/
函数减法天数(daysFirstDate、daysSecondDate){
如果(daysFirstDate>daysSecondDate){
流程。退出(“第一个日期必须早于第二个日期”);
}否则{
var datediff=DaysSecondDaysFirstDate;
datediff=datediff/(60*60*24)/1000;
var roundedNumber=数学楼层(datediff)
返回(舍入编号);
}   
}
/**
*描述:以unix格式获取第一天的第一个日期
*@param{string}@firstMonth
*@param{int}@firstYear
*@return{int}@date
*/
函数getDaysFirstDate(第一个月,第一年){
var月=getMonthFromString(第一个月,第一年);
报税表(UTC日期(第一年,第二个月,第1年));
}
/**
*描述:以unix格式获取当月最后一天的第二个日期
*@param{string}@secondMonth
*@param{int}@secondYear
*@return{int}@date2
*/
函数getDaysSecondDate(第二个月,第二年){
var secondMonthNumber=getMonthFromString(secondMonth,secondYear);
//得到一个月的最后一天
var lastDayMonth=GetLastDayOfMonth(secondMonthNumber,secondYear);
//将月份的最后一天添加到secondDate
返回(Date.parse(secondMonth+“”+lastDayMonth+’,“+secondYear));
}
/**
*描述:从月份字符串中获取月份编号
*@param{string}@month
*@return{int}@month
*/
函数getMonthFromString(周一,一年){
返回新日期(Date.parse(mon+“1,”+year)).getMonth();
}
/**
*描述:获取参数中给定的月份的最后一天
*@param{int}@secondYear
*@param{int}@secondMonthNumber
*@return{int}UTCDate
*
*/
函数GetLastDayOfMonth(secondMonthNumber,secondYear){
var lastDay=新日期(第二年,第二个月编号+1,0);
return(lastDay.getUTCDate());
}
/**
*说明:
*@param{int}totalDays
*@param{array}tempDate
*/
函数计算星期日(总计天、月、年){
var sundays={num:'0',输出:'0'};
var intMonth={val:newdate(Date.parse(month+year)).getMonth()};
intMonth.previousVal=intMonth.val;
var d=Math.floor((新日期(year,intMonth.val,1)).getTime();
///控制台日志(e);
//process.exit();
var d=新日期(年,intMonth.val,1);
var dayofweek=d.getUTCDay();
for(var日=2;dayintMonth.previousVal)
{
intMonth.previousVal=intMonth.val;
sundays.num=0;
}
}

列出有5个星期日的月份似乎有两条规则:

  • 每月应超过28天;及
  • 第一个星期天的天数应少于当月28天以上的天数
  • 我已修改您的代码以供使用

    它看起来像:

    //确保命令行上有文件名。
    如果(进程argv.length<3){
    console.log('用法:节点'+process.ar