Re: glib time functions (fwd)



i've already send this to havoc and ali, now also for the devel-list

-- 
best regards

so long...
	Ray :)

"There are two major products that come out of Berkeley: 
LSD and UNIX. We don't believe this to be a coincidence." 
  - Jeremy S. Anderson 

*-------------------------------------------------------*
| Raimund Bauer	- Kawasaki Zephyr 1100			|
| LBR-Admin	- see http://mars.tuwien.ac.at/		|
*-------------------------------------------------------*

---------- Forwarded message ----------
Date: Thu, 30 Nov 2000 17:50:47 +0100 (CET)
From: Raimund Bauer <ray pluto tuwien ac at>
To: Ali Abdin <aliabdin aucegypt edu>
Cc: Havoc Pennington <hp redhat com>
Subject: Re: glib time functions

On Wed, 29 Nov 2000, Ali Abdin wrote:

> My Islamic Calendar representation is based on time_t values or "absolute"
> points in time - These "absolute" values are based on the number of days
> beginning from an arbitrary point - This arbitray point chosen was 1/1/1
> (Gregorian). This is based on this calendar source that JWZ pointed me to
> (which is very good (it is a 250k postscript file, so if you want it, I can
> email it to you to privately)

yes, please! i'd like to get that.

> Unfortunately this approach can have error's :) i.e. during 1/1/1 the Islamic
> calendar is in the "negative". The Islamic calendar will not appear until
> 07/19/622, or 492148 days in absolute terms (i.e. from 1/1/1).

what's the problem with negativ dates? the christian calendar also has
negativ dates -> B.C.

> > should automatically adjust all appointments to the local time. So
> > internal storage would be in UTC I guess.

that's for sure a good idea ;-)

> Regards,
> Ali

i've attached a proposal, how the date/time handling could look like in my
opinion. the definitions for GDateTime are just 2 proposals, i could also
come up with something new.
I guess the 2 remaining main questions are:
1.) resolution: if we are targetting calendar applications, even a
	second-resolutions seems to be too much, leave alone usecs
2.) do you want to have just a point in time, or do we already include
	durations for events?

i'm also not sure, if it really makes sense, to have seperate
_add_* and _subtract_* function (format taken from GDate functions). i
think, it would be more comfortable for the programmer, to have just an
add_* function with a signed parameter for the change.

waiting for comments

-- 
best regards

so long...
	Ray :)

"There are two major products that come out of Berkeley: 
LSD and UNIX. We don't believe this to be a coincidence." 
  - Jeremy S. Anderson 

*-------------------------------------------------------*
| Raimund Bauer	- Kawasaki Zephyr 1100			|
| LBR-Admin	- see http://mars.tuwien.ac.at/		|
*-------------------------------------------------------*
typedef struct _GDateTime GDateTime;

#ifdef variant_1
struct _GDateTime
{
  GDate d;
  GTimeVal t;
}
#else
struct _GDateTime
{
  struct tm _tm;
  guint  usecs;
}
#endif

/* question: do we really need usec resolution? */

/******************************************************************/

/* g_dt_new() returns an invalid date/time, you then have to _set() stuff 
 * to get a usable object. You can also allocate a GDate statically,
 * then call g_dt_clear() to initialize.
 */
GDateTime*   g_dt_new                     (void);
GDateTime*   g_dt_new_dmy                 (GDateDay     day, 
                                           GDateMonth   month, 
                                           GDateYear    year);
GDateTime*   g_dt_new_dmyt                (GDateDay     day,
					   GDateMonth   month,
					   GDateYear    year,
					   guint        hours,
					   guint        mins,
					   guint        secs);
GDateTime*   g_dt_new_time                (GTime        time);
GDateTime*   g_dt_new_julian              (gdouble      julian_day);
void         g_dt_free                    (GDateTime    *date);

/* check g_dt_valid() after doing an operation that might fail, like
 * _parse.  Almost all g_date operations are undefined on invalid
 * dates (the exceptions are the mutators, since you need those to
 * return to validity).  
 */
gboolean     g_dt_valid                 (GDateTime   *date);
gboolean     g_dt_valid_day             (GDateDay     day);
gboolean     g_dt_valid_month           (GDateMonth   month);
gboolean     g_dt_valid_year            (GDateYear    year);
gboolean     g_dt_valid_weekday         (GDateWeekday weekday);
gboolean     g_dt_valid_julian          (gdouble      julian_date);
gboolean     g_dt_valid_dmy             (GDateDay     day,
                                           GDateMonth   month,
                                           GDateYear    year);

GDateWeekday g_dt_weekday               (GDateTime   *date);
GDateMonth   g_dt_month                 (GDateTime   *date);
GDateYear    g_dt_year                  (GDateTime   *date);
GDateDay     g_dt_day                   (GDateTime   *date);
gdouble      g_dt_julian                (GDateTime   *date);
guint        g_dt_day_of_year           (GDateTime   *date);

/* First monday/sunday is the start of week 1; if we haven't reached
 * that day, return 0. These are not ISO weeks of the year; that
 * routine needs to be added.
 * these functions return the number of weeks, starting on the
 * corrsponding day
 */
guint        g_dt_monday_week_of_year   (GDateTime  *date);
guint        g_dt_sunday_week_of_year   (GDateTime  *date);

/* If you create a static date struct you need to clear it to get it
 * in a sane state before use. You can clear a whole array at
 * once with the ndates argument.
 */
