# HG changeset patch
# Node ID 039eacbdd62e
# Parent  382ecbbf0080
diff --git a/finch/gntblist.c b/finch/gntblist.c
--- a/finch/gntblist.c
+++ b/finch/gntblist.c
@@ -1581,9 +1581,18 @@
 	if (purple_prefs_get_bool("/finch/blist/idletime")) {
 		PurplePresence *pre = purple_buddy_get_presence(buddy);
 		if (purple_presence_is_idle(pre)) {
-			time_t idle = purple_presence_get_idle_time(pre);
-			if (idle > 0) {
-				char *st = purple_str_seconds_to_string(time(NULL) - idle);
+			GDateTime *idle = purple_presence_get_idle_time(pre);
+
+			if(idle != NULL) {
+				GDateTime *now = NULL;
+				GTimeSpan since = 0;
+				char *st = NULL;
+
+				now = g_date_time_new_now_local();
+				since = g_date_time_difference(now, idle);
+				g_date_time_unref(now);
+
+				st = purple_str_seconds_to_string(since / G_TIME_SPAN_SECOND);
 				purple_notify_user_info_add_pair_plaintext(user_info, _("Idle"), st);
 				g_free(st);
 			}
diff --git a/libpurple/idle.c b/libpurple/idle.c
--- a/libpurple/idle.c
+++ b/libpurple/idle.c
@@ -61,6 +61,8 @@
 {
 	PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
 	PurplePresence *presence;
+	GDateTime *idle_since = NULL;
+	GDateTime *now = NULL;
 
 	presence = purple_account_get_presence(account);
 
@@ -72,7 +74,14 @@
 	purple_debug_info("idle", "Setting %s idle %d seconds\n",
 	                  purple_contact_info_get_username(info),
 	                  time_idle);
-	purple_presence_set_idle(presence, TRUE, time(NULL) - time_idle);
+
+	now = g_date_time_new_now_local();
+	idle_since = g_date_time_add_seconds(now, -1 * time_idle);
+	g_date_time_unref(now);
+
+	purple_presence_set_idle(presence, TRUE, idle_since);
+	g_date_time_unref(idle_since);
+
 	idled_accts = g_list_prepend(idled_accts, account);
 }
 
diff --git a/libpurple/plugins/idle/idle.c b/libpurple/plugins/idle/idle.c
--- a/libpurple/plugins/idle/idle.c
+++ b/libpurple/plugins/idle/idle.c
@@ -60,7 +60,8 @@
 	PurpleConnection *gc = purple_account_get_connection(acct);
 	PurpleContactInfo *info = PURPLE_CONTACT_INFO(acct);
 	PurplePresence *presence = purple_account_get_presence(acct);
-	time_t t;
+	GDateTime *idle_since = NULL;
+	gboolean idle = FALSE;
 
 	if (!gc)
 		return;
@@ -68,13 +69,17 @@
 	purple_debug_info("idle", "setting idle time for %s to %d\n",
 	                  purple_contact_info_get_username(info), mins_idle);
 
-	if (mins_idle) {
-		t = time(NULL) - (60 * mins_idle); /* subtract seconds idle from current time */
-	} else {
-		t = 0; /* time idle is irrelevant */
+	idle = mins_idle > 0;
+
+	if(idle) {
+		GDateTime *now = g_date_time_new_now_local();
+		idle_since = g_date_time_add_minutes(now, -1 * mins_idle);
+		g_date_time_unref(now);
 	}
 
-	purple_presence_set_idle(presence, mins_idle ? TRUE : FALSE, t);
+	purple_presence_set_idle(presence, idle, idle_since);
+
+	g_clear_pointer(&idle_since, g_date_time_unref);
 }
 
 static void
diff --git a/libpurple/protocols.c b/libpurple/protocols.c
--- a/libpurple/protocols.c
+++ b/libpurple/protocols.c
@@ -47,6 +47,7 @@
 {
 	PurplePresence *presence;
 	GSList *list;
+	GDateTime *idle_date_time = NULL;
 
 	g_return_if_fail(account != NULL);
 	g_return_if_fail(name    != NULL);
@@ -55,11 +56,13 @@
 	if ((list = purple_blist_find_buddies(account, name)) == NULL)
 		return;
 
+	idle_date_time = g_date_time_new_from_unix_local(idle_time);
 	while (list) {
 		presence = purple_buddy_get_presence(list->data);
 		list = g_slist_delete_link(list, list);
-		purple_presence_set_idle(presence, idle, idle_time);
+		purple_presence_set_idle(presence, idle, idle_date_time);
 	}
+	g_date_time_unref(idle_date_time);
 }
 
 void
diff --git a/libpurple/protocols/demo/purpledemocontacts.c b/libpurple/protocols/demo/purpledemocontacts.c
--- a/libpurple/protocols/demo/purpledemocontacts.c
+++ b/libpurple/protocols/demo/purpledemocontacts.c
@@ -63,15 +63,20 @@
 		}
 
 		if(json_object_has_member(status_object, "idle")) {
-			gint idle_seconds = 0;
-			time_t now;
+			PurplePresence *presence = NULL;
+			GDateTime *now = NULL;
+			GDateTime *idle_since = NULL;
+			gint idle_minutes = 0;
 
-			idle_seconds = json_object_get_int_member(status_object, "idle");
-			now = time(NULL);
+			idle_minutes = json_object_get_int_member(status_object, "idle");
+			now = g_date_time_new_now_local();
+			idle_since = g_date_time_add_minutes(now, -1 * idle_minutes);
 
-			purple_protocol_got_user_idle(account,
-			                              purple_buddy_get_name(buddy), TRUE,
-			                              now - idle_seconds);
+			presence = purple_buddy_get_presence(buddy);
+			purple_presence_set_idle(presence, TRUE, idle_since);
+
+			g_date_time_unref(idle_since);
+			g_date_time_unref(now);
 		}
 	}
 }
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -941,8 +941,14 @@
 		disconnected and the reconnects while being idle. I don't think it makes
 		sense to do this when registering a new account... */
 	presence = purple_account_get_presence(account);
