diff --git a/libempathy-gtk/empathy-contact-widget.c b/libempathy-gtk/empathy-contact-widget.c
index 26713eb..d70fe3f 100644
--- a/libempathy-gtk/empathy-contact-widget.c
+++ b/libempathy-gtk/empathy-contact-widget.c
@@ -138,6 +138,8 @@ typedef struct
   GtkTreeIter found_iter;
 } FindName;
 
+typedef GtkWidget * (* InfoFieldWidgetBuilder) (TpContactInfoField *field);
+
 enum
 {
   COL_NAME,
@@ -238,22 +240,92 @@ contact_widget_details_changed_cb (GtkEntry *entry,
   field->field_value = g_strdupv ((GStrv) strv);
 }
 
+static void
+contact_widget_bday_changed_cb (GtkCalendar *calendar,
+    TpContactInfoField *field)
+{
+  guint year, month, day;
+  GDate *date;
+  gchar tmp[255];
+  const gchar *strv[] = { NULL, NULL };
+
+  gtk_calendar_get_date (calendar, &year, &month, &day);
+  date = g_date_new_dmy (day, month+1, year);
+
+  gtk_calendar_clear_marks (calendar);
+  gtk_calendar_mark_day (calendar, g_date_get_day (date));
+
+  g_date_strftime (tmp, sizeof (tmp), EMPATHY_DATE_FORMAT_DISPLAY_SHORT, date);
+  strv[0] = tmp;
+  if (field->field_value != NULL)
+    g_strfreev (field->field_value);
+  field->field_value = g_strdupv ((GStrv) strv);
+
+  g_date_free (date);
+}
+
 static void contact_widget_details_notify_cb (EmpathyContactWidget *information);
 
+static GtkWidget *
+contact_widget_entry_field_build (TpContactInfoField *field)
+{
+  GtkWidget *w;
+  w = gtk_entry_new ();
+  gtk_entry_set_text (GTK_ENTRY (w),
+      field->field_value[0] ? field->field_value[0] : "");
+  gtk_widget_show (w);
+
+  g_signal_connect (w, "changed",
+      G_CALLBACK (contact_widget_details_changed_cb), field);
+  return w;
+}
+
+static GtkWidget *
+contact_widget_calendar_field_build (TpContactInfoField *field)
+{
+  GtkWidget *w;
+  GDate date;
+
+  w = gtk_calendar_new ();
+  if (field->field_value[0])
+    {
+      g_date_set_parse (&date, field->field_value[0]);
+      if (g_date_valid (&date))
+        {
+          gtk_calendar_select_day (GTK_CALENDAR (w),
+              g_date_get_day (&date));
+          gtk_calendar_select_month (GTK_CALENDAR (w),
+              g_date_get_month (&date) - 1, g_date_get_year (&date));
+          gtk_calendar_mark_day (GTK_CALENDAR (w),
+              g_date_get_day (&date));
+        }
+    }
+  gtk_widget_show (w);
+
+  g_signal_connect (w, "day-selected-double-click",
+    G_CALLBACK (contact_widget_bday_changed_cb), field);
+  g_signal_connect (w, "month-changed",
+    G_CALLBACK (contact_widget_bday_changed_cb), field);
+
+  return w;
+}
+
+
 typedef struct
 {
   const gchar *field_name;
   const gchar *title;
   gboolean linkify;
+  InfoFieldWidgetBuilder widget_builder;
 } InfoFieldData;
 
 static InfoFieldData info_field_datas[] =
 {
-  { "fn",    N_("Full name:"),      FALSE },
-  { "tel",   N_("Phone number:"),   FALSE },
-  { "email", N_("E-mail address:"), TRUE },
-  { "url",   N_("Website:"),        TRUE },
-  { "bday",  N_("Birthday:"),       FALSE },
+  { "fn",    N_("Full name:"),      FALSE, contact_widget_entry_field_build },
+  { "tel",   N_("Phone number:"),   FALSE, contact_widget_entry_field_build },
+  { "email", N_("E-mail address:"), TRUE,  contact_widget_entry_field_build },
+  { "url",   N_("Website:"),        TRUE,  contact_widget_entry_field_build },
+  { "bday",  N_("Birthday:"),       FALSE, contact_widget_calendar_field_build },
   { NULL, NULL }
 };
 
@@ -415,15 +487,9 @@ contact_widget_details_update_edit (EmpathyContactWidget *information)
       gtk_widget_show (w);
 
       /* Add Value */
-      w = gtk_entry_new ();
-      gtk_entry_set_text (GTK_ENTRY (w),
-          field->field_value[0] ? field->field_value[0] : "");
+      w = field_data->widget_builder (field);
       gtk_table_attach_defaults (GTK_TABLE (information->table_details),
           w, 1, 2, n_rows, n_rows + 1);
-      gtk_widget_show (w);
-
-      g_signal_connect (w, "changed",
-        G_CALLBACK (contact_widget_details_changed_cb), field);
 
       n_rows++;
     }
