Обьект времени в Javascript
21 May 2007
Мне понадобилось в одном проэкте работать с временем на стороне клиента (что как извесно подразумевает javascript). А вот функций работы именно с временем нет. Я имею ввиду время без даты, тоесть “22:00:45″. В Javascript есть обьект Date() который работает со всем, но вот чистого времени нет, да и изголятся надо, чтобы методы Date применять к его узкому месту - времени. Сначала я попробывал реализовать суммирование времени с помошью Date. Мне не понравилось. Потому что не работало как Я хотел. Толи я не так хотел, но суммировать у меня не получалось. И я решил сам сделать обьект. Да и поучится ООП на javascript не мешало бы.
Скажу, что значение времени решил хранить как int. Это упростит арифметические операции и всякие манипуляции с данными.
Начнём…
Создание обьектов в Javascript
Начал я изучения ООП самого Javascript, так как никогда не писал, что-то большое и универсальное (ООП - это универсальное. Я так считаю) на Javascript. Так, всегда по мелочах. Оказывается, ничего сложного нет.
Для того чтобы создать обьект OBJ в javascript следует воспользоватся конструкцией:
function OBJ (){
var OBJ_value;
this.get = function (){
return OBJ_value;
}
this.set = function (value){
OBJ_value = value;
}
}
В этом примере создан обьект OBJ и он имеет 2 метода - get и set. Первый служит для получения данных свойства OBJ_value, ну а второй - для записы данных в свойство. Как работают прототипы - пока и не разбирался, попожже напишу.
Если уж почесному, то пользовался я заметкой одного блогера ( спсб, за статейку)
В этот обьект мы можем добавить сколько угодно свойств и методов (забыл спросить: что такое методы и свойства надеюсь никому рассказывать ненадо, все Страуструпа читали?
) Создавать и вызывать методы тоже просто:
tmp_obj = new OBJ();
tmp_obj.set('e');
alert(tmp_obj.get());
C теорией всё. Если что непонятно, то заметка, выдана на руки ранее, всё прояснит. Приступим уже с конкретному заданию - нашему обьекту времени.
Перед этим бы…
Ну сначала я хочу написать о очень нужной функции, которой я пользуюсь больше в php, но тут она тоже понадобилась. Функция нахождения целой части от деления a на b. Реализации её нет в языках программирования, но сложности написать её нет никакой. Но, опять же признаюсь, я её не писал. Когда-то что-то спросил у друга zipo, а он нагора мне её по аське прислал, вот и пользуюсь до сих пор. Всё просто:
Так в PHP:
function div($a, $b)
{
return (int)(($a - $a % $b) / $b);
}
А так в Javscript:
function div(a,b){
return parseInt((a - a % b) / b );
}
Она возвращает целое число от деления. Не остачи, не float, а целое.
Приступим уже и к обьекту
Так что же я хочу от обьекта:
- Хранение данных, а так же передача времени как “23:45:00″;
- Добавление времени
- Вычитание времени
- В будущем, если возможно, то хотелось бы перегрузить базовые операции над обьектами, но пока не нашёл и не сделал.
Вот пока и всё. Начну пожалуй с создания обьекта с базовым набором функций: конструктор с кучей параметров, функция установки времени ну и получение значения обьекта. Код получился чуточку спецефический:
function Time (value, spliter){
// существует 2 параметра. Поверте, их таки 2. Сначала подумал о одном
// (типа время), но ведь пишется для людей же. Первый - время в формате
// "00:00:00" если нет разделителя. Или с другим разделитеолем.
var time_value; // а вот тут и будем хранить наш int типа времени.
if(value != null ){
// тут мы как-то записываем данные в свойство
} else {
// понятно, что программер ничего нее указал. Вот и 0 ему в обьект.
time_value = 0;
}
// getting data
/* вот и отдача результата. Пока отдаю с сепаратором (фу какое слово) ,
а дальше подумаем
*/
this.get = function (){
hour = div(time_value, 3600);
// тут мы получаем с помощью div целое число часов
minut = div((time_value - hour*3600), 60);
// опять математика но на выходе минуты
sec = time_value - hour*3600 - minut*60;
// .. ну и секунды
// а тут всем подкручиваем спереди 0 если числа уж малы.
(hour < 10)? hour = '0' + hour:hour;
(minut < 10)? minut = '0' + minut:minut;
(sec < 10)? sec = '0' + sec:sec;
// возвращаем каку
return hour + ":" + minut + ":" + sec;
}
}
Всё что внутри function Time(value, spliter){} есть конструктор. Так как у нас будет функция добавление/изменения времени, то её мы и можем использовать в конструкторе. Но что замечательно (да и не могу понять почему), её нужно описать до вызова в конструкторе даже если обьект вызывается через 1406 строк кода. Тоесть, если в конструкторе вы где-то используете метод обьекта, то этот метод должен быть обьявлен ДО вызова. Кумедiя.
Вот как я собираюсь вводить данные времени:
// set time. on perviy, kozz using in constructur after this
this.set = function (value, spliter) {
(spliter != null)? spliter = spliter: spliter = ":";
tmp = value.split(spliter);
if(tmp[0] != null && tmp[1] != null && tmp[2] !=null){
time_value = parseInt(tmp[2],10 ) + parseInt(tmp[1],10) * 60 + parseInt(tmp[0],10)*3600;
} else {
time_value = 0 ;
}
}
Но многое с этих строк будет использоваться по 14 раз за вызов, и почти всё вынес в отдельную функцию convert() и переписал set():
this.convert = function (value,split){
(spliter != null)? spliter = spliter: spliter = ":";
tmp = value.split(spliter);
if(tmp[0] != null && tmp[1] != null && tmp[2] !=null){
return parseInt(tmp[2] ,10) + parseInt(tmp[1],10) * 60 + parseInt(tmp[0],10)*3600;
} else {
return 0 ;
}
}
// set time. on perviy, kozz using in constructur after this
this.set = function (value, spliter) {
time_value = this.convert(value, spliter);
}
Вот и всё. Теперь простые функции по добавлению времени и вычитанию:
// summa
this.add = function(value, spliter){
time_value = time_value + this.convert(value, spliter);
}
// minux time
this.minus = function(value,spliter){
time_value = time_value - this.convert(value, spliter);
}
Финал
Вот и весь пока обьект. Весь текст скрипта с вызовом:
function Time (value, spliter){
var time_value;
// convert time to int
this.convert = function (value,split){
(spliter != null)? spliter = spliter: spliter = ":";
tmp = value.split(spliter);
if(tmp[0] != null && tmp[1] != null && tmp[2] !=null){
return parseInt(tmp[2] ,10) + parseInt(tmp[1],10) * 60 + parseInt(tmp[0],10)*3600;
} else {
return 0 ;
}
}
// set time. on perviy, kozz using in constructur after this
this.set = function (value, spliter) {
time_value = this.convert(value, spliter);
}
if(value != null ){
this.set(value,spliter);
} else {
time_value = 0;
}
// getting data
this.get = function (){
hour = div(time_value, 3600);
minut = div((time_value - hour*3600), 60);
sec = time_value - hour*3600 - minut*60;
(hour < 10)? hour = '0' + hour:hour;
(minut < 10)? minut = '0' + minut:minut;
(sec < 10)? sec = '0' + sec:sec;
return hour + ":" + minut + ":" + sec;
}
// summa
this.add = function(value, spliter){
time_value = time_value + this.convert(value, spliter);
}
// minux time
this.minus = function(value,spliter){
time_value = time_value - this.convert(value, spliter);
}
}
test = new Time('02:24:02');
test.set("00:00:01");
test.add('00:00:04');
//alert(test.get());
Замечания и камменты давайте! Буду рад.
UPDATE:
После некоторого использования был найден баг (смотрите мой комментарий), так что обновите скрипт.