-	if (purple_presence_is_idle(presence))
-		js->idle = purple_presence_get_idle_time(presence);
+	if (purple_presence_is_idle(presence)) {
+		GDateTime *idle = purple_presence_get_idle_time(presence);
+
+		js->idle = 0;
+		if(idle != NULL) {
+			js->idle = g_date_time_to_unix(idle);
+		}
+	}
 
 	return js;
 }
diff --git a/libpurple/protocols/jabber/presence.c b/libpurple/protocols/jabber/presence.c
--- a/libpurple/protocols/jabber/presence.c
+++ b/libpurple/protocols/jabber/presence.c
@@ -117,8 +117,15 @@
 	} else {
 		jbr = jabber_buddy_track_resource(jb, js->user->resource, priority,
 				state, msg);
-		jbr->idle = purple_presence_is_idle(presence) ?
-				purple_presence_get_idle_time(presence) : 0;
+
+		jbr->idle = 0;
+		if(purple_presence_is_idle(presence)) {
+			GDateTime *idle_since = purple_presence_get_idle_time(presence);
+
+			if(idle_since != NULL) {
+				jbr->idle = g_date_time_to_unix(idle_since);
+			}
+		}
 	}
 
 	/*
diff --git a/libpurple/purpleaccountpresence.c b/libpurple/purpleaccountpresence.c
--- a/libpurple/purpleaccountpresence.c
+++ b/libpurple/purpleaccountpresence.c
@@ -62,8 +62,6 @@
 	PurpleConnection *gc = NULL;
 	PurpleProtocol *protocol = NULL;
 	gboolean idle = purple_presence_is_idle(presence);
-	time_t idle_time = purple_presence_get_idle_time(presence);
-	time_t current_time = time(NULL);
 
 	gc = purple_account_get_connection(account_presence->account);
 
@@ -72,7 +70,24 @@
 	}
 
 	if(PURPLE_IS_PROTOCOL_SERVER(protocol)) {
-		purple_protocol_server_set_idle(PURPLE_PROTOCOL_SERVER(protocol), gc, (idle ? (current_time - idle_time) : 0));
+		gint idle_time = 0;
+
+		if(idle) {
+			GDateTime *idle_since = purple_presence_get_idle_time(presence);
+
+			if(idle_since != NULL) {
+				GDateTime *now = g_date_time_new_now_local();
+
+				idle_time = g_date_time_difference(now, idle_since);
+				idle_time = idle_time / G_TIME_SPAN_SECOND;
+
+				g_date_time_unref(now);
+				g_date_time_unref(idle_since);
+			}
+		}
+
+		purple_protocol_server_set_idle(PURPLE_PROTOCOL_SERVER(protocol), gc,
+		                                idle_time);
 	}
 }
 
diff --git a/libpurple/purplebuddypresence.c b/libpurple/purplebuddypresence.c
--- a/libpurple/purplebuddypresence.c
+++ b/libpurple/purplebuddypresence.c
@@ -87,7 +87,8 @@
 {
 	PurplePresence *presence1 = PURPLE_PRESENCE(buddy_presence1);
 	PurplePresence *presence2 = PURPLE_PRESENCE(buddy_presence2);
-	time_t idle_time_1, idle_time_2;
+	GDateTime *now = NULL;
+	GTimeSpan idle1, idle2;
 	int score1 = 0, score2 = 0;
 	int idle_time_score = purple_prefs_get_int("/purple/status/scores/idle_time");
 
@@ -111,13 +112,18 @@
 	/* Compute the score of the second set of statuses. */
 	score2 = purple_buddy_presence_compute_score(buddy_presence2);
 