void         g_dt_clear                 (GDateTime   *date, 
                                           guint        n_dates);

/* The parse routine is meant for dates typed in by a user, so it
 * permits many formats but tries to catch common typos. If your data
 * needs to be strictly validated, it is not an appropriate function.
 */

/* setting the whole time-point */
void         g_dt_set_parse             (GDateTime   *date,
                                           const gchar *str);
void         g_dt_set_time              (GDateTime   *date, 
                                           GTime        time);
void         g_dt_set_julian            (GDateTime   *date,
                                           gdouble      julian_date);
void         g_dt_set_dmy               (GDateTime   *date,
                                           GDateDay     day,
                                           GDateMonth   month,
                                           GDateYear    y);

/* setting single components */
void         g_dt_set_month             (GDateTime   *date, 
                                           GDateMonth   month);
void         g_dt_set_day               (GDateTime   *date, 
                                           GDateDay     day);
void         g_dt_set_year              (GDateTime   *date,
                                           GDateYear    year);
void         g_dt_set_daytime           (GDateTime   *dt,
					 guint        secs,
					 guint        usecs);

gboolean     g_dt_is_first_of_month     (GDateTime   *date);
gboolean     g_dt_is_last_of_month      (GDateTime   *date);


void         g_dt_add_hms               (GDateTime   *dt,
					 guint       hours,
					 guint       mins,
					 guint       secs);
void         g_dt_sub_hms               (GDateTime   *dt,
					 guint       hours,
					 guint       mins,
					 guint       secs);

void         g_dt_add_secs              (GDateTime   *dt,
					 guint       secs);
void         g_dt_sub_secs              (GDateTime   *dt,
					 guint       secs);
/* macros for _mins, _hours */
#define g_dt_add_mins(dt,m) g_dt_add_secs(dt, 60 * (m))
#define g_dt_sub_mins(dt,m) g_dt_sub_secs(dt, 60 * (m))
#define g_dt_add_hours(dt,h) g_dt_add_mins(dt, 24 * (h))
#define g_dt_sub_hours(dt,h) g_dt_sub_mins(dt, 24 * (h))

/* To go forward by some number of weeks just go forward weeks*7 days */
void         g_dt_add_days              (GDateTime   *date, 
                                           guint        n_days);
void         g_dt_subtract_days         (GDateTime   *date, 
                                           guint        n_days);

#define g_dt_add_weeks(date, n_weeks) \
  g_dt_add_days(date, 7 * (n_weeks))
#define g_dt_substract_weeks(date, n_weeks) \
  g_dt_substract_days(date, 7 * (n_weeks))

/* If you add/sub months while day > 28, the day might change */
void         g_dt_add_months              (GDateTime   *date,
                                           guint        n_months);
void         g_dt_subtract_months         (GDateTime   *date,
                                           guint        n_months);

/* If it's feb 29, changing years can move you to the 28th */
void         g_dt_add_years               (GDateTime   *date,
                                           guint        n_years);
void         g_dt_subtract_years          (GDateTime   *date,
                                           guint        n_years);
gboolean     g_dt_is_leap_year            (GDateYear    year);
guint8       g_dt_days_in_month           (GDateMonth   month, 
                                           GDateYear    year);
guint8       g_dt_monday_weeks_in_year    (GDateYear    year);
guint8       g_dt_sunday_weeks_in_year    (GDateYear    year);

/* qsort-friendly (with a cast...) */
gint         g_dt_compare                 (GDateTime   *lhs,
                                           GDateTime   *rhs);
void         g_dt_to_struct_tm            (GDateTime   *date,
                                           struct tm   *tm);

/* Just like strftime(). */
gsize        g_dt_strftime                (gchar       *s,
                                           gsize        slen,
                                           const gchar *format,
                                           GDateTime   *date);

/***********************************************************/

/* we could add a "duration" to GDateTime or make an own struct
 * including a duration.
 * This would also lead to some new functions:
 */

/* have the time-intervalls a common time-period? */
gboolean   g_dt_do_overlap           (const GDateTime *lhs,
				      const GDateTime *rhs);

/* are the 2 time-intervals completely distinct? */
/* alternativ: use compare, if overlapping return 0 */
gboolean   g_dt_are_distinct         (const GDateTime *lhs,
				      const GDateTime *rhs);

/* is timeintervall small_span in big_span included? */
gboolean   g_dt_is_included          (const GDateTime *big_span,
				      const GDateTime *small_span);

/* which timeintervall is larger? */
gint       g_dt_cmp_duration         (const GDateTime *lhs,
				      const GDateTime *rhs);

/* how many time is between 2 events? (result could also be: seconds) */
GDateTime* g_dt_between              (const GDateTime *ev1,
				      const GDateTime *ev2);

/* influence the duration of an event */
void       g_dt_prolong_event_<par-type> ();
void       g_dt_shorten_event_<par-type> ();

/* also some function from above could need const-pointers for their
 * parameters!
 */

/*******************************************************************/

/* for special date systems (islamic, chinese, ...), we could add
 * further functions, or a generic interface:
 */

void g_dt_set_special           (GDateTime *dt,
				 guint      dt_type, /* or a string */
				 ... /* further parameters */);

/* this assumes, that all systems have either year of 365/366 days or
 * count all days sequentially from a unique origin */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]