Esempio n. 1
0
Datum
plvdate_isbizday (PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	int y, m, d;
	holiday_desc hd;

	if (0 != ((1 << j2day(day+POSTGRES_EPOCH_JDATE)) & nonbizdays))
		return false;

	if (NULL != bsearch(&day, exceptions, exceptions_c,
						sizeof(DateADT), dateadt_comp))
		return false;

	j2date(day + POSTGRES_EPOCH_JDATE, &y, &m, &d);
	hd.month = m; hd.day = d;

	if (use_easter && (m == 3 || m == 4))
	{
		easter_sunday(y, &d, &m);
		if (m == hd.month && (d == hd.day || d+1 == hd.day))
			return false;
	}

	PG_RETURN_BOOL (NULL == bsearch(&hd, holidays, holidays_c,
									sizeof(holiday_desc), holiday_desc_comp));
}
Esempio n. 2
0
static int
ora_diff_bizdays(DateADT day1, DateADT day2)
{
	int d, days;
	int y, m, auxd;
	holiday_desc hd;

	int cycle_c = 0;
	bool start_is_bizday = false;

	DateADT aux_day;
	if (day1 > day2)
	{
		aux_day = day1;
		day1 = day2; day2 = aux_day;
	}


	d = j2day(day1+POSTGRES_EPOCH_JDATE);
	days = 0;

	while (day1 <= day2)
	{
		++ cycle_c;
		d = (d+1) % 7;
		d = (d < 0) ? 6:d;
		day1 += 1;
		if ((1 << d) & nonbizdays)
			continue;

		if (NULL != bsearch(&day1, exceptions, exceptions_c,
							sizeof(DateADT), dateadt_comp))
			continue;

		j2date(day1 + POSTGRES_EPOCH_JDATE, &y, &m, &auxd);
		hd.day = (char) auxd;
		hd.month = (char) m;

		if (use_easter && (m == 3 || m == 4))
		{
			easter_sunday(y, &auxd, &m);
			if (m == hd.month && (auxd == hd.day || d+1 == hd.day))
				continue;
		}
		if (NULL != bsearch(&hd, holidays, holidays_c,
							sizeof(holiday_desc), holiday_desc_comp))
			continue;

		days += 1;
		if (cycle_c == 1)
			start_is_bizday = true;
	}
	if (include_start && start_is_bizday && days >= 1)
		days -= 1;

	return days;
}
Esempio n. 3
0
Datum
next_day(PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	text *day_txt = PG_GETARG_TEXT_PP(1);
	const char *str = VARDATA_ANY(day_txt);
	int	len = VARSIZE_ANY_EXHDR(day_txt);
	int off;
	int d = -1;

#ifdef ENABLE_INTERNATIONALIZED_WEEKDAY
	/* Check mru_weekdays first for performance. */
	if (mru_weekdays)
	{
		if ((d = weekday_search(mru_weekdays, str, len)) >= 0)
			goto found;
		else
			mru_weekdays = NULL;
	}
#endif

	/*
	 * Oracle uses only 3 heading characters of the input.
	 * Ignore all trailing characters.
	 */
	if (len >= 3 && (d = ora_seq_prefix_search(str, ora_days, 3)) >= 0)
		goto found;

#ifdef ENABLE_INTERNATIONALIZED_WEEKDAY
	do
	{
		int		i;
		int		encoding = GetDatabaseEncoding();

		for (i = 0; i < lengthof(WEEKDAYS); i++)
		{
			if (encoding == WEEKDAYS[i].encoding)
			{
				if ((d = weekday_search(&WEEKDAYS[i], str, len)) >= 0)
				{
					mru_weekdays = &WEEKDAYS[i];
					goto found;
				}
			}
		}
	} while(0);
#endif

	CHECK_SEQ_SEARCH(-1, "DAY/Day/day");

found:
	off = d - j2day(day+POSTGRES_EPOCH_JDATE);

	PG_RETURN_DATEADT((off <= 0) ? day+off+7 : day + off);
}
Esempio n. 4
0
/* next_day(date, integer) is not documented in Oracle manual, but ... */
Datum
next_day_by_index(PG_FUNCTION_ARGS)
{
	DateADT day = PG_GETARG_DATEADT(0);
	int		idx = PG_GETARG_INT32(1);
	int		off;

	/*
	 * off is 1..7 (Sun..Sat).
	 *
	 * TODO: It should be affected by NLS_TERRITORY. For example,
	 * 1..7 should be interpreted as Mon..Sun in GERMAN.
	 */
	CHECK_SEQ_SEARCH((idx < 1 || 7 < idx) ? -1 : 0, "DAY/Day/day");

	/* j2day returns 0..6 as Sun..Sat */
	off = (idx - 1) - j2day(day+POSTGRES_EPOCH_JDATE);

	PG_RETURN_DATEADT((off <= 0) ? day+off+7 : day + off);
}
Esempio n. 5
0
static DateADT
ora_add_bizdays(DateADT day, int days)
{
	int d, dx;
	int y, m, auxd;
	holiday_desc hd;

	d = j2day(day+POSTGRES_EPOCH_JDATE);
	dx = days > 0? 1 : -1;

	while (days != 0)
	{
		d = (d+dx) % 7;
		d = (d < 0) ? 6:d;
		day += dx;
		if ((1 << d) & nonbizdays)
			continue;

		if (NULL != bsearch(&day, exceptions, exceptions_c,
							sizeof(DateADT), dateadt_comp))
			continue;

		j2date(day + POSTGRES_EPOCH_JDATE, &y, &m, &auxd);
		hd.day = (char) auxd;
		hd.month = (char) m;

		if (use_easter && (m == 3 || m == 4))
		{
			easter_sunday(y, &auxd, &m);
			if (m == hd.month && (auxd == hd.day || d+1 == hd.day))
				continue;
		}
		if (NULL != bsearch(&hd, holidays, holidays_c,
							sizeof(holiday_desc), holiday_desc_comp))
			continue;

		days -= dx;
	}

	return day;
}
Esempio n. 6
0
static int
ora_diff_bizdays(DateADT day1, DateADT day2)
{
	int d, days;
	int y, m, auxd;
	holiday_desc hd;

	int loops = 0;
	bool start_is_bizday = false;

	DateADT aux_day;
	if (day1 > day2)
	{
		aux_day = day1;
		day1 = day2; day2 = aux_day;
	}

	/* d is incremented on start of cycle, so now I have to decrease one */
	d = j2day(day1+POSTGRES_EPOCH_JDATE-1);
	days = 0;

	while (day1 <= day2)
	{
		loops++;
		day1 += 1;
		d = (d+1) % 7;

		if ((1 << d) & nonbizdays)
			continue;

		if (NULL != bsearch(&day1, exceptions, exceptions_c,
							sizeof(DateADT), dateadt_comp))
			continue;

		j2date(day1 + POSTGRES_EPOCH_JDATE, &y, &m, &auxd);
		hd.day = (char) auxd;
		hd.month = (char) m;

		if (easter_holidays(day1, y, m))
			continue;

		if (NULL != bsearch(&hd, holidays, holidays_c,
							sizeof(holiday_desc), holiday_desc_comp))
			continue;

		/* now the day have to be bizday, remember if first day was bizday */
		if (loops == 1)
			start_is_bizday = true;

		days += 1;
	}

	/*
	 * decrease result when first day was bizday, but we don't want
	 * calculate first day.
	 */
	if ( start_is_bizday && !include_start && days > 0)
		days -= 1;

	return days;
}