-	idle_time_1 = time(NULL) - purple_presence_get_idle_time(presence1);
-	idle_time_2 = time(NULL) - purple_presence_get_idle_time(presence2);
+	now = g_date_time_new_now_local();
+	idle1 = g_date_time_difference(now,
+	                               purple_presence_get_idle_time(presence1));
+	idle2 = g_date_time_difference(now,
+	                               purple_presence_get_idle_time(presence2));
+	g_date_time_unref(now);
 
-	if (idle_time_1 > idle_time_2)
+	if (idle1 > idle2) {
 		score1 += idle_time_score;
-	else if (idle_time_1 < idle_time_2)
+	} else if (idle1 < idle2) {
 		score2 += idle_time_score;
+	}
 
 	if (score1 < score2)
 		return 1;
diff --git a/libpurple/purplepresence.h b/libpurple/purplepresence.h
--- a/libpurple/purplepresence.h
+++ b/libpurple/purplepresence.h
@@ -116,13 +116,13 @@
  * purple_presence_set_idle:
  * @presence: The #PurplePresence instance.
  * @idle: The idle state.
- * @idle_time: The idle time, if @idle is %TRUE.  This is the time at which the
- *             user became idle, in seconds since the epoch.  If this value is
- *             unknown then 0 should be used.
+ * @idle_time: (transfer none): The idle time, if @idle is %TRUE.  This is the
+ *             time at which the user became idle. If this value is unknown
+ *             then %NULL should be used.
  *
  * Sets the idle state and time of @presence.
  */
-void purple_presence_set_idle(PurplePresence *presence, gboolean idle, time_t idle_time);
+void purple_presence_set_idle(PurplePresence *presence, gboolean idle, GDateTime *idle_time);
 
 /**
  * purple_presence_set_login_time:
@@ -233,7 +233,7 @@
  *
  * Returns: The idle time of @presence.
  */
-time_t purple_presence_get_idle_time(PurplePresence *presence);
+GDateTime *purple_presence_get_idle_time(PurplePresence *presence);
 
 /**
  * purple_presence_get_login_time:
diff --git a/libpurple/purplepresence.c b/libpurple/purplepresence.c
--- a/libpurple/purplepresence.c
+++ b/libpurple/purplepresence.c
@@ -24,14 +24,13 @@
 
 #include "purplepresence.h"
 
-#include "internal.h"
 #include "debug.h"
 #include "purpleenums.h"
 #include "purpleprivate.h"
 
 typedef struct {
 	gboolean idle;
-	time_t idle_time;
+	GDateTime *idle_time;
 	GDateTime *login_time;
 
 	GHashTable *status_table;
@@ -86,16 +85,11 @@
 
 	switch (param_id) {
 		case PROP_IDLE:
-			purple_presence_set_idle(presence, g_value_get_boolean(value), 0);
+			purple_presence_set_idle(presence, g_value_get_boolean(value),
+			                         NULL);
 			break;
 		case PROP_IDLE_TIME:
-#if SIZEOF_TIME_T == 4
-			purple_presence_set_idle(presence, TRUE, g_value_get_int(value));
-#elif SIZEOF_TIME_T == 8
-			purple_presence_set_idle(presence, TRUE, g_value_get_int64(value));
-#else
-#error Unknown size of time_t
-#endif
+			purple_presence_set_idle(presence, TRUE, g_value_get_boxed(value));
 			break;
 		case PROP_LOGIN_TIME:
 			purple_presence_set_login_time(presence, g_value_get_boxed(value));
@@ -121,13 +115,7 @@
 			g_value_set_boolean(value, purple_presence_is_idle(presence));
 			break;
 		case PROP_IDLE_TIME:
-#if SIZEOF_TIME_T == 4
-			g_value_set_int(value, purple_presence_get_idle_time(presence));
-#elif SIZEOF_TIME_T == 8
-			g_value_set_int64(value, purple_presence_get_idle_time(presence));
-#else
-#error Unknown size of time_t
-#endif
+			g_value_set_boxed(value, purple_presence_get_idle_time(presence));
 			break;
 		case PROP_LOGIN_TIME:
 			g_value_set_boxed(value, purple_presence_get_login_time(presence));
@@ -191,23 +179,10 @@
 	 *
 	 * The time when the presence went idle.
 	 */
