From: Andrea Zagli Date: Sat, 5 Sep 2009 14:16:28 +0000 (+0200) Subject: Added display-format property to GtkFormFieldDateTime. X-Git-Tag: 0.1.0~20 X-Git-Url: https://saetta.ns0.it/gitweb?a=commitdiff_plain;h=0b64fbdf208facd4a15427b05b7cbfa48e4773f6;p=libgtkform Added display-format property to GtkFormFieldDateTime. Reimplemented function GtkFormFieldDateTime::get_tm_from_str to be more accurate and extendable. Menaged datetime-type property on xml definition for GtkFormFieldDateTime. --- diff --git a/data/gtkform.dtd b/data/gtkform.dtd index 202f7c1..ad8db76 100644 --- a/data/gtkform.dtd +++ b/data/gtkform.dtd @@ -14,7 +14,7 @@ - + + + diff --git a/docs/reference/libgtkform-decl.txt b/docs/reference/libgtkform-decl.txt index e418092..62bcf87 100644 --- a/docs/reference/libgtkform-decl.txt +++ b/docs/reference/libgtkform-decl.txt @@ -526,7 +526,7 @@ GtkFormField *field, GdaDataModel *dm, gint row gtk_form_field_datetime_get_tm_from_str struct tm * -const gchar *str +const gchar *str, const gchar *format gtk_form_field_datetime_get_str_from_tm diff --git a/docs/reference/libgtkform-undocumented.txt b/docs/reference/libgtkform-undocumented.txt index fcb0787..18721ba 100644 --- a/docs/reference/libgtkform-undocumented.txt +++ b/docs/reference/libgtkform-undocumented.txt @@ -1,5 +1,5 @@ 7% symbol docs coverage. -19 symbols documented. +20 symbols documented. 1 symbols incomplete. 271 not documented. @@ -126,6 +126,7 @@ gtk_form_field_boolean_set_from_datamodel gtk_form_field_boolean_str_to_boolean (value) gtk_form_field_clear gtk_form_field_datetime_clear +gtk_form_field_datetime_get_str_format gtk_form_field_datetime_get_str_from_tm gtk_form_field_datetime_get_tm_from_str gtk_form_field_datetime_get_type @@ -149,7 +150,6 @@ gtk_form_field_float_new gtk_form_field_float_set_as_origin gtk_form_field_float_set_from_datamodel gtk_form_field_get_field_name -gtk_form_field_get_str_format gtk_form_field_get_type gtk_form_field_get_value gtk_form_field_get_value_sql diff --git a/docs/reference/libgtkform.args b/docs/reference/libgtkform.args index 4fda591..ab99c82 100644 --- a/docs/reference/libgtkform.args +++ b/docs/reference/libgtkform.args @@ -48,6 +48,16 @@ + +GtkFormFieldDateTime::display-format +gchar* + +rwx +Display format +Display format. +"%Y-%m-%d %H:%M:%S" + + GtkFormFieldDateTime::type gint diff --git a/docs/reference/tmpl/fielddatetime.sgml b/docs/reference/tmpl/fielddatetime.sgml index a97eb78..9706ebe 100644 --- a/docs/reference/tmpl/fielddatetime.sgml +++ b/docs/reference/tmpl/fielddatetime.sgml @@ -75,6 +75,11 @@ FormFieldDateTime + + + + + diff --git a/src/field.c b/src/field.c index 218d259..82b6646 100644 --- a/src/field.c +++ b/src/field.c @@ -251,7 +251,8 @@ gtk_form_field_is_empty (GtkFormField *field) * @field: a #GtkFormField object. * * Returns: TRUE if the values in the form are changed since last calling to - * gtk_form_field_clear() or gtk_form_field_set_from_datamodel(). + * gtk_form_field_clear(), gtk_form_field_set_from_datamodel() or + * gtk_form_field_set_as_origin(). */ gboolean gtk_form_field_is_changed (GtkFormField *field) diff --git a/src/fielddatetime.c b/src/fielddatetime.c index 5af6a41..6cc2bc1 100644 --- a/src/fielddatetime.c +++ b/src/fielddatetime.c @@ -27,7 +27,8 @@ enum { PROP_0, PROP_DEFAULT, - PROP_TYPE + PROP_TYPE, + PROP_DISPLAY_FORMAT }; static void gtk_form_field_datetime_class_init (GtkFormFieldDateTimeClass *klass); @@ -44,7 +45,7 @@ static void gtk_form_field_datetime_get_property (GObject *object, static gboolean gtk_form_field_datetime_set_value_stringify (GtkFormField *field, const gchar *value); -static gchar *gtk_form_field_get_str_format (GtkFormField *field); +static gchar *gtk_form_field_datetime_get_str_format (GtkFormFieldDateTime *field); static gchar *gtk_form_field_datetime_str_replace (const gchar *string, const gchar *origin, @@ -59,6 +60,8 @@ struct _GtkFormFieldDateTimePrivate struct tm *original_value; gint type; + + gchar *display_format; }; @@ -97,6 +100,13 @@ gtk_form_field_datetime_class_init (GtkFormFieldDateTimeClass *klass) GTK_FORM_FIELD_DATETIME_TYPE_DATETIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, PROP_DISPLAY_FORMAT, + g_param_spec_string ("display-format", + "Display format", + "Display format", + "%Y-%m-%d %H:%M:%S", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_type_class_add_private (object_class, sizeof (GtkFormFieldDateTimePrivate)); } @@ -148,6 +158,7 @@ const gchar * gtk_form_field_datetime_get_value: * @field: a #GtkFormField object. * + * Returns: a #GValue of type G_TYPE_POINTER that point to a struct tm. */ const GValue *gtk_form_field_datetime_get_value (GtkFormField *field) @@ -155,14 +166,17 @@ const GValue struct tm *datetime; GValue *ret; const gchar *value; + GtkFormFieldDateTimePrivate *priv; g_return_val_if_fail (IS_GTK_FORM_FIELD_DATETIME (field), NULL); + priv = GTK_FORM_FIELD_DATETIME_GET_PRIVATE (GTK_FORM_FIELD_DATETIME (field)); + ret = NULL; value = gtk_form_field_datetime_get_value_stringify (field); - datetime = gtk_form_field_datetime_get_tm_from_str (value); + datetime = gtk_form_field_datetime_get_tm_from_str (value, priv->display_format); if (value != NULL && datetime != NULL) { ret = g_malloc0 (sizeof (GValue)); @@ -184,18 +198,21 @@ const gchar const gchar *ret; const gchar *value; const gchar *format; + GtkFormFieldDateTimePrivate *priv; g_return_val_if_fail (IS_GTK_FORM_FIELD_DATETIME (field), NULL); + priv = GTK_FORM_FIELD_DATETIME_GET_PRIVATE (GTK_FORM_FIELD_DATETIME (field)); + ret = NULL; value = gtk_form_field_datetime_get_value_stringify (field); - format = gtk_form_field_get_str_format (field); + format = gtk_form_field_datetime_get_str_format (GTK_FORM_FIELD_DATETIME (field)); if (value != NULL) { struct tm *datetime; - datetime = gtk_form_field_datetime_get_tm_from_str (value); + datetime = gtk_form_field_datetime_get_tm_from_str (value, priv->display_format); if (datetime != NULL) { gchar *value; @@ -221,12 +238,9 @@ gtk_form_field_datetime_clear (GtkFormField *field) { gboolean ret; GtkFormFieldDateTimePrivate *priv; - gchar *format; g_return_val_if_fail (IS_GTK_FORM_FIELD_DATETIME (field), FALSE); - format = gtk_form_field_get_str_format (field); - priv = GTK_FORM_FIELD_DATETIME_GET_PRIVATE (field); ret = FALSE; @@ -234,7 +248,7 @@ gtk_form_field_datetime_clear (GtkFormField *field) { gchar *value; - value = gtk_form_field_datetime_get_str_from_tm (priv->default_value, format); + value = gtk_form_field_datetime_get_str_from_tm (priv->default_value, priv->display_format); if (value != NULL) { ret = gtk_form_field_datetime_set_value_stringify (field, value); @@ -283,7 +297,8 @@ gtk_form_field_datetime_is_changed (GtkFormField *field) priv = GTK_FORM_FIELD_DATETIME_GET_PRIVATE (GTK_FORM_FIELD_DATETIME (field)); - value = gtk_form_field_datetime_get_tm_from_str (gtk_form_field_datetime_get_value_stringify (field)); + value = gtk_form_field_datetime_get_tm_from_str (gtk_form_field_datetime_get_value_stringify (field), + priv->display_format); if (value != NULL) { @@ -314,7 +329,8 @@ gtk_form_field_datetime_set_as_origin (GtkFormField *field) priv = GTK_FORM_FIELD_DATETIME_GET_PRIVATE (GTK_FORM_FIELD_DATETIME (field)); - value = gtk_form_field_datetime_get_tm_from_str (gtk_form_field_datetime_get_value_stringify (field)); + value = gtk_form_field_datetime_get_tm_from_str (gtk_form_field_datetime_get_value_stringify (field), + priv->display_format); priv->original_value = g_memdup (value, sizeof (struct tm)); } @@ -329,23 +345,38 @@ gtk_form_field_datetime_set_as_origin (GtkFormField *field) gboolean gtk_form_field_datetime_set_from_datamodel (GtkFormField *field, GdaDataModel *dm, gint row) { - gboolean ret = FALSE; + gboolean ret; GtkFormFieldDateTimePrivate *priv; - const gchar *field_name; - const gchar *value; + gchar *field_name; + struct tm *datetime; + gchar *value; + gchar *format; g_return_val_if_fail (IS_GTK_FORM_FIELD_DATETIME (field), FALSE); g_return_val_if_fail (GDA_IS_DATA_MODEL (dm), FALSE); + ret = FALSE; + priv = GTK_FORM_FIELD_DATETIME_GET_PRIVATE (GTK_FORM_FIELD_DATETIME (field)); - field_name = gtk_form_field_get_field_name (field); + field_name = (gchar *)gtk_form_field_get_field_name (field); - value = gdaex_data_model_get_field_value_stringify_at (dm, row, field_name); + if (field_name != NULL && g_strcmp0 (g_strstrip (field_name), "") != 0) + { + datetime = gdaex_data_model_get_field_value_tm_at (dm, row, field_name); + + value = gtk_form_field_datetime_get_str_from_tm (datetime, priv->display_format); - ret = gtk_form_field_datetime_set_value_stringify (field, value); + ret = gtk_form_field_datetime_set_value_stringify (field, value); - priv->original_value = gtk_form_field_datetime_get_tm_from_str (value); + format = gtk_form_field_datetime_get_str_format (GTK_FORM_FIELD_DATETIME (field)); + + priv->original_value = gtk_form_field_datetime_get_tm_from_str (value, format); + } + else + { + g_warning ("GtkFormField hasn't a field name."); + } return ret; } @@ -353,61 +384,100 @@ gtk_form_field_datetime_set_from_datamodel (GtkFormField *field, GdaDataModel *d /** * gtk_form_field_datetime_get_tm_from_str: * @str: the #gchar to be parsed. + * @format: * */ struct tm -*gtk_form_field_datetime_get_tm_from_str (const gchar *str) +*gtk_form_field_datetime_get_tm_from_str (const gchar *str, const gchar *format) { /* TO DO * check if it is a valid date/time */ - struct tm *tm; + struct tm *ret; gchar *new_str; + gchar *new_format; + gchar **str_tokens; + gchar **format_tokens; + gchar *delimiters; + guint len_strv; + guint len_formatv; + guint i; g_return_val_if_fail (str != NULL, NULL); new_str = g_strstrip (g_strdup (str)); + if (g_strcmp0 (new_str, "") == 0) + { + return NULL; + } + + 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 = gtk_form_field_datetime_str_replace (new_format, "%Y", ""); + delimiters = gtk_form_field_datetime_str_replace (delimiters, "%m", ""); + delimiters = gtk_form_field_datetime_str_replace (delimiters, "%d", ""); + delimiters = gtk_form_field_datetime_str_replace (delimiters, "%H", ""); + delimiters = gtk_form_field_datetime_str_replace (delimiters, "%M", ""); + delimiters = gtk_form_field_datetime_str_replace (delimiters, "%S", ""); - if (strcmp (new_str, "") == 0) + if (delimiters == NULL || g_strcmp0 (delimiters, "") == 0) { return NULL; } - tm = g_malloc0 (sizeof (struct tm)); - tm->tm_mday = 1; - switch (strlen (str)) + str_tokens = g_strsplit_set (str, delimiters, -1); + if (str_tokens == NULL) { - case 8: - /* only time */ - tm->tm_hour = strtol (g_strndup (new_str, 2), NULL, 10); - tm->tm_min = strtol (g_strndup (new_str + 3, 2), NULL, 10); - tm->tm_sec = strtol (g_strndup (new_str + 6, 2), NULL, 10); - break; + return NULL; + } - case 10: - /* only date */ - tm->tm_year = strtol (g_strndup (new_str, 4), NULL, 10) - 1900; - tm->tm_mon = strtol (g_strndup (new_str + 5, 2), NULL, 10) - 1; - tm->tm_mday = strtol (g_strndup (new_str + 8, 2), NULL, 10); - break; + format_tokens = g_strsplit_set (format, delimiters, -1); + if (format_tokens == NULL) + { + return NULL; + } - case 19: - /* date & time */ - tm->tm_year = strtol (g_strndup (new_str, 4), NULL, 10) - 1900; - tm->tm_mon = strtol (g_strndup (new_str + 5, 2), NULL, 10) - 1; - tm->tm_mday = strtol (g_strndup (new_str + 8, 2), NULL, 10); - tm->tm_hour = strtol (g_strndup (new_str + 11, 2), NULL, 10); - tm->tm_min = strtol (g_strndup (new_str + 14, 2), NULL, 10); - tm->tm_sec = strtol (g_strndup (new_str + 17, 2), NULL, 10); - break; + len_strv = g_strv_length (str_tokens); + len_formatv = g_strv_length (format_tokens); - default: - tm = NULL; - break; + ret = g_malloc0 (sizeof (struct tm)); + ret->tm_mday = 1; + + for (i = 0; i < MIN (len_strv, len_formatv); i++) + { + if (g_strcmp0 (format_tokens[i], "%Y") == 0) + { + ret->tm_year = strtol (str_tokens[i], NULL, 10) - 1900; + } + else if (g_strcmp0 (format_tokens[i], "%m") == 0) + { + ret->tm_mon = strtol (str_tokens[i], NULL, 10) - 1; + } + else if (g_strcmp0 (format_tokens[i], "%d") == 0) + { + ret->tm_mday = strtol (str_tokens[i], NULL, 10); + } + else if (g_strcmp0 (format_tokens[i], "%H") == 0) + { + ret->tm_hour = strtol (str_tokens[i], NULL, 10); + } + else if (g_strcmp0 (format_tokens[i], "%M") == 0) + { + ret->tm_min = strtol (str_tokens[i], NULL, 10); + } + else if (g_strcmp0 (format_tokens[i], "%S") == 0) + { + ret->tm_sec = strtol (str_tokens[i], NULL, 10); + } } - return tm; + return ret; } /** @@ -416,7 +486,7 @@ struct tm * @format: * * Returns: a string representation of @datetime based on the format in @format. - * It interprets a very little subset of format identifier from strftime. + * It interprets a very little subset of format identifiers from strftime. * %Y: the year with 4 digits. * %m: the month with 2 digits. * %d: the day with 2 digits. @@ -469,6 +539,10 @@ gtk_form_field_datetime_set_property (GObject *object, priv->type = g_value_get_int (value); break; + case PROP_DISPLAY_FORMAT: + priv->display_format = g_strdup (g_value_get_string (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -495,6 +569,10 @@ gtk_form_field_datetime_get_property (GObject *object, g_value_set_int (value, priv->type); break; + case PROP_DISPLAY_FORMAT: + g_value_set_string (value, priv->display_format); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -517,16 +595,19 @@ gtk_form_field_datetime_set_value_stringify (GtkFormField *field, const gchar *v } /** - * gtk_form_field_get_str_format: - * @field: a #GtkFormField object. + * gtk_form_field_datetime_get_str_format: + * @field: a #GtkFormFieldDateTime object. * */ static gchar -*gtk_form_field_get_str_format (GtkFormField *field) +*gtk_form_field_datetime_get_str_format (GtkFormFieldDateTime *field) { gchar *format; + GtkFormFieldDateTimePrivate *priv; - GtkFormFieldDateTimePrivate *priv = GTK_FORM_FIELD_DATETIME_GET_PRIVATE (field); + g_return_val_if_fail (IS_GTK_FORM_FIELD_DATETIME (field), NULL); + + priv = GTK_FORM_FIELD_DATETIME_GET_PRIVATE (field); switch (priv->type) { diff --git a/src/fielddatetime.h b/src/fielddatetime.h index f56f5b5..a3acef9 100644 --- a/src/fielddatetime.h +++ b/src/fielddatetime.h @@ -72,7 +72,7 @@ void gtk_form_field_datetime_set_as_origin (GtkFormField *field); gboolean gtk_form_field_datetime_set_from_datamodel (GtkFormField *field, GdaDataModel *dm, gint row); -struct tm *gtk_form_field_datetime_get_tm_from_str (const gchar *str); +struct tm *gtk_form_field_datetime_get_tm_from_str (const gchar *str, const gchar *format); gchar *gtk_form_field_datetime_get_str_from_tm (struct tm *datetime, const gchar *format); diff --git a/src/form.c b/src/form.c index 9f67e5e..9370a18 100644 --- a/src/form.c +++ b/src/form.c @@ -216,27 +216,27 @@ GtkForm widget = NULL; type = xmlGetProp (cur, (const xmlChar *)"type"); - if (strcmp (type, "checkbox") == 0) + if (g_strcmp0 (type, "checkbox") == 0) { widget = gtk_form_widget_check_new (); } - else if (strcmp (type, "combobox") == 0) + else if (g_strcmp0 (type, "combobox") == 0) { widget = gtk_form_widget_combo_box_new (); } - else if (strcmp (type, "entry") == 0) + else if (g_strcmp0 (type, "entry") == 0) { widget = gtk_form_widget_entry_new (); } - else if (strcmp (type, "label") == 0) + else if (g_strcmp0 (type, "label") == 0) { widget = gtk_form_widget_label_new (); } - else if (strcmp (type, "spin") == 0) + else if (g_strcmp0 (type, "spin") == 0) { widget = gtk_form_widget_spin_new (); } - else if (strcmp (type, "textview") == 0) + else if (g_strcmp0 (type, "textview") == 0) { widget = gtk_form_widget_textview_new (); } @@ -279,23 +279,23 @@ GtkForm field = NULL; type = xmlGetProp (node_widget, (const xmlChar *)"type"); - if (strcmp (type, "boolean") == 0) + if (g_strcmp0 (type, "boolean") == 0) { field = gtk_form_field_boolean_new (); } - else if (strcmp (type, "datetime") == 0) + else if (g_strcmp0 (type, "datetime") == 0) { field = gtk_form_field_datetime_new (); } - else if (strcmp (type, "float") == 0) + else if (g_strcmp0 (type, "float") == 0) { field = gtk_form_field_float_new (); } - else if (strcmp (type, "integer") == 0) + else if (g_strcmp0 (type, "integer") == 0) { field = gtk_form_field_integer_new (); } - else if (strcmp (type, "text") == 0) + else if (g_strcmp0 (type, "text") == 0) { field = gtk_form_field_text_new (); } @@ -324,16 +324,16 @@ GtkForm } else if (xmlStrcmp (node_field->name, (const xmlChar *)"default") == 0) { - if (strcmp (type, "boolean") == 0) + if (g_strcmp0 (type, "boolean") == 0) { gboolean value = gtk_form_field_boolean_str_to_boolean (prop); g_object_set (G_OBJECT (field), "default", value, NULL); } - else if (strcmp (type, "datetime") == 0) + else if (g_strcmp0 (type, "datetime") == 0) { struct tm *datetime; - if (strcmp (prop, "now") == 0) + if (g_strcmp0 (prop, "now") == 0) { time_t time_now; @@ -343,24 +343,24 @@ GtkForm } else { - datetime = gtk_form_field_datetime_get_tm_from_str (prop); + datetime = gtk_form_field_datetime_get_tm_from_str (prop, "%Y-%m-%d %H:%M:%S"); if (datetime != NULL) { g_object_set (G_OBJECT (field), "default", datetime, NULL); } } } - else if (strcmp (type, "float") == 0) + else if (g_strcmp0 (type, "float") == 0) { gfloat value = g_strtod (prop, NULL); g_object_set (G_OBJECT (field), "default", value, NULL); } - else if (strcmp (type, "integer") == 0) + else if (g_strcmp0 (type, "integer") == 0) { gint value = strtol (prop, NULL, 10); g_object_set (G_OBJECT (field), "default", value, NULL); } - else if (strcmp (type, "text") == 0) + else if (g_strcmp0 (type, "text") == 0) { g_object_set (G_OBJECT (field), "default", prop, NULL); } @@ -377,6 +377,29 @@ GtkForm gtk_form_key_add_field (priv->key, field); } } + else if (xmlStrcmp (node_field->name, (const xmlChar *)"datetime-type") == 0) + { + if (g_strcmp0 (type, "datetime") == 0) + { + if (g_strcmp0 (prop, "date")) + { + g_object_set (G_OBJECT (field), "type", GTK_FORM_FIELD_DATETIME_TYPE_DATE, NULL); + + } + else if (g_strcmp0 (prop, "time")) + { + g_object_set (G_OBJECT (field), "type", GTK_FORM_FIELD_DATETIME_TYPE_TIME, NULL); + + } + } + } + else if (xmlStrcmp (node_field->name, (const xmlChar *)"display-format") == 0) + { + if (g_strcmp0 (type, "datetime") == 0) + { + g_object_set (G_OBJECT (field), "display-format", prop, NULL); + } + } node_field = node_field->next; } @@ -623,7 +646,7 @@ GtkFormField while (fields != NULL) { name = gtk_form_field_get_field_name ((GtkFormField *)fields->data); - if (strcmp (name, field_name) == 0) + if (g_strcmp0 (name, field_name) == 0) { field = (GtkFormField *)fields->data; break; @@ -660,7 +683,7 @@ GtkFormWidget { widget = gtk_form_field_get_form_widget ((GtkFormField *)fields->data); - if (strcmp (gtk_form_widget_get_widget_name (widget), widget_name) == 0) + if (g_strcmp0 (gtk_form_widget_get_widget_name (widget), widget_name) == 0) { widget_ret = widget; break; @@ -906,7 +929,7 @@ gtk_form_check (GtkForm *form, gboolean with_key, GtkFormWidget **form_widget, * @form: * * Returns: TRUE if the values in the form are changed since last calling to - * gtk_form_clear() or gtk_form_fill_from_datamodel(). + * gtk_form_clear(), gtk_form_fill_from_datamodel() or gtk_form_set_as_origin(). */ gboolean gtk_form_is_changed (GtkForm *form) @@ -1095,7 +1118,7 @@ gchar field_name = gtk_form_field_get_field_name (field); - if (field_name != NULL && strcmp (field_name, "") != 0) + if (field_name != NULL && g_strcmp0 (field_name, "") != 0) { switch (type) { @@ -1161,7 +1184,7 @@ gchar { where = gtk_form_key_get_sql (priv->key); if ((type == GTK_FORM_SQL_SELECT || type == GTK_FORM_SQL_UPDATE || type == GTK_FORM_SQL_DELETE) - && where != NULL && strcmp (where, "") != 0) + && where != NULL && g_strcmp0 (where, "") != 0) { sql = g_strconcat (sql, where, NULL); } diff --git a/test/main.c b/test/main.c index ebd0c87..765d04d 100644 --- a/test/main.c +++ b/test/main.c @@ -341,7 +341,9 @@ main (int argc, char **argv) g_object_set (fdatetime, "field", "now", "form-widget", wlabel, + "type", GTK_FORM_FIELD_DATETIME_TYPE_DATE, "default", now, + "display-format", "%d/%m/%Y", NULL); gtk_form_add_field (form, fdatetime); diff --git a/test/test_db.xml b/test/test_db.xml index c62baa9..25f3e59 100644 --- a/test/test_db.xml +++ b/test/test_db.xml @@ -41,6 +41,7 @@ + %d/%m/%Y