mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			223 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			223 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * datetime_functions.c --
 | |
|  *
 | |
|  * This file defines new functions for the time and date data types.
 | |
|  *
 | |
|  * Copyright (c) 1996, Massimo Dal Zotto <dz@cs.unitn.it>
 | |
|  */
 | |
| 
 | |
| #include <stdio.h>				/* for sprintf() */
 | |
| #include <string.h>
 | |
| #include <limits.h>
 | |
| #ifdef HAVE_FLOAT_H
 | |
| #include <float.h>
 | |
| #endif
 | |
| 
 | |
| #include "postgres.h"
 | |
| #include "miscadmin.h"
 | |
| #include "utils/builtins.h"
 | |
| #include "utils/nabstime.h"
 | |
| #include "utils/datetime.h"
 | |
| #include "access/xact.h"
 | |
| 
 | |
| #include "datetime_functions.h"
 | |
| 
 | |
| /* Constant to replace calls to date2j(2000,1,1) */
 | |
| #define JDATE_2000	2451545
 | |
| 
 | |
| /*
 | |
|  * A modified version of time_in which allows the value 24:00:00 for
 | |
|  * time and converts it to TimeADT data type forcing seconds to 0.
 | |
|  * This can be Useful if you need to handle TimeADT values limited
 | |
|  * to hh:mm like in timetables.
 | |
|  */
 | |
| 
 | |
| TimeADT    *
 | |
| hhmm_in(char *str)
 | |
| {
 | |
| 	TimeADT    *time;
 | |
| 
 | |
| 	double		fsec;
 | |
| 	struct tm	tt,
 | |
| 			   *tm = &tt;
 | |
| 
 | |
| 	int			nf;
 | |
| 	char		lowstr[MAXDATELEN + 1];
 | |
| 	char	   *field[MAXDATEFIELDS];
 | |
| 	int			dtype;
 | |
| 	int			ftype[MAXDATEFIELDS];
 | |
| 
 | |
| 	if (!PointerIsValid(str))
 | |
| 		elog(ERROR, "Bad (null) time external representation", NULL);
 | |
| 
 | |
| 	if ((ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf) != 0)
 | |
| 		|| (DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec) != 0))
 | |
| 		elog(ERROR, "Bad time external representation '%s'", str);
 | |
| 
 | |
| 	if (tm->tm_hour < 0 || tm->tm_hour > 24 ||
 | |
| 		(tm->tm_hour == 24 && (tm->tm_min != 0 || tm->tm_sec != 0 || fsec != 0)))
 | |
| 	{
 | |
| 		elog(ERROR,
 | |
| 			 "time_in: hour must be limited to values 0 through 24:00 "
 | |
| 			 "in \"%s\"",
 | |
| 			 str);
 | |
| 	}
 | |
| 	if ((tm->tm_min < 0) || (tm->tm_min > 59))
 | |
| 		elog(ERROR, "Minute must be limited to values 0 through 59 in '%s'", str);
 | |
| 	if ((tm->tm_sec < 0) || ((tm->tm_sec + fsec) >= 60))
 | |
| 		elog(ERROR, "Second must be limited to values 0 through < 60 in '%s'",
 | |
| 			 str);
 | |
| 
 | |
| 	time = palloc(sizeof(TimeADT));
 | |
| 
 | |
| 	*time = ((((tm->tm_hour * 60) + tm->tm_min) * 60));
 | |
| 
 | |
| 	return (time);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * A modified version of time_out which converts from TimeADT data type
 | |
|  * omitting the seconds field when it is 0.
 | |
|  * Useful if you need to handle TimeADT values limited to hh:mm.
 | |
|  */
 | |
| 
 | |
| char *
 | |
| hhmm_out(TimeADT *time)
 | |
