2016-06-15 1 views
0

Есть ли способ разумно найти начало и конец определенного объекта Date в JavaScript для определенного временного окна (месяц, день, год, неделя)?Создать начальный и конечный диапазоны для конкретной даты и идентификатора JavaScript (месяц, день, год, неделя)?

Я хочу, чтобы иметь возможность указывать любую дату, затем идентификатор (например, месяц, неделю, день или год), затем логическое значение для того, нужно ли использовать время UTC. Он должен вернуть объект JavaScript с двумя ключами (startTime, endTime), где значениями для этих ключей являются миллисекунды эпохи (или даты), представляющие мой диапазон.

Я начал писать функцию, чтобы сделать это (смотри ниже), просто интересно, если есть более разумный способ идти о делать это:

/** 
* @param rangeValue; String ('year', 'month', 'week', 'day') 
* @param dateTime; JavaScript Date Object. 
* @param useUTC; Boolean. Determines whether or not UTC is to be used or default browser time 
* @returns {{}}; startTime and endTime, in epoch milliseconds 
*/ 
function generateTimeRange(rangeValue, dateTime, useUTC) { 
    var dateRange = {}; 

    var year = dateTime.getUTCFullYear(); 
    var month = dateTime.getUTCMonth(); 
    var dayOfWeek = dateTime.getUTCDay(); 
    var day = dateTime.getUTCDate(); 

    if (!useUTC) { 
    year = dateTime.getFullYear(); 
    month = dateTime.getMonth(); 
    dayOfWeek = dateTime.getDay(); 
    day = dateTime.getDate(); 
    } 

    if (rangeValue === 'year') { 
    dateRange.startTime = new Date(year, 0, 0, 0, 0, 0, 0).getTime(); 
    dateRange.endTime = new Date(year + 1, 0, 0, 0, 0, 0, 0).getTime() - 1; 
    } else if (rangeValue === 'month') { 
    dateRange.startTime = new Date(year, month, 0, 0, 0, 0, 0).getTime(); 
    month += 1; 
    if (month > 11) 
     year += 1; 
    dateRange.endTime = new Date(year + 1, month % 12, 0, 0, 0, 0, 0).getTime() - 1; 
    } else if (rangeValue === 'week') { 
    // Do week calculation 
    } else if (rangeValue === 'day' { 
    // Do day calculation 
    } 
    return dateRange; 
} 

EDIT: Просто обнаружил, что Moment.js имеет startOf и endOf методы. Есть ли элегантный способ сделать это без внешних библиотек?

+0

Перед тем, как сделать «начало» и «конец» Вы должны определить, что они , Например. Сеансы ISO начинаются в понедельник, недели США обычно в воскресенье. Конец недели может быть в воскресенье (ISO), в субботу (США) или в пятницу (западная рабочая неделя).Некоторые культуры имеют деловую неделю с субботы по среду или четверг, а пятница - это эквивалент западного воскресенья. – RobG

+0

Обратите внимание, что в 'new Date (year, 0, 0, 0, 0, 0, 0) значение дня должно быть 1, иначе вы получите 31 декабря предыдущего года. ;-) – RobG

ответ

1

Это, вероятно, более подходит для обзора кода.

Кажется бесполезным получить все части UTC, а затем посмотреть, нужны ли они вам и получить локальные части, если нет. Просто получите те, которые вы хотите. А поскольку UTC должно использоваться везде, если требуется, то:

var UTC = useUTC? 'UTC' : ''; 

Теперь вы просто сделать:

var year = dateTime.['get' + UTC + 'FullYear'](); 
var month = dateTime.['get' + UTC + 'Month'](); 

и так далее. Но нет необходимости делать это, если не нужно. Тогда есть:

if (rangeValue === 'year') { 

, что является довольно строгим, вы можете его не чувствительны к регистру, так:

if (/^year$/i.test(rangeValue)) 

затем

dateRange.startTime = new Date(year, 0, 0, 0, 0, 0, 0).getTime(); 

получит 31 декабря предыдущего года, поскольку вы» установите дату на 0. Это также будет 00:00:00 для часового пояса хост-системы, а не UTC (если оно указано). Если вы предъявите год и месяц, все остальные значения равны нулю (за исключением даты, это 1) по умолчанию, и вы хотите использовать UTC, если указано так:

dateRange.startTime = (UTC? new Date(Date.UTC(year,0)) : new Date(year,0)).getTime(); 

Аналогично для конечного времени:

dateRange.endTime = (UTC? new Date(Date.UTC(+year+1,0)) : new Date(+year+1,0)).getTime() - 1; 

Вы на самом деле не нужно GetTime поскольку вычитание будет принуждать значение числа в любом случае, но он держит вещи последовательно. Для этого месяца схожа:

// Get the month 
var month = dateTime['get' + UTC + 'Month'](); 
// If month range is required 
if (/^month$/i.test(rangeValue)) { 
    // Get the start of the month 
    var monthStart = UTC? new Date(Date.UTC(year,month)) : new Date(year,month); 
    // Assign the time value 
    dateRange.startTime = monthStart.getTime(); 
    // Adjust to end of month. 
    // The setTime method returns the time value, so no need for getTime 
    dateRange.endTime = monthStart['set' + UTC + 'Month'](monthStart['get' + UTC + 'Month']() + 1, 1) - 1; 
    return dateRange; 
} 

Так положить эту часть вместе:

function generateTimeRange(rangeValue, dateTime, useUTC) { 
 
    var dateRange = {}; 
 
    var UTC = useUTC? 'UTC' : ''; 
 
    var year = dateTime['get' + UTC + 'FullYear'](); 
 

 
    if (/^year$/i.test(rangeValue)) { 
 
    dateRange.startTime = (UTC? new Date(Date.UTC(year,0)) : new Date(year,0)).getTime(); 
 
    dateRange.endTime = (UTC? new Date(Date.UTC(year+1,0)) : new Date(year+1,0)).getTime() - 1; 
 
    return dateRange; 
 
    } 
 

 
    var month = dateTime['get' + UTC + 'Month'](); 
 
    if (/^month$/i.test(rangeValue)) { 
 
    var monthStart = UTC? new Date(Date.UTC(year,month)) : new Date(year,month); 
 
    dateRange.startTime = monthStart.getTime(); 
 
    // The setMonth method returns the time value, so no need for getTime 
 
    dateRange.endTime = monthStart['set' + UTC + 'Month'](monthStart['get' + UTC + 'Month']() + 1, 1) - 1; 
 
    return dateRange; 
 
    } 
 
    // Add week, day, etc. 
 
} 
 

 
var dr = generateTimeRange('year', new Date(), false); 
 
console.log('Start: ' + new Date(dr.startTime) + '\nEnd: ' + new Date(dr.endTime)); 
 

 
dr = generateTimeRange('month', new Date(), false); 
 
console.log('Start: ' + new Date(dr.startTime) + '\nEnd: ' + new Date(dr.endTime)); 
 

 
// UTC tests, note if west of GMT will seem to be one day early: 
 

 
dr = generateTimeRange('year', new Date(), true); 
 
console.log('Start: ' + new Date(dr.startTime) + '\nEnd: ' + new Date(dr.endTime)); 
 

 
dr = generateTimeRange('month', new Date(), true); 
 
console.log('Start: ' + new Date(dr.startTime) + '\nEnd: ' + new Date(dr.endTime));

+0

Спасибо @RobG! Я в конечном итоге посмотрел, как Moment.js реализует свои функции 'startOf' и' endOf' [здесь] (https://github.com/moment/moment/blob/develop/src/lib/moment/startend) -of.js). Они используют случай переключения, где они устанавливают каждую отдельную единицу по мере ее прохождения через инструкцию. Ваш метод немного приятнее для моего использования, я не знал, что вы можете динамически запускать функции в квадратных скобках. – Alexander

+0

Функции - это объекты, поэтому вы можете использовать квадратную скобку для доступа к свойствам, как и любой другой объект. :-) – RobG

Смежные вопросы