﻿// time.js
// Copyright © 2003-2004, Intellecta Systems AB.
// Encoded as UTF-8.


// ===================================================================
// Datum och tid.

// -----------------------------------------------------------------------
// Formaterar ett datum till formen YYYYMMDD. Ingen kontroll görs av att
// datumet existerar.
// ARG: date - datum på formerna YYYYMMDD, YYMMDD, YYYY-MM-DD, YY-MM-DD,
//  MM/DD/YY, MM/DD/YYYY. Om YY är <70 antas det avse 2000-tal, annars 
//  antas det avse 1900-tal.
// RET: datumet på formen YYYYMMDD om date har giltig form, annars null.
// -----------------------------------------------------------------------
function FormatDate(date)
{
	if( date==null || typeof(date)=="undefined" )
		return null;
	if( date.length!=6 && date.length!=8 && date.length!=10 )
		return null;

	// YYYYMMDD
	else if( date.length==8 && StrIsNumeric(date) ) 
	{
		return date;
	} 

	// YYMMDD
	else if( date.length==6 && StrIsNumeric(date) ) 
	{
		var year = date.substr(0,2);
		year = FormatYear(year);
		if( year==null )
			return null;
		
		return year + date.substr(2,4);
	}
	
	// YYYY-MM-DD
	else if( date.length==10 && date.charAt(4)=='-' && date.charAt(7)=='-' )
	{
		var part = date.substr(0,4);
		if( !StrIsNumeric(part) )
			return null;
	
		var back = part;
		
		part = date.substr(5,2);
		if( !StrIsNumeric(part) )
			return null;
		back += part;
			
		part = date.substr(8,2);
		if( !StrIsNumeric(part) )
			return null;
		back += part;

		return back;
	}

	// YY-MM-DD
	else if( date.length==8 && date.charAt(2)=='-' && date.charAt(5)=='-' )
	{
		var year = FormatYear(date.substr(0,2));
		if( year==null )
			return null;

		var back = year;

		var part = date.substr(3,2);
		if( !StrIsNumeric(part) )
			return null;
		back += part;
			
		part = date.substr(6,2);
		if( !StrIsNumeric(part) )
			return null;
		back += part;

		return back;
	}

	// MM/DD/YY
	else if( date.length==8 && date.charAt(2)=='/' && date.charAt(5)=='/' )
	{
		var year = FormatYear(date.substr(6,2));
		if( year==null )
			return null;
		
		var back = year;

		var part = date.substr(0,2);
		if( !StrIsNumeric(part) )
			return null;
		back += part;
			
		part = date.substr(3,2);
		if( !StrIsNumeric(part) )
			return null;
		back += part;

		return back;
	}

	// MM/DD/YYYY
	else if( date.length==10 && date.charAt(2)=='/' && date.charAt(5)=='/' )
	{
		var year = FormatYear(date.substr(6,4));
		if( year==null )
			return null;
		
		var back = year;

		var part = date.substr(0,2);
		if( !StrIsNumeric(part) )
			return null;
		back += part;
			
		part = date.substr(3,2);
		if( !StrIsNumeric(part) )
			return null;
		back += part;

		return back;
	}
	
	return null;
}	

// -----------------------------------------------------------------------
// Formaterar ett årtal till formen YYYY. 
// ARG: year - årtal på formen YYYY, YYY, YY eller Y. Om YY är <70 antas 
//  det avse 2000-tal, annars antas det avse 1900-tal.
// RET: årtalet på formen YYYY om giltigt årtal, annars null.
// -----------------------------------------------------------------------
function FormatYear(year)
{
	if( !StrIsNumeric(year) )
		return null;
	
	if( year.length==2 )
	{
		var y = parseInt(year, 10);
		if( isNaN(y) )
			return null;
			
		if( y<70 )
			return "20" + year;
		else
			return "19" + year;
	}
	else if( year.length<5 )
	{
		while( year.length<4 )
			year = "0"+year;
		return year;
	}
	else
		return null;
}