| {
 | |
| 	char	   *result;
 | |
| 	struct tm	tt,
 | |
| 			   *tm = &tt;
 | |
| 	char		buf[MAXDATELEN + 1];
 | |
| 
 | |
| 	if (!PointerIsValid(time))
 | |
| 		return NULL;
 | |
| 
 | |
| 	tm->tm_hour = (*time / (60 * 60));
 | |
| 	tm->tm_min = (((int) (*time / 60)) % 60);
 | |
| 	tm->tm_sec = (((int) *time) % 60);
 | |
| 
 | |
| 	if (tm->tm_sec == 0)
 | |
| 		sprintf(buf, "%02d:%02d", tm->tm_hour, tm->tm_min);
 | |
| 	else
 | |
| 		sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
 | |
| 
 | |
| 	result = palloc(strlen(buf) + 1);
 | |
| 
 | |
| 	strcpy(result, buf);
 | |
| 
 | |
| 	return (result);
 | |
| }
 | |
| 
 | |
| TimeADT    *
 | |
| hhmm(TimeADT *time)
 | |
| {
 | |
| 	TimeADT    *result = palloc(sizeof(TimeADT));
 | |
| 
 | |
| 	*result = (((int) *time) / 60 * 60);
 | |
| 
 | |
| 	return (result);
 | |
| }
 | |
| 
 | |
| TimeADT    *
 | |
| time_difference(TimeADT *time1, TimeADT *time2)
 | |
| {
 | |
| 	TimeADT    *time = palloc(sizeof(TimeADT));
 | |
| 
 | |
| 	*time = (*time1 - *time2);
 | |
| 	return (time);
 | |
| }
 | |
| 
 | |
| int4
 | |
| time_hours(TimeADT *time)
 | |
| {
 | |
| 	return (((int) *time) / 3600);
 | |
| }
 | |
| 
 | |
| int4
 | |
| time_minutes(TimeADT *time)
 | |
| {
 | |
| 	return ((((int) *time) / 60) % 60);
 | |
| }
 | |
| 
 | |
| int4
 | |
| time_seconds(TimeADT *time)
 | |
| {
 | |
| 	return (((int) *time) % 60);
 | |
| }
 | |
| 
 | |
| int4
 | |
| as_minutes(TimeADT *time)
 | |
| {
 | |
| 	return (((int) *time) / 60);
 | |
| }
 | |
| 
 | |
| int4
 | |
| as_seconds(TimeADT *time)
 | |
| {
 | |
| 	return ((int) *time);
 | |
| }
 | |
| 
 | |
| int4
 | |
| date_day(DateADT val)
 | |
| {
 | |
| 	int			year,
 | |
| 				month,
 | |
| 				day;
 | |
| 
 | |
| 	j2date(val + JDATE_2000, &year, &month, &day);
 | |
| 
 | |
| 	return (day);
 | |
| }
 | |
| 
 | |
| int4
 | |
| date_month(DateADT val)
 | |
| {
 | |
| 	int			year,
 | |
| 				month,
 | |
| 				day;
 | |
| 
 | |
| 	j2date(val + JDATE_2000, &year, &month, &day);
 | |
| 
 | |
| 	return (month);
 | |
| }
 | |
| 
 | |
| int4
 | |
| date_year(DateADT val)
 | |
| {
 | |
| 	int			year,
 | |
| 				month,
 | |
| 				day;
 | |
| 
 | |
| 	j2date(val + JDATE_2000, &year, &month, &day);
 | |
| 
 | |
| 	return (year);
 | |
| }
 | |
| 
 | |
| TimeADT    *
 | |
| currenttime()
 | |
| {
 | |
| 	TimeADT    *result = palloc(sizeof(TimeADT));
 | |
| 	struct tm  *tm;
 | |
| 	time_t		current_time;
 | |
| 
 | |
| 	current_time = time(NULL);
 | |
| 	tm = localtime(¤t_time);
 | |
| 	*result = ((((tm->tm_hour * 60) + tm->tm_min) * 60) + tm->tm_sec);
 | |
| 
 | |
| 	return (result);
 | |
| }
 | |
| 
 | |
| DateADT
 | |
| currentdate()
 | |
| {
 | |
| 	DateADT		date;
 | |
| 	struct tm	tt,
 | |
| 			   *tm = &tt;
 | |
| 
 | |
| 	GetCurrentTime(tm);
 | |
| 	date = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - JDATE_2000);
 | |
| 	return (date);
 | |
| }
 | |
| 
 | |
| /* end of file */
 |