Методы класса Date

У класса Date имеется огромное количество методов — 37 (у самого «большого» класса ActionScript MovieClip их всего 30). Но не стоит пугаться этого числа: методы класса Date однотипные и легко поддаются систематизации. Так, за исключением методов UTC() и toString(), все методы класса Date() могут быть разделены на две категории.

• Get-методы. Используя эти методы, можно определить любую характеристику момента времени. Например, метод getHours() возвращает час (по локальной шкале), к которому относится момент времени, соответствующий объекту класса Date. Метод getYear() определяет год, метод getMilliseconds() — миллисекунду и т. д. Особенностью get-методов является то, что они не принимают параметров.

• Set-методы. Позволяют произвольным образом изменить любую из характеристик момента
времени, описываемого объектом класса Date, Например, метод setDate() изменяет дату, setSeconds() — секунду, setMonth() — месяц. Все set-методы принимают один параметр и возвращают новое значение времени (в машинном формате).

Обычно set-методы применяются, если необходимо сопоставить два момента времени, у которых различается только одна или несколько характеристик.


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

Второй подход к систематизации методов класса Date основан на том, со временем в какой шкале работает соответствующий метод.

• Методы локального времени. Чаше применяются методы, возвращающие или устанавливающие временные характеристики, исходя из локальной шкалы той зоны, в которой находится машина пользователя. Такие методы полезны для создания разного рода часов, календарей и таймеров.

У методов локального времени есть недостаток, заключающийся в плохой поддержке летнего и зимнего времени. Так, если считывается текущий момент времени, то час и прочие его характеристики будут определены (или заданы) абсолютно корректно. Это связано с тем, что методы локального времени используют данные операционной системы, для которой то, переходить или нет на зимнее время, вы указываете самостоятельно. Но если вы попытаетесь вычислить какую-то характеристику момента времени из прошлого или будущего, то переходы на зимнее время учтены в принципе не будут.


Из-за этого вероятность того, что время будет определено неверно, весьма высока (вероятность ошибки на час составляет 50 %). В таких случаях нужно или использовать универсальное время, или самостоятельно вносить поправку.

// Если бы методы локального времени работали полностью корректно, то
// моментам, которые разделяет ровно полгода, всегда бы соответствовал
// час разницы
var time:Date=new Date();
trace(time.getHours()); // Выводит "11"
time.setMonth(6); // "Переносимся" ровно на полгода назад
trace(time.getHours()); // Выводит "11"

Bo Flash 5 используются правила перехода на зимнее время, принятые в США. Это осложняет применение методов локального времени на машинах пользователей из других стран, поэтому, начиная со Flash 6. часовой сдвиг определяется исходя из установок в операционной системе.

• Методы универсального времени. Реже на практике применяются методы, работающие с универсальным, или UTC-временем. Как вы помните, UTC-временем принято называть гринвичское время, измеренное относительно шкалы UTC. Никаких принципиальных различий между локальным временем и универсальным нет. Первое может быть легко получено из второго, если известен номер временной зоны.

Универсальное время используется, если необходимо синхронизировать удаленные процессы.


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

В названии всех методов универсального времени имеется корень UTC (например, getUTCTime()). Все методы класса Date, за исключением UTCQ, являются наследуемыми. Метод LTC() статичен (т. е. является свойством самого конструктора Date()). Работа со временем в машинном формате Иногда задают вопрос о том, почему инструменты класса Date реализованы в форме методов, а не свойств. Не проще было бы, если бы каждой временной характеристике соответствовало отдельное свойство (например, не getMonth(), а month)? Одной из причин использования именно методов является то, что для определения или задания каждой характеристики необходимо произвести вычисления. Внутренний же формат адресации момента времени — это не годы, месяцы и часы, а количество миллисекунд, прошедших с 1 января 1970 года по гринвичскому времени до этого момента. Если момент времени относится к периоду до 1970 года, то миллисекунды отсчитываются от него и до точки начала отсчета. Значение времени при этом имеет отрицательный знак.

Машинное время сохраняется не как локальное, а как универсальное. В локальный формат оно пересчитывается с учетом сдвига временной зоны, который вы указываете, настраивая часы операционной системы.

У класса Date за работу со временем в машинном формате отвечают следующие методы:

• getTime() — возвращает машинное время как число;
• setTime() — переопределяет время, хранимое объектом класса Date;
• UTC() — переводит дату из стандартного представления в машинное.

Метод getTime() обычно применяется для точного измерения момента времени, прошедшего между некоторыми событиями. Для примера приведем код, проверяющий, за сколько выполнится пустой цикл из миллиона итераций:

