From ad59a4ffd9d7f8a2cb84b6b1fac7f42ea3d6fa26 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Sun, 6 Dec 2015 10:36:58 +0100 Subject: [PATCH] Added datetime functions from libsolipa. Added function ::string_replace. --- src/Makefile.am | 6 +- src/datetime.c | 467 ++++++++++++++++++++++++++++++++++++++++++++++ src/datetime.h | 52 ++++++ src/generic.c | 32 ++++ src/generic.h | 4 + src/libzakutils.h | 1 + 6 files changed, 560 insertions(+), 2 deletions(-) create mode 100644 src/datetime.c create mode 100644 src/datetime.h diff --git a/src/Makefile.am b/src/Makefile.am index e12b89d..f63fb4d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,12 +7,14 @@ AM_CPPFLAGS = $(ZAKUTILS_CFLAGS) \ lib_LTLIBRARIES = libzakutils.la libzakutils_la_SOURCES = \ - generic.c + generic.c \ + datetime.c libzakutils_la_LDFLAGS = -no-undefined libzakutils_include_HEADERS = \ libzakutils.h \ - generic.h + generic.h \ + datetime.h libzakutils_includedir = $(includedir)/libzakutils diff --git a/src/datetime.c b/src/datetime.c new file mode 100644 index 0000000..cc6647b --- /dev/null +++ b/src/datetime.c @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2015 Andrea Zagli + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#include "generic.h" +#include "datetime.h" + + +/** + * zak_utils_get_now_tm: + * + */ +struct tm +*zak_utils_get_now_tm (void) +{ + time_t tt; + + tt = time (NULL); + + return localtime (&tt); +} + +/** + * zak_utils_get_today_gdate: + * + */ +GDate +*zak_utils_get_today_gdate (void) +{ + struct tm *tt_tm = zak_utils_get_now_tm (); + + return g_date_new_dmy ((GDateDay)tt_tm->tm_mday, + (GDateMonth)tt_tm->tm_mon + 1, + (GDateYear)tt_tm->tm_year + 1900); +} + +/** + * zak_utils_tm_to_gdatetime: + * @tm_date: + * + */ +GDateTime +*zak_utils_tm_to_gdatetime (struct tm *tm_date) +{ + GDateTime *ret; + + ret = NULL; + if (tm_date != NULL) + { + ret = g_date_time_new_local (tm_date->tm_year + 1900, + tm_date->tm_mon + 1, + tm_date->tm_mday, + tm_date->tm_hour, + tm_date->tm_min, + tm_date->tm_sec); + } + + return ret; +} + +/** + * zak_utils_gdatetime_to_tm: + * @gdatetime: + * + */ +struct tm +*zak_utils_gdatetime_to_tm (GDateTime *gdatetime) +{ + struct tm *ret; + + ret = g_new0 (struct tm, 1); + ret->tm_year = g_date_time_get_year (gdatetime) - 1900; + ret->tm_mon = g_date_time_get_month (gdatetime) - 1; + ret->tm_mday = g_date_time_get_day_of_month (gdatetime); + ret->tm_hour = g_date_time_get_hour (gdatetime); + ret->tm_min = g_date_time_get_minute (gdatetime); + ret->tm_sec = g_date_time_get_second (gdatetime); + mktime (ret); + + return ret; +} + +/** + * zak_utils_gdate_to_gdatetime: + * @gdate: + * + */ +GDateTime +*zak_utils_gdate_to_gdatetime (GDate *gdate) +{ + GDateTime *ret; + + ret = NULL; + if (gdate != NULL && g_date_valid (gdate)) + { + ret = g_date_time_new_local (g_date_get_year (gdate), + g_date_get_month (gdate), + g_date_get_day (gdate), + 0, 0, 0.0); + } + + return ret; +} + +/** + * zak_utils_gdatetime_to_gdate: + * @gdatetime: + * + */ +GDate +*zak_utils_gdatetime_to_gdate (GDateTime *gdatetime) +{ + GDate *ret; + + ret = NULL; + if (gdatetime != NULL) + { + ret = g_new0 (GDate, 1); + g_date_set_year (ret, g_date_time_get_year (gdatetime)); + g_date_set_month (ret, g_date_time_get_month (gdatetime)); + g_date_set_day (ret, g_date_time_get_day_of_month (gdatetime)); + } + + return ret; +} + +/** + * zak_utils_tm_to_sql: + * @tm_data: + * @format: + * + */ +const gchar +*zak_utils_tm_to_sql (struct tm *tm_data, const gchar *format) +{ + const gchar *ret; + + ret = g_strdup ("NULL"); + + if (tm_data != NULL) + { + ret = zak_utils_gdatetime_to_sql (zak_utils_tm_to_gdatetime (tm_data), format); + } + + return ret; +} + +/** + * zak_utils_gdate_to_sql: + * @gdate: + * @format: + * + */ +const gchar +*zak_utils_gdate_to_sql (GDate *gdate, const gchar *format) +{ + const gchar *ret; + + ret = g_strdup ("NULL"); + + if (gdate != NULL && g_date_valid (gdate)) + { + ret = zak_utils_gdatetime_to_sql (zak_utils_gdate_to_gdatetime (gdate), format == NULL ? "date" : format); + } + + return ret; +} + +/** + * zak_utils_gdatetime_to_sql: + * @gdatetime: + * @format: + * + */ +const gchar +*zak_utils_gdatetime_to_sql (GDateTime *gdatetime, const gchar *format) +{ + const gchar *ret; + gchar *_format; + + ret = g_strdup ("NULL"); + + if (gdatetime != NULL) + { + if (format == NULL) + { + _format = g_strdup ("%F %R:%S"); + } + else + { + _format = g_strstrip (g_strdup (format)); + if (g_strcmp0 (_format, "") == 0 + || g_strcmp0 (_format, "datetime") == 0) + { + _format = g_strdup ("%F %R:%S"); + } + else if (g_strcmp0 (_format, "date") == 0) + { + _format = g_strdup ("%F"); + } + else if (g_strcmp0 (_format, "time") == 0) + { + _format = g_strdup ("%R:%S"); + } + } + ret = g_strdup_printf ("'%s'", g_date_time_format (gdatetime, _format)); + } + + return ret; +} + +/** + * zak_utils_get_gdate_from_string: + * @string: + * @format: + * + */ +GDate +*zak_utils_get_gdate_from_string (const gchar *string, const gchar *format) +{ + GDate *ret; + + GDateTime *gdatetime; + + gdatetime = zak_utils_get_gdatetime_from_string (string, format); + + ret = zak_utils_gdatetime_to_gdate (gdatetime); + + g_object_unref (gdatetime); + + return ret; +} + +/** + * zak_utils_get_gdatetime_from_string: + * @string: + * @format: + * + */ +GDateTime +*zak_utils_get_gdatetime_from_string (const gchar *string, const gchar *format) +{ + GDateTime *ret; + + gchar *new_str; + gchar *new_format; + gchar **str_tokens; + gchar **format_tokens; + gchar *delimiters; + guint len_strv; + guint len_formatv; + guint i; + guint i_to; + + gint year; + gint month; + gint day; + gint hour; + gint minute; + gdouble seconds; + + gboolean error; + + g_return_val_if_fail (string != NULL, NULL); + + new_str = g_strstrip (g_strdup (string)); + if (g_strcmp0 (new_str, "") == 0) + { + g_free (new_str); + return NULL; + } + + if (format == NULL) + { + new_format = g_strdup ("%Y-%m-%d %H:%M:%S"); + } + else + { + new_format = g_strstrip (g_strdup (format)); + if (g_strcmp0 (new_format, "") == 0) + { + new_format = g_strdup ("%Y-%m-%d %H:%M:%S"); + } + } + + /* removes format identifiers to find delimiters */ + delimiters = zak_utils_string_replace (new_format, "%Y", ""); + delimiters = zak_utils_string_replace (delimiters, "%m", ""); + delimiters = zak_utils_string_replace (delimiters, "%d", ""); + delimiters = zak_utils_string_replace (delimiters, "%H", ""); + delimiters = zak_utils_string_replace (delimiters, "%M", ""); + delimiters = zak_utils_string_replace (delimiters, "%S", ""); + + if (delimiters == NULL || g_strcmp0 (delimiters, "") == 0) + { + g_free (delimiters); + g_free (new_format); + g_free (new_str); + return NULL; + } + + str_tokens = g_strsplit_set (string, delimiters, -1); + if (str_tokens == NULL) + { + g_free (delimiters); + g_free (new_format); + g_free (new_str); + return NULL; + } + + format_tokens = g_strsplit_set (format, delimiters, -1); + if (format_tokens == NULL) + { + g_free (delimiters); + g_free (new_format); + g_free (new_str); + return NULL; + } + + len_strv = g_strv_length (str_tokens); + len_formatv = g_strv_length (format_tokens); + + year = 1; + month = 1; + day = 1; + hour = 0; + minute = 0; + seconds = 0.0; + + error = FALSE; + ret = NULL; + + i_to = MIN (len_strv, len_formatv); + for (i = 0; i < i_to; i++) + { + if (g_strcmp0 (format_tokens[i], "%Y") == 0) + { + year = strtol (str_tokens[i], NULL, 10); + if (year < 1 || year > 9999) + { + error = TRUE; + break; + } + } + else if (g_strcmp0 (format_tokens[i], "%m") == 0) + { + month = strtol (str_tokens[i], NULL, 10); + if (month < 1 || month > 12) + { + error = TRUE; + break; + } + } + else if (g_strcmp0 (format_tokens[i], "%d") == 0) + { + day = strtol (str_tokens[i], NULL, 10); + if (day < 1 || day > 31) + { + error = TRUE; + break; + } + } + else if (g_strcmp0 (format_tokens[i], "%H") == 0) + { + hour = strtol (str_tokens[i], NULL, 10); + if (hour > 23) + { + error = TRUE; + break; + } + } + else if (g_strcmp0 (format_tokens[i], "%M") == 0) + { + minute = strtol (str_tokens[i], NULL, 10); + if (minute > 59) + { + error = TRUE; + break; + } + } + else if (g_strcmp0 (format_tokens[i], "%S") == 0) + { + seconds = g_strtod (str_tokens[i], NULL); + if (seconds > 59.0) + { + error = TRUE; + break; + } + } + } + + g_strfreev (format_tokens); + g_strfreev (str_tokens); + g_free (delimiters); + g_free (new_format); + g_free (new_str); + + if (!error) + { + ret = g_date_time_new_local (year, + month, + day, + hour, + minute, + seconds); + } + + return ret; +} + +/** + * zak_utils_gate_format: + * @gdate: + * @format: + * + */ +gchar +*zak_utils_gdate_format (GDate *gdate, const gchar *format) +{ + gchar *ret; + + if (g_date_valid (gdate)) return ""; + + ret = zak_utils_gdatetime_format (zak_utils_gdate_to_gdatetime (gdate), format); + + return ret; +} + +/** + * zak_utils_gdatetime_format: + * @gdate: + * @format: + * + */ +gchar +*zak_utils_gdatetime_format (GDateTime *gdatetime, const gchar *format) +{ + gchar *ret; + + if (gdatetime == NULL) return ""; + + ret = g_date_time_format (gdatetime, format); + + if (ret == NULL) return ""; + + return ret; +} diff --git a/src/datetime.h b/src/datetime.h new file mode 100644 index 0000000..094e749 --- /dev/null +++ b/src/datetime.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 Andrea Zagli + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __ZAK_UTILS_DATETIME_H__ +#define __ZAK_UTILS_DATETIME_H__ + + +#include +#include + + +G_BEGIN_DECLS + + +struct tm *zak_utils_get_now_tm (void); +GDate *zak_utils_get_today_gdate (void); + +GDateTime *zak_utils_tm_to_gdatetime (struct tm *tm_date); +struct tm *zak_utils_gdatetime_to_tm (GDateTime *gdatetime); + +GDateTime *zak_utils_gdate_to_gdatetime (GDate *gdate); +GDate *zak_utils_gdatetime_to_gdate (GDateTime *gdatetime); + +const gchar *zak_utils_tm_to_sql (struct tm *tm_date, const gchar *format); +const gchar *zak_utils_gdate_to_sql (GDate *gdate, const gchar *format); +const gchar *zak_utils_gdatetime_to_sql (GDateTime *gdatetime, const gchar *format); + +GDate *zak_utils_get_gdate_from_string (const gchar *string, const gchar *format); +GDateTime *zak_utils_get_gdatetime_from_string (const gchar *string, const gchar *format); +gchar *zak_utils_gdate_format (GDate *gdate, const gchar *format); +gchar *zak_utils_gdatetime_format (GDateTime *gdatetime, const gchar *format); + + +G_END_DECLS + + +#endif /* __ZAK_UTILS_DATETIME_H__ */ diff --git a/src/generic.c b/src/generic.c index 8d9e720..7ab5f07 100644 --- a/src/generic.c +++ b/src/generic.c @@ -46,6 +46,38 @@ zak_utils_file_exists (const gchar *filename) return ret; } +/** + * zak_utils_string_replace: + * @string: + * @origin: + * @replace: + * + */ +gchar +*zak_utils_string_replace (const gchar *string, + const gchar *origin, + const gchar *replace) +{ + gchar *ret; + gchar *p; + + if (string == NULL) return NULL; + if (origin == NULL || replace == NULL) return g_strdup (string); + + p = g_strstr_len (string, -1, origin); + + if (p == NULL) + { + return g_strdup (string); + } + + ret = g_strndup (string, p - string); + + ret = g_strdup_printf ("%s%s%s", ret, replace, p + strlen (origin)); + + return ret; +} + /** * zak_utils_round: * @value: diff --git a/src/generic.h b/src/generic.h index 0ee9247..bfa0fe2 100644 --- a/src/generic.h +++ b/src/generic.h @@ -30,6 +30,10 @@ G_BEGIN_DECLS gboolean zak_utils_file_exists (const gchar *filename); +gchar *zak_utils_string_replace (const gchar *string, + const gchar *origin, + const gchar *replace); + gdouble zak_utils_round (gdouble value, guint n_decimals); gchar *zak_utils_format_money (gdouble number, gint decimals, gboolean with_currency_symbol); diff --git a/src/libzakutils.h b/src/libzakutils.h index c1410ff..20ffe19 100644 --- a/src/libzakutils.h +++ b/src/libzakutils.h @@ -21,6 +21,7 @@ #include +#include #endif /* __LIBZAKUTILS_H__ */ -- 2.49.0