// -----------------------------------------------------------------------
// Jämför om ett datum är tidigare än, senare än eller lika med ett annat datum.
// ARG: datum1 - Datum på form enligt FormatDate.
// ARG: datum2 - Datum på form enligt FormatDate.
// ARG: message - Text som ska visas i alert-ruta om datumet är ogiltigt.
//  Om message="", visas ingen alert-ruta.
// RET: 0 om de är lika, -1 om datum1 är tidigare, 1 om datum1 är senare.
// -----------------------------------------------------------------------
function CompareDate(datum1, datum2, message)
{
	datum1 = FormatDate(datum1);
	datum2 = FormatDate(datum2);
	
	if( datum1==null || datum2==null )
	{
		if( message!=null && typeof(message)!="undefined" && message.length>0 ) 
			alert(message); 
		return null; 
	}

	var year1 = datum1.substr(0,4);
	var month1 = datum1.charAt(4) + datum1.charAt(5);
	var date1 = datum1.charAt(6) + datum1.charAt(7);

	var year2 = datum2.substr(0,4);
	var month2 = datum2.charAt(4) + datum2.charAt(5);
	var date2 = datum2.charAt(6) + datum2.charAt(7);

	if( year1==year2 && month1==month2 && date1==date2 )
		return 0;

	if( (year1<year2) || (year1==year2 && month1<month2) ||
		(year1==year2 && month1==month2 && date1<date2) )
		return -1;

	return 1;
}

// -----------------------------------------------------------------------
// Jämför om ett datum är tidigare än, senare än eller lika med dagens datum.
// ARG: datum - Datum på formen SSYYMMDD, YYMMDD, SSYY-MM-DD eller YY-MM-DD.
// ARG: message - Text som ska visas i alert-ruta om datumet är ogiltigt.
// Om message="", visas ingen alert-ruta.
// RET: 0 om de är lika, -1 om dagens datum är tidigare, 1 om dagens datum är senare 
// -----------------------------------------------------------------------
function CompareDateToday(datum, message)
{
	return CompareDate(GetCurrentDateAsString(),datum,message);
}

// -----------------------------------------------------------------------
// Jämför om en tidpunkt är tidigare än, senare än eller lika med en annan tid
// ARG: time1 - Tid på formen HH:MM
// ARG: time2 - Tid på formen HH:MM
// ARG: message - Text som ska visas i alert-ruta om tiden är ogiltig.
// Om message="", visas ingen alert-ruta.
// RET: 0 om de är lika, -1 om time1 är tidigare, 1 om time1 är senare.
//  Returvärdet är null om jämförelsen misslyckades.
// -----------------------------------------------------------------------
function CompareTime(time1, time2, message)
{
	var hour1 = time1.charAt(0) + time1.charAt(1);
	var minute1 = time1.charAt(3) + time1.charAt(4);

	var hour2 = time2.charAt(0) + time2.charAt(1);
	var minute2 = time2.charAt(3) + time2.charAt(4);

	if( isNaN(hour1) || isNaN(minute1) || isNaN(hour2) || isNaN(minute2)
		|| (time1.charAt(2)!=":") || (time2.charAt(2)!=":")
		|| (hour1<0) || (hour1>23) || (hour2<0) || (hour2>23) 
		|| (minute1<0) || (minute1>59) || (minute2<0) || (minute2>59) )
	{
		if( message!=null && typeof(message)!="undefined" && message.length>0 )
			alert(message); 
		return null; 
	}

	if( hour1==hour2 && minute1==minute2 )
		return 0;

	if( (hour1<hour2) || (hour1==hour2 && minute1<minute2) )
		return -1;

	return 1;
}

// -----------------------------------------------------------------------
// Jämför om en tidpunkt är tidigare än, senare än eller lika med aktuell tid
// ARG: time - Tid på formen hh:mm
// ARG: message - Text som ska visas i alert-ruta om tiden är ogiltigt.
//  Om message="", visas ingen alert-ruta.
// RET: 0 om de är lika, -1 om aktuell tid är tidigare, 1 om aktuell tid är senare.
//-----------------------------------------------------------------------
function CompareTimeNow(time, message)
{
	return CompareTime(GetCurrentTimeAsString(),time,message);
}

// -----------------------------------------------------------------------
// Adderar en eller flera dagar till ett datum.
// ARG: date - Datumet på form enligt FormatDate.
// ARG: days - Antal dagar som datumet ska ökas/minskas med. 
//  Använd negativt antal för att minska.
// RET: Det nya datumet på formen YYYYMMDD.
// -----------------------------------------------------------------------
function AddDays(date, days)
{
	date = FormatDate(date);
	
	var year = date.substr(0,4);
	var month = date.charAt(4) + date.charAt(5);
	var day = date.charAt(6) + date.charAt(7);

	day *= 1;
	month *= 1;
	year *= 1;

	while( days!=0 )
	{
		if( days>0 ) { days--; day++; }
		if( days<0 ) { days++; day--; }
		if( day<1 )
		{ 
			month--; if( month<1 ) { year--; month=12; }
			day = GetDaysPerMonth(year,month);
		}
		else if( day>GetDaysPerMonth(year,month) )
		{
			month++; if( month>12 ) { year++; month=1; }
			day = 1;
		}
	}
	return GetNumberDateAsString(year,month,day);
}

