new files to contain functions to parse and format dates and times for
2001-03-04 Damon Chaplin <damon@ximian.com> * e-time-utils.[hc]: new files to contain functions to parse and format dates and times for various calendar widgets. svn path=/trunk/; revision=8546
This commit is contained in:
committed by
Damon Chaplin
parent
601186a4ed
commit
0a60162f0b
@ -1,3 +1,8 @@
|
||||
2001-03-04 Damon Chaplin <damon@ximian.com>
|
||||
|
||||
* e-time-utils.[hc]: new files to contain functions to parse and
|
||||
format dates and times for various calendar widgets.
|
||||
|
||||
2001-03-01 Dan Winship <danw@ximian.com>
|
||||
|
||||
* e-path.c (e_path_to_physical): New function to turn foo/bar into
|
||||
|
||||
@ -39,6 +39,8 @@ libeutil_la_SOURCES = \
|
||||
e-path.h \
|
||||
e-sexp.c \
|
||||
e-sexp.h \
|
||||
e-time-utils.c \
|
||||
e-time-utils.h \
|
||||
e-dbhash.c \
|
||||
e-dbhash.h \
|
||||
md5-utils.c \
|
||||
|
||||
292
e-util/e-time-utils.c
Normal file
292
e-util/e-time-utils.c
Normal file
@ -0,0 +1,292 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* Time utility functions
|
||||
*
|
||||
* Author:
|
||||
* Damon Chaplin (damon@ximian.com)
|
||||
*
|
||||
* (C) 2001 Ximian, Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* We need this for strptime. */
|
||||
#define _XOPEN_SOURCE 500
|
||||
#define __USE_XOPEN
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#undef _XOPEN_SOURCE
|
||||
#undef __USE_XOPEN
|
||||
|
||||
#include <ctype.h>
|
||||
#include <glib.h>
|
||||
#include <libgnome/gnome-defs.h>
|
||||
#include <libgnome/gnome-i18n.h>
|
||||
#include "e-time-utils.h"
|
||||
|
||||
static gboolean string_is_empty (const char *value);
|
||||
|
||||
|
||||
/*
|
||||
* Parses a string containing a date and a time. The date is expected to be
|
||||
* in a format something like "Wed 3/13/00 14:20:00", though we use gettext
|
||||
* to support the appropriate local formats and we try to accept slightly
|
||||
* different formats, e.g. the weekday can be skipped and we can accept 12-hour
|
||||
* formats with an am/pm string.
|
||||
*
|
||||
* Returns E_TIME_PARSE_OK if it could not be parsed, E_TIME_PARSE_NONE if it
|
||||
* was empty, or E_TIME_PARSE_INVALID if it couldn't be parsed.
|
||||
*/
|
||||
ETimeParseStatus
|
||||
e_time_parse_date_and_time (const char *value,
|
||||
struct tm *result)
|
||||
{
|
||||
struct tm discard_tm, time_tm;
|
||||
struct tm *today_tm;
|
||||
time_t t;
|
||||
const char *pos, *parse_end;
|
||||
char *format[4];
|
||||
gboolean parsed_date = FALSE, parsed_time = FALSE;
|
||||
gint i;
|
||||
|
||||
if (string_is_empty (value))
|
||||
return E_TIME_PARSE_NONE;
|
||||
|
||||
pos = value;
|
||||
|
||||
/* Skip any whitespace. */
|
||||
while (isspace (*pos))
|
||||
pos++;
|
||||
|
||||
/* Skip any weekday name, full or abbreviated. */
|
||||
parse_end = strptime (pos, "%a ", &discard_tm);
|
||||
if (parse_end)
|
||||
pos = parse_end;
|
||||
|
||||
memset (result, 0, sizeof (*result));
|
||||
/* strptime format for a date. */
|
||||
parse_end = strptime (pos, _("%m/%d/%Y"), result);
|
||||
if (parse_end) {
|
||||
pos = parse_end;
|
||||
parsed_date = TRUE;
|
||||
}
|
||||
|
||||
/* Skip any whitespace. */
|
||||
while (isspace (*pos))
|
||||
pos++;
|
||||
|
||||
/* Skip any weekday name, full or abbreviated, again. */
|
||||
parse_end = strptime (pos, "%a ", &discard_tm);
|
||||
if (parse_end)
|
||||
pos = parse_end;
|
||||
|
||||
|
||||
/* strptime format for a time of day, in 12-hour format.
|
||||
If it is not appropriate in the locale set to an empty string. */
|
||||
format[0] = _("%I:%M:%S %p%n");
|
||||
|
||||
/* strptime format for a time of day, in 24-hour format. */
|
||||
format[1] = _("%H:%M:%S%n");
|
||||
|
||||
/* strptime format for time of day, without seconds, 12-hour format.
|
||||
If it is is not appropriate in the locale set to an empty string. */
|
||||
format[2] = _("%I:%M %p%n");
|
||||
|
||||
/* strptime format for time of day, without seconds 24-hour format. */
|
||||
format[3] = _("%H:%M%n");
|
||||
|
||||
for (i = 0; i < sizeof (format) / sizeof (format[0]); i++) {
|
||||
memset (&time_tm, 0, sizeof (time_tm));
|
||||
parse_end = strptime (pos, format[i], &time_tm);
|
||||
if (parse_end) {
|
||||
pos = parse_end;
|
||||
parsed_time = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip any whitespace. */
|
||||
while (isspace (*pos))
|
||||
pos++;
|
||||
|
||||
/* If we haven't already parsed a date, try again. */
|
||||
if (!parsed_date) {
|
||||
memset (result, 0, sizeof (*result));
|
||||
/* strptime format for a date. */
|
||||
parse_end = strptime (pos, _("%m/%d/%Y"), result);
|
||||
if (parse_end) {
|
||||
pos = parse_end;
|
||||
parsed_date = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't have a date or a time it must be invalid. */
|
||||
if (!parsed_date && !parsed_time)
|
||||
return E_TIME_PARSE_INVALID;
|
||||
|
||||
if (parsed_date) {
|
||||
/* If a 2-digit year was used we use the current century. */
|
||||
if (result->tm_year < 0) {
|
||||
t = time (NULL);
|
||||
today_tm = localtime (&t);
|
||||
|
||||
/* This should convert it into a value from 0 to 99. */
|
||||
result->tm_year += 1900;
|
||||
|
||||
/* Now add on the century. */
|
||||
result->tm_year += today_tm->tm_year
|
||||
- (today_tm->tm_year % 100);
|
||||
}
|
||||
} else {
|
||||
/* If we didn't get a date we use the current day. */
|
||||
t = time (NULL);
|
||||
today_tm = localtime (&t);
|
||||
result->tm_mday = today_tm->tm_mday;
|
||||
result->tm_mon = today_tm->tm_mon;
|
||||
result->tm_year = today_tm->tm_year;
|
||||
}
|
||||
|
||||
if (parsed_time) {
|
||||
result->tm_hour = time_tm.tm_hour;
|
||||
result->tm_min = time_tm.tm_min;
|
||||
result->tm_sec = time_tm.tm_sec;
|
||||
} else {
|
||||
result->tm_hour = 0;
|
||||
result->tm_min = 0;
|
||||
result->tm_sec = 0;
|
||||
}
|
||||
|
||||
result->tm_isdst = -1;
|
||||
|
||||
return E_TIME_PARSE_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parses a string containing a time. It is expected to be in a format
|
||||
* something like "14:20:00", though we use gettext to support the appropriate
|
||||
* local formats and we try to accept slightly different formats, e.g. we can
|
||||
* accept 12-hour formats with an am/pm string.
|
||||
*
|
||||
* Returns E_TIME_PARSE_OK if it could not be parsed, E_TIME_PARSE_NONE if it
|
||||
* was empty, or E_TIME_PARSE_INVALID if it couldn't be parsed.
|
||||
*/
|
||||
ETimeParseStatus
|
||||
e_time_parse_time (const char *value,
|
||||
struct tm *result)
|
||||
{
|
||||
const char *pos, *parse_end;
|
||||
char *format[4];
|
||||
gboolean parsed_time = FALSE;
|
||||
gint i;
|
||||
|
||||
if (string_is_empty (value)) {
|
||||
memset (result, 0, sizeof (*result));
|
||||
result->tm_isdst = -1;
|
||||
return E_TIME_PARSE_NONE;
|
||||
}
|
||||
|
||||
pos = value;
|
||||
|
||||
/* Skip any whitespace. */
|
||||
while (isspace (*pos))
|
||||
pos++;
|
||||
|
||||
/* strptime format for a time of day, in 12-hour format.
|
||||
If it is not appropriate in the locale set to an empty string. */
|
||||
format[0] = _("%I:%M:%S %p%n");
|
||||
|
||||
/* strptime format for a time of day, in 24-hour format. */
|
||||
format[1] = _("%H:%M:%S%n");
|
||||
|
||||
/* strptime format for time of day, without seconds, 12-hour format.
|
||||
If it is is not appropriate in the locale set to an empty string. */
|
||||
format[2] = _("%I:%M %p%n");
|
||||
|
||||
/* strptime format for time of day, without seconds 24-hour format. */
|
||||
format[3] = _("%H:%M%n");
|
||||
|
||||
for (i = 0; i < sizeof (format) / sizeof (format[0]); i++) {
|
||||
memset (result, 0, sizeof (*result));
|
||||
parse_end = strptime (pos, format[i], result);
|
||||
if (parse_end) {
|
||||
pos = parse_end;
|
||||
parsed_time = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result->tm_isdst = -1;
|
||||
|
||||
/* If we don't have a date or a time it must be invalid. */
|
||||
if (!parsed_time)
|
||||
return E_TIME_PARSE_INVALID;
|
||||
|
||||
return E_TIME_PARSE_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Returns whether a string is NULL, empty, or full of whitespace */
|
||||
static gboolean
|
||||
string_is_empty (const char *value)
|
||||
{
|
||||
const char *p;
|
||||
gboolean empty = TRUE;
|
||||
|
||||
if (value) {
|
||||
p = value;
|
||||
while (*p) {
|
||||
if (!isspace (*p)) {
|
||||
empty = FALSE;
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
/* Creates a string representation of a time value and stores it in result.
|
||||
result_size is the size of the result buffer, and should be about 64 to
|
||||
be safe. If show_midnight is FALSE, and the time is midnight, then we just
|
||||
show the date. */
|
||||
void
|
||||
e_time_format_date_and_time (struct tm *date_tm,
|
||||
gboolean use_24_hour_format,
|
||||
gboolean show_midnight,
|
||||
gboolean show_zero_seconds,
|
||||
char *result,
|
||||
int result_size)
|
||||
{
|
||||
char *format;
|
||||
|
||||
if (!show_midnight && date_tm->tm_hour == 0
|
||||
&& date_tm->tm_min == 0 && date_tm->tm_sec == 0) {
|
||||
/* strftime format of a weekday and a date. */
|
||||
format = _("%a %m/%d/%Y");
|
||||
} else if (use_24_hour_format) {
|
||||
if (!show_zero_seconds && date_tm->tm_sec == 0)
|
||||
/* strftime format of a weekday, a date and a
|
||||
time, in 24-hour format, without seconds. */
|
||||
format = _("%a %m/%d/%Y %H:%M");
|
||||
else
|
||||
/* strftime format of a weekday, a date and a
|
||||
time, in 24-hour format. */
|
||||
format = _("%a %m/%d/%Y %H:%M:%S");
|
||||
} else {
|
||||
if (!show_zero_seconds && date_tm->tm_sec == 0)
|
||||
/* strftime format of a weekday, a date and a
|
||||
time, in 12-hour format, without seconds. */
|
||||
format = _("%a %m/%d/%Y %I:%M %p");
|
||||
else
|
||||
/* strftime format of a weekday, a date and a
|
||||
time, in 12-hour format. */
|
||||
format = _("%a %m/%d/%Y %I:%M:%S %p");
|
||||
}
|
||||
|
||||
/* strftime returns 0 if the string doesn't fit, and leaves the buffer
|
||||
undefined, so we set it to the empty string in that case. */
|
||||
if (strftime (result, result_size, format, date_tm) == 0)
|
||||
result[0] = '\0';
|
||||
}
|
||||
35
e-util/e-time-utils.h
Normal file
35
e-util/e-time-utils.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* Time utility functions
|
||||
*
|
||||
* Author:
|
||||
* Damon Chaplin (damon@ximian.com)
|
||||
*
|
||||
* (C) 2001 Ximian, Inc.
|
||||
*/
|
||||
|
||||
#ifndef E_TIME_UTILS
|
||||
#define E_TIME_UTILS
|
||||
|
||||
typedef enum {
|
||||
E_TIME_PARSE_OK,
|
||||
E_TIME_PARSE_NONE,
|
||||
E_TIME_PARSE_INVALID
|
||||
} ETimeParseStatus;
|
||||
|
||||
/* Tries to parse a string containing a date and time. */
|
||||
ETimeParseStatus e_time_parse_date_and_time (const char *value,
|
||||
struct tm *result);
|
||||
|
||||
/* Tries to parse a string containing a time. */
|
||||
ETimeParseStatus e_time_parse_time (const char *value,
|
||||
struct tm *result);
|
||||
|
||||
/* Turns a struct tm into a string like "Wed 3/12/00 12:00:00 AM". */
|
||||
void e_time_format_date_and_time (struct tm *date_tm,
|
||||
gboolean use_24_hour_format,
|
||||
gboolean show_midnight,
|
||||
gboolean show_zero_seconds,
|
||||
char *result,
|
||||
int result_size);
|
||||
#endif /* E_TIME_UTILS */
|
||||
Reference in New Issue
Block a user