Ejemplo n.º 1
0
Datum
ora_timestamp_round(PG_FUNCTION_ARGS)
{
	Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
	Timestamp result;
	text *fmt = PG_GETARG_TEXT_PP(1);
	fsec_t fsec;
	struct pg_tm tt, *tm = &tt;
	bool	redotz = false;

	if (TIMESTAMP_NOT_FINITE(timestamp))
		PG_RETURN_TIMESTAMPTZ(timestamp);

	if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
		ereport(ERROR,
					(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
					 errmsg("timestamp out of range")));

	tm_round(tm, fmt, &redotz);

	if (tm2timestamp(tm, fsec, NULL, &result) != 0)
		ereport(ERROR,
				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
				 errmsg("timestamp out of range")));

	PG_RETURN_TIMESTAMP(result);
}
Ejemplo n.º 2
0
Datum
ora_timestamptz_round(PG_FUNCTION_ARGS)
{
	TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(0);
	TimestampTz result;
	text *fmt = PG_GETARG_TEXT_PP(1);
	int tz;
	fsec_t fsec;
	struct pg_tm tt, *tm = &tt;
	const char *tzn;
	bool redotz = false;

	if (TIMESTAMP_NOT_FINITE(timestamp))
		PG_RETURN_TIMESTAMPTZ(timestamp);

	if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn, NULL) != 0)
		ereport(ERROR,
					(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
					 errmsg("timestamp out of range")));

	tm_round(tm, fmt, &redotz);

	if (redotz)
		tz = DetermineTimeZoneOffset(tm, get_session_timezone(fcinfo));

	if (tm2timestamp(tm, fsec, &tz, &result) != 0)
		ereport(ERROR,
				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
				 errmsg("timestamp out of range")));

	PG_RETURN_TIMESTAMPTZ(result);
}
Ejemplo n.º 3
0
void
PGTYPEStimestamp_current(timestamp * ts)
{
	struct tm	tm;

	GetCurrentDateTime(&tm);
	tm2timestamp(&tm, 0, NULL, ts);
	return;
}
Ejemplo n.º 4
0
static timestamp
SetEpochTimestamp(void)
{
	timestamp	dt;
	struct tm	tt,
			   *tm = &tt;

	GetEpochTime(tm);
	tm2timestamp(tm, 0, NULL, &dt);
	return dt;
}	/* SetEpochTimestamp() */
Ejemplo n.º 5
0
int
PGTYPEStimestamp_add_interval(timestamp * tin, interval * span, timestamp * tout)
{


	if (TIMESTAMP_NOT_FINITE(*tin))
		*tout = *tin;


	else
	{
		if (span->month != 0)
		{
			struct tm	tt,
					   *tm = &tt;
			fsec_t		fsec;


			if (timestamp2tm(*tin, NULL, tm, &fsec, NULL) != 0)
				return -1;
			tm->tm_mon += span->month;
			if (tm->tm_mon > MONTHS_PER_YEAR)
			{
				tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
				tm->tm_mon = (tm->tm_mon - 1) % MONTHS_PER_YEAR + 1;
			}
			else if (tm->tm_mon < 1)
			{
				tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
				tm->tm_mon = tm->tm_mon % MONTHS_PER_YEAR + MONTHS_PER_YEAR;
			}


			/* adjust for end of month boundary problems... */
			if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
				tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);


			if (tm2timestamp(tm, fsec, NULL, tin) != 0)
				return -1;
		}


		*tin += span->time;
		*tout = *tin;
	}
	return 0;

}
Ejemplo n.º 6
0
/**
 * Convert ASN1_TIME object to PostgreSQL timestamp.
 */
int asn1Time_to_timestamp(ASN1_TIME *asn1, Timestamp *dt) {
    BIO *bio;
    char buf[DATE_LEN];
    struct tm tm;
    struct pg_tm pgtm;
    int r;

    // extract 'not before' date
    bio = BIO_new(BIO_s_mem());
    if ((r = ASN1_TIME_print(bio, asn1)) <= 0) {
        BIO_free(bio);
        ereport(ERROR,
                (errcode(ERRCODE_DATA_CORRUPTED), errmsg("unable to retrieve timestamp")));
        return 1;
    }

    // convert 'not before' date
    if ((r = BIO_gets(bio, buf, DATE_LEN)) <= 0) {
        BIO_free(bio);
        ereport(ERROR,
                (errcode(ERRCODE_DATA_CORRUPTED), errmsg("unable to create ISO-8601 timestamp")));
        return 1;
    }

    BIO_free(bio);

    memset(&tm, 0, sizeof(struct tm));
    strptime(buf, "%b %d %T %Y %z", &tm);
    
    pgtm.tm_sec = tm.tm_sec;
    pgtm.tm_min = tm.tm_min;
    pgtm.tm_hour = tm.tm_hour;
    pgtm.tm_mday= tm.tm_mday;
    pgtm.tm_mon= tm.tm_mon + 1;
    pgtm.tm_year = tm.tm_year + 1900;
    pgtm.tm_wday= tm.tm_wday;
    pgtm.tm_yday = tm.tm_yday;
    pgtm.tm_isdst = tm.tm_isdst;
    pgtm.tm_gmtoff = 0;
    pgtm.tm_zone = "UTC";

    tm2timestamp(&pgtm, 0, NULL, dt);
    
    return 0;
}
Ejemplo n.º 7
0
static timestamp
SetEpochTimestamp(void)
{
#ifdef HAVE_INT64_TIMESTAMP
	int64		noresult = 0;
#else
	double		noresult = 0.0;
#endif
	timestamp	dt;
	struct tm	tt,
			   *tm = &tt;

	if (GetEpochTime(tm) < 0)
		return noresult;

	tm2timestamp(tm, 0, NULL, &dt);
	return dt;
}	/* SetEpochTimestamp() */
Ejemplo n.º 8
0
/* abstime_timestamptz()
 * Convert abstime to timestamp with time zone.
 */
