# HG changeset patch
# Node ID 0ad343253277
# Parent  c8a4853205e3
diff --git a/libpurple/connection.c b/libpurple/connection.c
--- a/libpurple/connection.c
+++ b/libpurple/connection.c
@@ -178,13 +178,16 @@
 
 	if(priv->state == PURPLE_CONNECTION_STATE_CONNECTED) {
 		PurplePresence *presence;
+		GDateTime *timestamp = NULL;
 		gboolean emit_online = FALSE;
 		gpointer handle = NULL;
 
 		presence = purple_account_get_presence(priv->account);
 
 		/* Set the time the account came online */
-		purple_presence_set_login_time(presence, time(NULL));
+		timestamp = g_date_time_new_now_utc();
+		purple_presence_set_login_time(presence, timestamp);
+		g_date_time_unref(timestamp);
 
 		if(ops != NULL && ops->connected != NULL) {
 			ops->connected(connection);
diff --git a/libpurple/protocols.h b/libpurple/protocols.h
--- a/libpurple/protocols.h
+++ b/libpurple/protocols.h
@@ -54,18 +54,6 @@
                                       time_t idle_time);
 
 /**
- * purple_protocol_got_account_login_time:
- * @account:    The account the user is on.
- * @login_time: The user's log-in time.
- *
- * Notifies Purple of our account's log-in time.
- *
- * This is meant to be called from protocols.
- */
-void purple_protocol_got_account_login_time(PurpleAccount *account,
-                                            time_t login_time);
-
-/**
  * purple_protocol_got_account_status:
  * @account: The account the user is on.
  * @status_id: The status ID.
@@ -126,19 +114,6 @@
                                    gboolean idle, time_t idle_time);
 
 /**
- * purple_protocol_got_user_login_time:
- * @account:    The account the user is on.
- * @name:       The name of the buddy.
- * @login_time: The user's log-in time.
- *
- * Notifies Purple of a buddy's log-in time.
- *
- * This is meant to be called from protocols.
- */
-void purple_protocol_got_user_login_time(PurpleAccount *account,
-                                         const char *name, time_t login_time);
-
-/**
  * purple_protocol_got_user_status:
  * @account: The account the user is on.
  * @name: The name of the buddy.
diff --git a/libpurple/protocols.c b/libpurple/protocols.c
--- a/libpurple/protocols.c
+++ b/libpurple/protocols.c
@@ -53,22 +53,6 @@
 }
 
 void
-purple_protocol_got_account_login_time(PurpleAccount *account, time_t login_time)
-{
-	PurplePresence *presence;
-
-	g_return_if_fail(account != NULL);
-	g_return_if_fail(purple_account_is_connected(account));
-
-	if (login_time == 0)
-		login_time = time(NULL);
-
-	presence = purple_account_get_presence(account);
-
-	purple_presence_set_login_time(presence, login_time);
-}
-
-void
 purple_protocol_got_account_status_with_attributes(PurpleAccount *account,
                                                    const gchar *status_id,
                                                    GHashTable *attributes)
@@ -137,36 +121,6 @@
 }
 
 void
-purple_protocol_got_user_login_time(PurpleAccount *account, const char *name,
-		time_t login_time)
-{
-	GSList *list;
-	PurplePresence *presence;
-
-	g_return_if_fail(account != NULL);
-	g_return_if_fail(name    != NULL);
-
-	if ((list = purple_blist_find_buddies(account, name)) == NULL)
-		return;
-
-	if (login_time == 0)
-		login_time = time(NULL);
-
-	while (list) {
-		PurpleBuddy *buddy = list->data;
-		presence = purple_buddy_get_presence(buddy);
-		list = g_slist_delete_link(list, list);
-
-		if (purple_presence_get_login_time(presence) != login_time)
-		{
-			purple_presence_set_login_time(presence, login_time);
-
-			purple_signal_emit(purple_blist_get_handle(), "buddy-got-login-time", buddy);
-		}
-	}
-}
-
-void
 purple_protocol_got_user_status_with_attributes(PurpleAccount *account,
                                                 const gchar *name,
                                                 const gchar *status_id,
diff --git a/libpurple/purplepresence.h b/libpurple/purplepresence.h
--- a/libpurple/purplepresence.h
+++ b/libpurple/purplepresence.h
@@ -113,11 +113,11 @@
 /**
  * purple_presence_set_login_time:
  * @presence: The #PurplePresence instance.
- * @login_time: The login time.
+ * @login_time: (transfer none): The login time.
  *
  * Sets the login time on a presence.
  */
-void purple_presence_set_login_time(PurplePresence *presence, time_t login_time);
+void purple_presence_set_login_time(PurplePresence *presence, GDateTime *login_time);
 
 /**
  * purple_presence_get_statuses:
@@ -227,9 +227,9 @@
  *
  * Gets the login time of @presence.
  *
- * Returns: The login time of @presence.
+ * Returns: (transfer none): The login time of @presence.
  */
-time_t purple_presence_get_login_time(PurplePresence *presence);
+GDateTime *purple_presence_get_login_time(PurplePresence *presence);
 
 /**
  * purple_presence_compare:
diff --git a/libpurple/purplepresence.c b/libpurple/purplepresence.c
--- a/libpurple/purplepresence.c
+++ b/libpurple/purplepresence.c
@@ -30,7 +30,7 @@
 typedef struct {
 	gboolean idle;
 	time_t idle_time;
-	time_t login_time;
+	GDateTime *login_time;
 
 	GHashTable *status_table;
 
@@ -89,13 +89,7 @@
 #endif
 			break;
 		case PROP_LOGIN_TIME:
-#if SIZEOF_TIME_T == 4
-			purple_presence_set_login_time(presence, g_value_get_int(value));
-#elif SIZEOF_TIME_T == 8
-			purple_presence_set_login_time(presence, g_value_get_int64(value));
-#else
-#error Unknown size of time_t
-#endif
+			purple_presence_set_login_time(presence, g_value_get_boxed(value));
 			break;
 		case PROP_ACTIVE_STATUS:
 			purple_presence_set_active_status(presence,
@@ -127,13 +121,7 @@
 #endif
 			break;
 		case PROP_LOGIN_TIME:
-#if SIZEOF_TIME_T == 4
-			g_value_set_int(value, purple_presence_get_login_time(presence));
-#elif SIZEOF_TIME_T == 8
-			g_value_set_int64(value, purple_presence_get_login_time(presence));
-#else
-#error Unknown size of time_t
-#endif
+			g_value_set_boxed(value, purple_presence_get_login_time(presence));
 			break;
 		case PROP_ACTIVE_STATUS:
 			g_value_set_object(value, purple_presence_get_active_status(presence));
@@ -212,24 +200,11 @@
 	 *
 	 * The login-time of the presence.
 	 */
-	properties[PROP_LOGIN_TIME] =
-#if SIZEOF_TIME_T == 4
-		g_param_spec_int
-#elif SIZEOF_TIME_T == 8
-		g_param_spec_int64
-#else
-#error Unknown size of time_t
-#endif
-				("login-time", "Login time",
-				"The login time of the presence.",
-#if SIZEOF_TIME_T == 4
-				G_MININT, G_MAXINT, 0,
-#elif SIZEOF_TIME_T == 8
-				G_MININT64, G_MAXINT64, 0,
-#else
-#error Unknown size of time_t
-#endif
-				G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+	properties[PROP_LOGIN_TIME] = g_param_spec_boxed(
+		"login-time", "Login time",
+		"The login time of the presence.",
+		G_TYPE_DATE_TIME,
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
 	/**
 	 * PurplePresence:active-status:
@@ -316,21 +291,31 @@
 }
 
 void
-purple_presence_set_login_time(PurplePresence *presence, time_t login_time) {
+purple_presence_set_login_time(PurplePresence *presence, GDateTime *login_time)
+{
 	PurplePresencePrivate *priv = NULL;
 
 	g_return_if_fail(PURPLE_IS_PRESENCE(presence));
 
 	priv = purple_presence_get_instance_private(presence);
 
-	if(priv->login_time == login_time) {
-		return;
+	if(priv->login_time != NULL && login_time != NULL) {
+		if(g_date_time_equal(priv->login_time, login_time)) {
+			return;
+		}
 	}
 
-	priv->login_time = login_time;
+	if(priv->login_time != NULL) {
+		g_date_time_unref(priv->login_time);
+	}
 
-	g_object_notify_by_pspec(G_OBJECT(presence),
-			properties[PROP_LOGIN_TIME]);
+	if(login_time != NULL) {
+		priv->login_time = g_date_time_ref(login_time);
+	} else {
+		priv->login_time = NULL;
+	}
+
+	g_object_notify_by_pspec(G_OBJECT(presence), properties[PROP_LOGIN_TIME]);
 }
 
 GList *
@@ -481,7 +466,7 @@
 	return priv->idle_time;
 }
 
-time_t
+GDateTime *
 purple_presence_get_login_time(PurplePresence *presence) {
 	PurplePresencePrivate *priv = NULL;
 
@@ -489,7 +474,7 @@
 
 	priv = purple_presence_get_instance_private(presence);
 
-	return purple_presence_is_online(presence) ? priv->login_time : 0;
+	return priv->login_time;
 }
 
 gint
diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c
--- a/pidgin/gtkblist.c
+++ b/pidgin/gtkblist.c
@@ -2251,10 +2251,11 @@
 		PurpleBuddy *b;
 		PurplePresence *presence;
 		PurpleNotifyUserInfo *user_info;
+		GDateTime *signon = NULL;
 		GList *connections;
 		char *tmp;
 		gchar *alias;
-		time_t idle_secs, signon;
+		time_t idle_secs;
 
 		if (PURPLE_IS_META_CONTACT(node))
 		{
@@ -2306,27 +2307,31 @@
 
 		/* Logged In */
 		signon = purple_presence_get_login_time(presence);
-		if (full && PURPLE_BUDDY_IS_ONLINE(b) && signon > 0)
+		if (full && PURPLE_BUDDY_IS_ONLINE(b) && signon != NULL)
 		{
-			if (signon > time(NULL)) {
+			GDateTime *now = g_date_time_new_now_utc();
+			GTimeSpan duration = g_date_time_compare(now, signon);
+
+			if(duration < 0) {
 				/*
 				 * They signed on in the future?!  Our local clock
 				 * must be wrong, show the actual date instead of
 				 * "4 days", etc.
 				 */
-				GDateTime *dt = NULL, *local = NULL;
-
-				dt = g_date_time_new_from_unix_utc(signon);
-				local = g_date_time_to_local(dt);
-				g_date_time_unref(dt);
+				GDateTime *local = NULL;
+
+				local = g_date_time_to_local(signon);
 
 				tmp = g_date_time_format(local, _("%x %X"));
 				g_date_time_unref(local);
 			} else {
-				tmp = purple_str_seconds_to_string(time(NULL) - signon);
+				tmp = purple_str_seconds_to_string(duration / G_TIME_SPAN_SECOND);
 			}
+
 			purple_notify_user_info_add_pair_plaintext(user_info, _("Logged In"), tmp);
 			g_free(tmp);
+
+			g_date_time_unref(now);
 		}
 
 		/* Idle */