var time1:Number=(new Date()).getTime();
for (var i=0; i<1000000; i++) {
}
trace((new Date()).getTime()-time1); // Выводит "5147"

Перевести время в миллисекундах в более традиционные единицы очень просто. Для этого нужно использовать третью форму конструктора Date(), учитывая, что точкой отсчета является момент времени, у которого вес характеристики, кроме года и даты, равны нулю (естественно, что характеристики при этом должны быть вычислены относительно универсального времени):

var begin_time:Number={new Date()).getTime();
for (var i=0; i<1000000; i++) {
}
var delta_time:Number=(new Date()).getTime()-begin_time;
var time:Date-new Date(delta_time);
trace("Процесс завершился за:\r"+(time.getUTCFullYear()-1970)+" лет\r" +
time.getUTCMonth() + " месяцев\r" + (time.getUTCDate()-1) + " дней\r" +
time.getUTCHours() + " часов\r" + time.getUTCMinutes() + " минут\r" +
time.getUTCSeconds() + " секунд\r" + time.getUTCMilliseconds() + "
миллисекунд");
/* Выводит следующее:
"Процесс завершился за:
0 лет 0 месяцев 0 дней 0 часов 0 минут 5 секунд 307 миллисекунд" */

Перевести время в миллисекундах в традиционные единицы легко и без обращения к классу Date. Для этого достаточно разделить его на число, равное количеству миллисекунд в интересующей единице, а затем округлить результат.

Минимальный временной промежуток, который может быть измерен методом getTime(), составляет 10 миллисекунд. Чтобы в этом убедиться, можно использовать следующий код:

var time1:Number=(new Date()).getTime();
var time2:Number=null;
for (var i=0; i<10000; i++) {
time2=(new Date()).getTime();
trace(time2-time1);
time1-=time2;
} // Выводит "0 0 0 0 0 10 0 0 0 0..."

Вероятно, точность метода getTime() напрямую зависит от точности системных часов. Последняя, следовательно, составляет 100 прерываний в секунду. На более старых машинах частота прерываний системных часов может быть и ниже (18 в секунду).

ActionScript дает возможность заменить хранимое объектом класса Date время, основываясь на машинном представлении нового его значения. Для этого служит метод setTime():

var date:Date=new Date();
date.setTime(565436745768);
trace(date.getFullYear()); // Выводит "4987"

Иногда возникает задача перехода от традиционных единиц к машинному представлению времени. Конечно, ее можно решить, просто создав соответствующий объект класса Date и применив к нему метод getTime(). Для примера выясним, сколько миллисекунд осталось до нового года:

trace((new Date(2004, 0)).getTime()-(new Date()).getTime()); // Выводит "711372224"

Однако перевести время в машинную форму можно и проще, не создавая объект класса Date. Для этого нужно использовать единственный статичный метод класса Date — UTC(). Набор параметров данный метод принимает точно такой же, как и конструктор Date() во второй форме. Рассмотрим пример:

trace(((Date.UTC(2005,0))-Date.UTC(2004,0))/(1000*60*60*24));
// Выводит "366" (2004 год - високосный)

Определение и задание года
У класса Date целых шесть методов, предназначенных для чтения и задания года, к которому относится момент времени. По особенностям возвращаемого и принимаемого значений их можно разделить на две группы.

• getYear() и setYear(). Эти методы работают с традиционной для компьютеров формой представления года. Значит, годом начала отсчета является 1900. Соответственно, 1999 год в этой системе будет 99-м, а 2003-103. Годы до 1900 обозначаются отрицательными числами (например, 1798 год будет-102).

Методы getYear() и setYear() работают в локальной шкале времени. Аналогичных им UTC-
методов в ActionScript нет,

• getFullYear(), setFullYear() (локальное время) и getUTCFullYear(), setUTCFuilYear() (универсальное время), Работают со стандартным четырехзначным обозначением года. Годы до рождества Христова задаются отрицательными числами.

На практике удобнее применять методы второй группы. Методы же первой группы могут быть полезны, если код ActionScript взаимодействует с какой-то внешней технологией, в которой год обозначается традиционным образом. Например:

var date:Date=new Date(0,0);
trace(date.getFullYear()); // Выводит "1900"
trace(date.getYear()); // Выводит "0"

Определение и задание месяца
Определить месяц, к которому относится описываемый объектом класса Date момент, позволяют методы getMonth() (применяется локальная шкала) и getUTCMonth() (используется универсальное время). Изменить значение месяца дают возможность методы setMonth() и setUTCMonth(). Обозначаются месяцы при помощи своих порядковых номеров. Отсчет ведется с нуля, т. е. январю соответствует 0, февралю — 1 и т. д. Рассмотрим пример:

// Определяем, какой месяц будет через 100 дней
var date:Date=new Date();
date.setTime(date.getTime()+100*1000*60*60*24);
function month(numb:Number):String {
var arr:Array=["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль",
"Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"];
return arr[numb];
}
trace(month(date.getMonth())); // Выводит: Апрель

Определение и задание дня месяца
Чтобы определить день месяца, к которому относится некоторый момент, нужно использовать метод getDate() (локальное время) или getUTCDate() (универсальное время). Задать день недели позволяют методы setDate() и setUTCDate(). Месяцы обозначаются не названиями, а своими порядковыми номерами. Отсчет их, в отличие от месяцев, ведется с 1, а не с 0.

Для примера вычислим, какое число будет через 100 дней:

var date:Date=new Date();
date.setTime(date.getTime()+100*1000*60*60*24);
trace(date.getDate()); // Выводит: 1

Определение дня недели
Зная год, месяц и число, можно без особой сложности определить, к какому дню недели относится момент времени. Эту работу выполняют методы getDay() (локальное время) и getUTCDay() (глобальное время). День недели возвращается, как число от 0 (понедельник) до 6 (воскресенье).

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

// Вычислим, какой день недели будет через 100 дней
var date:Date=new Date();
date.setTime(date.getTime()+100*1000*60*60*24);
function day(numb:Number):String {
var arr:Array=["Понедельник", "Вторник", "Среда", "Четверг", "Пятница",
"Суббота", "Воскресенье"];
return arr[numb];
}
trace(day(date.getDay())); // Выводит: Пятница

Определение и задание часа, минуты, секунды и миллисекунды
Создавая часы и таймеры, бывает необходимо определить, сколько в данный момент на системных часах компьютера часов, минут, секунд и, реже, миллисекунд по локальной шкале данной временной зоны или по универсальной шкале UTC. Иногда же данные характеристики приходится в объекте класса Date перезаписывать, чтобы обработать схожий момент из прошлого или будущего.

Методы, которые служат для решения данных задач, идентичны, поэтому рассмотрим их вместе:

• getHours(), setHours() (локальное время) и getUTCHours(), setUTCHours() (универсальное время) — считывают и записывают значение часа. Отсчет часов ведется с нуля (как на обычных электронных часах);

• getMinutes(), setMinutes() (локальное время) и getUTCMinutes(), setUTCMinutes() (универсальное время) — методы, возвращающие и задающие значение минуты. Работают с целыми числами от 0 до 59;

• getSeconds(), setSeconds() (локальное время) и getUTCSeconds(), setUTCSeconds() (универсальное время) — методы, считывающие и записывающие номер секунды, соответствующей данному объекту класса Date. Могут работать с числами от 0 до 59;

• getMilliseconds(), setMilliseconds() (локальное время) и getUTCMilliseconds(), setUTCMilliseconds() (универсальное время) — методы, возвращающие и записывающие наименьшую характеристику момента времени — миллисекунды. Работают с числами от 0 до 999.

То, что минимальное изменение времени, которое может быть зафиксировано при помощи объекта класса Date, составляет 10 миллисекунд, означает, что последняя цифра возвращаемого методом getMilliseconds() или getUTCMilliseconds() значения будет неизменна в течение одной секунды. Это нужно учесть при создании таймера, округлив до двух цифр.

Если перечисленным методам группы set передается значение, лежащее в пределах положенного для их аргументов интервала (0-23 — часы, 0-59 — минуты и секунды, 0-999 — миллисекунды), то производимое ими изменение одной из характеристик не приводит к изменению остальных. Если же аргумент выходит за пределы положенного для него интервала, то он пересчитывается в более крупные единицы, чем устанавливает данный метод. В результате изменяются и другие характеристики момента времени. Например, передача методу setMinutes() значения 100 вызовет изменение величины, возвращаемой методом getHours() (а может даже и getDate() или getMonth()). Методам группы set можно передать и отрицательную величину. При этом время будет пересчитано в сторону уменьшения. Например:

var date:Date=new Date();
trace(date.getDate()); // Выводит: 23
trace(date.setHours(-100);
trace(date.getDate()); // Выводит: 18

В качестве примера использования рассмотренных методов приведем код, создающий простой таймер:

// Создаем поле, в котором Судет отображаться время
this.createTextField("timer", 0, 100, 150, 145, 27), timer.border=true;
timer.setNewTextFormat(new TextFormat("Lucida Console", 20, 0, true));
// Создаем функцию, выводящую в поле текущее время
function time():Void {
var tm:Date=new Date();
timer.text=tm.getHours() + ":" + tm.getMinutes() + ":" + tm.getSeconds()
+ ":" + Math.round(tm.getMilliseconds()/10);
// Обновляем экран, чтобы изменение отобразилось
updateAfterEvent();
}
setInterval(time, 10); // Обновляем таймер 100 раз в секунду

Определение смещения часового пояса
Пересчитать локальное время в универсальное (или произвести обратную операцию) очень просто. Но для этого в общем случае необходимо знать, на сколько часов смещена локальная шкала по сравнению с гринвичской. Данное смешение задается пользователем при настройке часов операционной системы и может изменяться от — 12 до 12 часов (возможны и дробные значения, например 4 часа 30 минут — смещение времени на широте Кабула). В ActionScript определить разность локального и глобального времени в минутах позволяет метод getTimezoneOffset(). Например:

var date:Date=new Date();
trace(dats.getHours()==(date.getUTCHours()-date.getTimezoneOffset()/60) %24);
// Выводит: true

Смещение локального времени — это атрибут не конкретного объекта класса Date, а операционной системы. Поэтому его невозможно изменить средствами ActionScript. Особенности преобразования объектов класса Date в строки и числа Объекты данных типа object при преобразовании к типу String дают следующую, в общем, малоинформативную запись:

[object Object]

Если объект не принадлежит ни к одному классу (такими объектами, например, являются _global и объекты активизации функций), то преобразование в строку дает [type Object]

Исключением из описанных правил являются объекты классов Array, Number, Boolean, String и Date. Массивы при приведении к типу String дают строку, представляющую собой список разделенных запятыми элементов. Каждый элемент, естественно, также переводится в строку. Например:

trace([{}, 3, [2, 1]]); // Выводит: [object Object],3,2,1

Объекты классов Number, Boolean и String перед преобразованием переводятся в соответствующую величину элементарного типа, которая затем и приводится к типу String. Объекты класса Date при преобразовании к типу String дают строку, содержащую практически полную информацию о данном моменте времени, В ней приводятся соответствующие ему значения секунды, минуты, часа, даты, месяца, года и даже дня недели и смещения временной зоны.

Например:
trace(new Date()); // Выводит: Wed Dec 2A 00:41:52 GMT+0300 2003

Если результат преобразования объекта класса Date в строку должен быть сохранен, то нужно использовать метод toString().

На практике строки, получаемые при преобразовании объекта класса Date к типу String, применяются редко. Потенциально их можно было бы использовать для хранения информации о некоторых событиях во внешних файлах или передаче этой информации, например, другому SWF-фильму или серверному скрипту. Осложняет применение таких строк то, что на их основе трудно создать новый объект класса Date. В ЕСМА-262 для решения этой задачи служит особый статичный метод parse(), который, увы, в ActionScript не поддерживается. Поэтому хранить и передавать информацию о времени все же лучше в машинном формате.

К типу Number объекты класса Date также преобразовываются весьма специфично. Если объекты всех остальных классов (кроме Boolean, Number и String, которым в подобных операциях соответствуют величины элементарных типов) дают при приведении к числам NaN, то объекты класса Date преобразовываются в число, хранящее значение момента времени в машинном формате (т. е. как количество миллисекунд, прошедших с 1 января !970 года). Например:

trace(Number(new Date())); // Выводит: 1072217134319
Таким образом, преобразование объекта класса Date в число аналогично использованию метода getTime().

Описанная особенность может быть использована для упрощения выражений. К примеру, если нужно вычислить время в миллисекундах, разделяющее два момента, то применять метод getTime() совсем необязательно:

// Следующий код работает, так как оператор "-" преобразует операнды в числа
var begin_time:Date=new Date();
for (var i=0; i<2000000; i++) {};
trace((new Date())-begin_time); // Выводит: 10164

У класса Date имеется недокументированный метод valueOf(), аналогичный по возвращаемому результату методу getTime() и операции приведения к числу. Рассмотрим пример:

var time:Date=new Date();
trace(Number(time)==time.valueOf() // Выводит: true

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Action Script на эту тему:
Класс Date
Компьютерное время
Определение времени, прошедшего с начала проигрывания фильма
Основные понятия теории измерения времени

Вернуться в раздел: Action Script / 14. Время и дата