Datum
abstime_timestamptz(PG_FUNCTION_ARGS)
{
	AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0);
	TimestampTz result;
	struct pg_tm tt,
			   *tm = &tt;
	int			tz;
	char		zone[MAXDATELEN + 1],
			   *tzn = zone;

	switch (abstime)
	{
		case INVALID_ABSTIME:
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("cannot convert abstime \"invalid\" to timestamp"),
						   errOmitLocation(true)));
			TIMESTAMP_NOBEGIN(result);
			break;

		case NOSTART_ABSTIME:
			TIMESTAMP_NOBEGIN(result);
			break;

		case NOEND_ABSTIME:
			TIMESTAMP_NOEND(result);
			break;

		default:
			abstime2tm(abstime, &tz, tm, &tzn);
			if (tm2timestamp(tm, 0, &tz, &result) != 0)
				ereport(ERROR,
						(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
						 errmsg("timestamp out of range"),
								   errOmitLocation(true)));
			break;
	};

	PG_RETURN_TIMESTAMP(result);
}
Ejemplo n.º 9
0
timestamp
PGTYPEStimestamp_from_asc(char *str, char **endptr)
{
	timestamp	result;

#ifdef HAVE_INT64_TIMESTAMP
	int64		noresult = 0;
#else
	double		noresult = 0.0;
#endif
	fsec_t		fsec;
	struct tm	tt,
			   *tm = &tt;
	int			dtype;
	int			nf;
	char	   *field[MAXDATEFIELDS];
	int			ftype[MAXDATEFIELDS];
	char		lowstr[MAXDATELEN + MAXDATEFIELDS];
	char	   *realptr;
	char	  **ptr = (endptr != NULL) ? endptr : &realptr;

	if (strlen(str) >= sizeof(lowstr))
	{
		errno = PGTYPES_TS_BAD_TIMESTAMP;
		return (noresult);
	}

	if (ParseDateTime(str, lowstr, field, ftype, &nf, ptr) != 0 ||
		DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, 0) != 0)
	{
		errno = PGTYPES_TS_BAD_TIMESTAMP;
		return (noresult);
	}

	switch (dtype)
	{
		case DTK_DATE:
			if (tm2timestamp(tm, fsec, NULL, &result) != 0)
			{
				errno = PGTYPES_TS_BAD_TIMESTAMP;
				return (noresult);
			}
			break;

		case DTK_EPOCH:
			result = SetEpochTimestamp();
			break;

		case DTK_LATE:
			TIMESTAMP_NOEND(result);
			break;

		case DTK_EARLY:
			TIMESTAMP_NOBEGIN(result);
			break;

		case DTK_INVALID:
			errno = PGTYPES_TS_BAD_TIMESTAMP;
			return (noresult);

		default:
			errno = PGTYPES_TS_BAD_TIMESTAMP;
			return (noresult);
	}

	/* AdjustTimestampForTypmod(&result, typmod); */

	/*
	 * Since it's difficult to test for noresult, make sure errno is 0 if no
	 * error occured.
	 */
	errno = 0;
	return result;
}
Ejemplo n.º 10
0
/* timestamptz_pl_interval()
 * Add a interval to a timestamp with time zone data type.
 * Note that interval has provisions for qualitative year/month
 *	units, so try to do the right thing with them.
 * To add a month, increment the month, and use the same day of month.
 * Then, if the next month has fewer days, set the day of month
 *	to the last day of month.
 * Lastly, add in the "quantitative time".
 */
TimestampTz
timestamptz_pl_interval(TimestampTz timestamp, Interval *span)
{
	TimestampTz result;
	int			tz;

	if (TIMESTAMP_NOT_FINITE(timestamp))
		result = timestamp;
	else
	{
		if (span->month != 0)
		{
			struct tm tt,
					   *tm = &tt;
			fsec_t		fsec;

			if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
				warnx("timestamp out of range");

			tm->tm_mon += span->month;
			if (tm->tm_mon > MONTHS_PER_YEAR)
			{
				tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
				tm->tm_mon = ((tm->tm_mon - 1) % MONTHS_PER_YEAR) + 1;
			}
			else if (tm->tm_mon < 1)
			{
				tm->tm_year += tm->tm_mon / MONTHS_PER_YEAR - 1;
				tm->tm_mon = tm->tm_mon % MONTHS_PER_YEAR + MONTHS_PER_YEAR;
			}

			/* adjust for end of month boundary problems... */
			if (tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1])
				tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]);

			tz = DetermineTimeZoneOffset(tm, session_timezone);

			if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
				warnx("timestamp out of range");
		}

		if (span->day != 0)
		{
			struct tm tt,
					   *tm = &tt;
			fsec_t		fsec;
			int			julian;

			if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0)
				warnx("timestamp out of range");

			/* Add days by converting to and from julian */
			julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + span->day;
			j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);

			tz = DetermineTimeZoneOffset(tm, session_timezone);

			if (tm2timestamp(tm, fsec, &tz, &timestamp) != 0)
				warnx("timestamp out of range");
		}

		timestamp += span->time;
		result = timestamp;
	}

	return result;
}