3 Responses to “Обьект времени в Javascript”
July 9th, 2007 at 8:31 pm
Никто и не заметил баг
История.
Началось всё с того, что класс, когда в секундах встречалась девятка, неправильно устанавливал время. Везде правильно, а вот если в секундах цифра 9, то секунды превращались в 0. Я начал изучать и пришёл к выводу, что неправильно конвертирует время функция convert. А покопавшись в мане на функцию parseInt() вот что нашёл:
If the radix parameter is omitted, JavaScript assumes the following:
* If the string begins with “0x”, the radix is 16 (hexadecimal)
* If the string begins with “0″, the radix is 8 (octal). This feature is deprecated
* If the string begins with any other value, the radix is 10 (decimal)
Вот в чём дело! фунция parseInt() работала в восмеричной системе счисления!!! Чтобы всё работало, следует “насильно” указать систему.
Скрипт поправил и всё заработало.
October 2nd, 2007 at 5:01 pm
Интересно сделано.
А где можно побольше узнать про ООП на JavaScript?
Пиши на почту, если что…
October 2nd, 2007 at 5:10 pm
Ой, не знаю. Мне статейка (в тексте есть линк) та понравилась, очень доходчиво написано, но, как я вижу, вы там уже побывали.
Если вам поможет, то есть подборочка линков по Javascript у меня на memori.ru.