-	properties[PROP_IDLE_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
-				("idle-time", "Idle time",
+	properties[PROP_IDLE_TIME] = g_param_spec_boxed(
+				"idle-time", "Idle time",
 				"The idle 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_TYPE_DATE_TIME,
 				G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
 	/**
@@ -306,7 +281,7 @@
 
 void
 purple_presence_set_idle(PurplePresence *presence, gboolean idle,
-                         time_t idle_time)
+                         GDateTime *idle_time)
 {
 	PurplePresencePrivate *priv = NULL;
 	PurplePresenceClass *klass = NULL;
@@ -324,7 +299,11 @@
 
 	old_idle = priv->idle;
 	priv->idle = idle;
-	priv->idle_time = (idle ? idle_time : 0);
+
+	g_clear_pointer(&priv->idle_time, g_date_time_unref);
+	if(idle && idle_time != NULL) {
+		priv->idle_time = g_date_time_ref(idle_time);
+	}
 
 	obj = G_OBJECT(presence);
 	g_object_freeze_notify(obj);
@@ -502,11 +481,11 @@
 	return priv->idle;
 }
 
-time_t
+GDateTime *
 purple_presence_get_idle_time(PurplePresence *presence) {
 	PurplePresencePrivate *priv = NULL;
 
-	g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), 0);
+	g_return_val_if_fail(PURPLE_IS_PRESENCE(presence), NULL);
 
 	priv = purple_presence_get_instance_private(presence);
 
@@ -526,8 +505,11 @@
 
 gint
 purple_presence_compare(PurplePresence *presence1, PurplePresence *presence2) {
-	time_t idle_time_1;
-	time_t idle_time_2;
+	GDateTime *idle1 = NULL;
+	GDateTime *idle2 = NULL;
+	GDateTime *now = NULL;
+	GTimeSpan diff1 = 0;
+	GTimeSpan diff2 = 0;
 
 	if(presence1 == presence2) {
 		return 0;
@@ -547,12 +529,27 @@
 		return 1;
 	}
 
-	idle_time_1 = time(NULL) - purple_presence_get_idle_time(presence1);
-	idle_time_2 = time(NULL) - purple_presence_get_idle_time(presence2);
+	idle1 = purple_presence_get_idle_time(presence1);
+	idle2 = purple_presence_get_idle_time(presence2);
+
+	if(idle1 == NULL && idle2 == NULL) {
+		return 0;
+	} else if(idle1 == NULL && idle2 != NULL) {
+		return -1;
+	} else if(idle1 != NULL && idle2 == NULL) {
+		return 1;
+	}
 
-	if(idle_time_1 > idle_time_2) {
+	now = g_date_time_new_now_local();
+	diff1 = g_date_time_difference(now,
+	                               purple_presence_get_idle_time(presence1));
+	diff2 = g_date_time_difference(now,
+	                               purple_presence_get_idle_time(presence2));
+	g_date_time_unref(now);
+
+	if(diff1 > diff2) {
 		return 1;
-	} else if (idle_time_1 < idle_time_2) {
+	} else if (diff1 < diff2) {
 		return -1;
 	}
 