// -----------------------------------------------------------------------
// Adderar en eller flera dagar till dagens datum
// ARG: days - Antal dagar som dagens datum ska ökas med
// RET: Det nya datumet
// -----------------------------------------------------------------------
function AddDaysToday(days)
{
	return AddDays(GetCurrentDateAsString(), days);
}


// -----------------------------------------------------------------------
// Returnerar antalet dager för angiven månad.
// ARG: year - årtalet.
// ARG: month - månaden, 1-12.
// ARG: Tidssträngen
// -----------------------------------------------------------------------
function GetDaysPerMonth(year, month)
{
	if( month==2 )
	{
		// Check leap year.
		if( (year%04)==0 && (year%100)!=0 || (year%400)==0 )
			return 29;
		else
			return 28;
	}
	else if( month==4 || month==6 || month==9 || month==11 )
		return 30;
	else
		return 31;
}

// -----------------------------------------------------------------------
// Hämtar aktuell tid som en sträng på formen hh:mm
// RET: Tidssträngen
// -----------------------------------------------------------------------
function GetCurrentTimeAsString()
{
	var now = new Date();	
	var nHour = now.getHours();
	var nMinutes = now.getMinutes();
	var time = String(nHour) + ":" + String(nMinutes);
	return time;
}

// -----------------------------------------------------------------------
// Hämtar aktuellt datum som en sträng på formen YYYYMMDD.
// RET: Datumsträngen
// -----------------------------------------------------------------------
function GetCurrentDateAsString()
{
	var now = new Date();
	return GetNumberDateAsString(
		now.getFullYear(),now.getMonth()+1,now.getDate() );
}

// -----------------------------------------------------------------------
// Skapar datumsträng från datumvärden.
// ARG: year - ett nummer för ett årtal.
// ARG: month - nummer på månad, 1-12.
// ARG: day - nummer på dag, 1-31.
// RET: Datumsträngen
// -----------------------------------------------------------------------
function GetNumberDateAsString(year,month,day)
{
	var str = FormatYear(String(year)); 
	if( month<10 ) str += "0";
	str += String(month);
	if( day<10 ) str += "0";
	str += String(day);
	return str;
}

// -----------------------------------------------------------------------
// Kontrollerar om ett datum existerar.
// ARG: date - Datum på form enligt FormatDate.
// ARG: message - Text som ska visas i alert-ruta om datumet är ogiltigt.
//  Om message="", visas ingen alert-ruta.
// RET: TRUE om det är ett giltigt datum, annars FALSE
// -----------------------------------------------------------------------
function CheckDate(date, message)
{
	if( date==null )
		return false;
	date = FormatDate(date);
	if( date==null )
		return false;

	var year = date.substr(0,4);
	var month = date.charAt(4) + date.charAt(5);
	var day = date.charAt(6) + date.charAt(7);
	var ok = true;

	if( month<1 || month>12 || day<1 )
	{
		ok = false;
	}
	else if( day>GetDaysPerMonth(year, month) )
	{
		ok = false;
	}

	if( ok )
		return true;
	else
	{
		if( typeof(message)!="undefined" && message!=null && message.length>0 ) 
			alert(message); 
		return false;
	}
}

// -----------------------------------------------------------------------
// Check if a string contains only numeric characters, [0-9].
// ARG: str - the string to check.
// RET: true if numeric string.
// -----------------------------------------------------------------------
function StrIsNumeric(str)
{
	if( str==null || typeof(str)=="undefined" )
		return false;
	
	str = String(str);
	for( var i=0; i<str.length; i++ )
	{
		if( !CharIsNumeric(str.charAt(i)) )
			return false;
	}
	
	return true;
}

// -----------------------------------------------------------------------
// Check if a single character string contains a numeric character, [0-9].
// ARG: str - the single character string to check.
// RET: true if numeric character.
// -----------------------------------------------------------------------
function CharIsNumeric(ch)
{
	return ch=='0'||ch=='1'||ch=='2'||ch=='3'||ch=='4'
		||ch=='5'||ch=='6'||ch=='7'||ch=='8'||ch=='9';
}
