Home > javascript, web, программирование > Обьект времени в Javascript

Обьект времени в Javascript

scriptМне понадобилось в одном проэкте работать с временем на стороне клиента (что как извесно подразумевает 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, а целое.

Приступим уже и к обьекту

Так что же я хочу от обьекта:

  1. Хранение данных, а так же передача времени как “23:45:00″;
  2. Добавление времени
  3. Вычитание времени
  4. В будущем, если возможно, то хотелось бы перегрузить базовые операции над обьектами, но пока не нашёл и не сделал.

Вот пока и всё. Начну пожалуй с создания обьекта с базовым набором функций: конструктор с кучей параметров, функция установки времени ну и получение значения обьекта. Код получился чуточку спецефический:

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:
После некоторого использования был найден баг (смотрите мой комментарий), так что обновите скрипт.

  1. July 9th, 2007 at 20:31 | #1

    Никто и не заметил баг ;)

    История.
    Началось всё с того, что класс, когда в секундах встречалась девятка, неправильно устанавливал время. Везде правильно, а вот если в секундах цифра 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() работала в восмеричной системе счисления!!! Чтобы всё работало, следует “насильно” указать систему.

    Скрипт поправил и всё заработало.

  2. Wide Specialist
    October 2nd, 2007 at 17:01 | #2

    Интересно сделано.

    А где можно побольше узнать про ООП на JavaScript?

    Пиши на почту, если что…

  3. October 2nd, 2007 at 17:10 | #3

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

    Если вам поможет, то есть подборочка линков по Javascript у меня на memori.ru.

  1. No trackbacks yet.