[gitg] Added date class



commit 23bc9feeb7b12a1d6cba2794806fd0297d244a00
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Fri Jul 5 19:47:30 2013 +0200

    Added date class

 libgitg/Makefile.am            |    3 +-
 libgitg/gitg-date.vala         |  313 ++++++++++++++++++++++++++++++++++++++++
 libgitg/tests/Makefile.am      |    5 +-
 libgitg/tests/gitg-assert.h    |    5 +
 libgitg/tests/gitg-assert.vapi |    1 +
 libgitg/tests/main.vala        |    1 +
 libgitg/tests/test-date.vala   |  125 ++++++++++++++++
 7 files changed, 450 insertions(+), 3 deletions(-)
---
diff --git a/libgitg/Makefile.am b/libgitg/Makefile.am
index 6cc90db..9dc08c1 100644
--- a/libgitg/Makefile.am
+++ b/libgitg/Makefile.am
@@ -67,7 +67,8 @@ VALA_FILES =                                  \
        gitg-stage.vala                         \
        gitg-stage-status-enumerator.vala       \
        gitg-sidebar.vala                       \
-       gitg-hook.vala
+       gitg-hook.vala                          \
+       gitg-date.vala
 
 # Ignore all warnings for vala code...
 libgitg_1_0_la_CFLAGS =                \
diff --git a/libgitg/gitg-date.vala b/libgitg/gitg-date.vala
new file mode 100644
index 0000000..cb65a9c
--- /dev/null
+++ b/libgitg/gitg-date.vala
@@ -0,0 +1,313 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2013 - Jesse van den Kieboom
+ *
+ * gitg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gitg 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Gitg
+{
+
+public errordomain DateError
+{
+       INVALID_FORMAT
+}
+
+public class Date : Object, Initable
+{
+       private static Regex s_rfc2822;
+       private static Regex s_iso8601;
+       private static Regex s_internal;
+
+       private static string?[] s_months = new string?[] {
+               null,
+               "Jan",
+               "Feb",
+               "Mar",
+               "Apr",
+               "May",
+               "Jun",
+               "Jul",
+               "Aug",
+               "Sep",
+               "Oct",
+               "Nov",
+               "Dec"
+       };
+
+       static construct
+       {
+               try
+               {
+
+               s_iso8601 = new Regex(@"^
+                       (?<year>[0-9]{4})
+                       (?:
+                               [-.]?(?:
+                                       (?<month>[0-9]{2})
+                                       (?:
+                                               [-.]?(?<day>[0-9]{2})
+                                       )?
+                               |
+                                       W(?<week>[0-9]{2})
+                                       (?:
+                                               [-.]?(?<weekday>[0-9])
+                                       )?
+                               )
+                               (?:
+                                       [T ](?<hour>[0-9]{2})
+                                       (?:
+                                               :?
+                                               (?<minute>[0-9]{2})
+                                               (?:
+                                                       :?
+                                                       (?<seconds>[0-9]{2})
+                                                       (?<tz>
+                                                               (?<tzutc>Z) |
+                                                               [+-](?<tzhour>[0-9]{2})
+                                                               (?:
+                                                                       :?
+                                                                       (?<tzminute>[0-9]{2})
+                                                               )?
+                                                       )?
+                                               )?
+                                       )?
+                               )?
+                       )?
+               $$", RegexCompileFlags.EXTENDED);
+
+               s_rfc2822 = new Regex(@"^
+                       (?:
+                               [\\s]*(?<dayofweek>Mon|Tue|Wed|Thu|Fri|Sat|Sun)
+                               ,
+                       )?
+                       [\\s]*(?<day>[0-9]{1,2})
+                       [\\s]+
+                               (?<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
+                       [\\s]+
+                               (?<year>[0-9]{4})
+                       [\\s]+
+                               (?<hour>[0-9]{2})
+                               :
+                               (?<minute>[0-9]{2})
+                               (?:
+                                       :
+                                       (?<seconds>[0-9]{2})
+                               )?
+                       [\\s]+
+                       (?<tz>
+                               [+-]
+                               (?<tzhour>[0-9]{2})
+                               (?<tzminute>[0-9]{2})
+                       )
+               $$", RegexCompileFlags.EXTENDED);
+
+               s_internal = new Regex(@"^
+                       @?
+                       (?<timestamp>[0-9]+)
+                       [ ](?<tz>
+                               [+-](?<tzhour>[0-9]{2})
+                               (?:
+                                       :?
+                                       (?<tzminute>[0-9]{2})?
+                               )
+                       )
+               $$", RegexCompileFlags.EXTENDED);
+
+               }
+               catch (Error e)
+               {
+                       warning(@"Failed to compile date regex: $(e.message)");
+               }
+       }
+
+       private static bool fetch_and_set_int(MatchInfo info, string name, ref int retval)
+       {
+               string? val = info.fetch_named(name);
+
+               if (val == null)
+               {
+                       return false;
+               }
+
+               retval = int.parse(val);
+               return true;
+       }
+
+       private static bool fetch_and_set_double(MatchInfo info, string name, ref double retval)
+       {
+               string? val = info.fetch_named(name);
+
+               if (val == null)
+               {
+                       return false;
+               }
+
+               retval = double.parse(val);
+               return true;
+       }
+
+       private static DateTime parse_internal(MatchInfo info) throws Error
+       {
+               string? timestamp = info.fetch_named("timestamp");
+               int64 unixt = int64.parse(timestamp);
+
+               string? tzs = info.fetch_named("tz");
+
+               if (tzs != null)
+               {
+                       var ret = new DateTime.from_unix_utc(unixt);
+                       return ret.to_timezone(new TimeZone(tzs));
+               }
+               else
+               {
+                       return new DateTime.from_unix_local(unixt);
+               }
+       }
+
+       private static DateTime parse_iso8601(MatchInfo info) throws Error
+       {
+               TimeZone tz = new TimeZone.utc();
+
+               int year = 0;
+               int month = 1;
+               int day = 1;
+               int hour = 0;
+               int minute = 0;
+               double seconds = 0.0;
+
+               fetch_and_set_int(info, "year", ref year);
+               fetch_and_set_int(info, "month", ref month);
+               fetch_and_set_int(info, "day", ref day);
+               fetch_and_set_int(info, "hour", ref hour);
+               fetch_and_set_int(info, "minute", ref minute);
+               fetch_and_set_double(info, "seconds", ref seconds);
+
+               string? tzs = info.fetch_named("tz");
+
+               if (tzs != null)
+               {
+                       tz = new TimeZone(tzs);
+               }
+               else
+               {
+                       tz = new TimeZone.local();
+               }
+
+               return new DateTime(tz, year, month, day, hour, minute, seconds);
+       }
+
+       private static DateTime parse_rfc2822(MatchInfo info) throws Error
+       {
+               TimeZone tz;
+               int year = 0;
+               int month = 0;
+               int day = 1;
+               int hour = 0;
+               int minute = 0;
+               double seconds = 0;
+
+               fetch_and_set_int(info, "year", ref year);
+
+               string? monthstr = info.fetch_named("month");
+
+               for (int i = 0; i < s_months.length; ++i)
+               {
+                       if (s_months[i] != null && s_months[i] == monthstr)
+                       {
+                               month = i;
+                               break;
+                       }
+               }
+
+               if (month == 0)
+               {
+                       throw new DateError.INVALID_FORMAT("Invalid month specified");
+               }
+
+               fetch_and_set_int(info, "day", ref day);
+               fetch_and_set_int(info, "hour", ref hour);
+               fetch_and_set_int(info, "minute", ref minute);
+               fetch_and_set_double(info, "seconds", ref seconds);
+
+               string? tzs = info.fetch_named("tz");
+
+               if (tzs != null)
+               {
+                       tz = new TimeZone(tzs);
+               }
+               else
+               {
+                       tz = new TimeZone.local();
+               }
+
+               return new DateTime(tz, year, month, day, hour, minute, seconds);
+       }
+
+       private DateTime d_datetime;
+
+       public string date_string
+       {
+               get; construct set;
+       }
+
+       public DateTime date
+       {
+               get { return d_datetime; }
+       }
+
+       public bool init(Cancellable? cancellable = null) throws Error
+       {
+               MatchInfo info;
+
+               if (s_internal.match(date_string, 0, out info))
+               {
+                       d_datetime = parse_internal(info);
+
+                       return true;
+               }
+
+               if (s_iso8601.match(date_string, 0, out info))
+               {
+                       d_datetime = parse_iso8601(info);
+
+                       return true;
+               }
+
+               if (s_rfc2822.match(date_string, 0, out info))
+               {
+                       d_datetime = parse_rfc2822(info);
+
+                       return true;
+               }
+
+               throw new DateError.INVALID_FORMAT("Invalid date format");
+       }
+
+       public Date(string date) throws Error
+       {
+               Object(date_string: date);
+               ((Initable)this).init(null);
+       }
+
+       public static DateTime parse(string date) throws Error
+       {
+               return (new Date(date)).date;
+       }
+}
+
+}
+
+// ex: ts=4 noet
diff --git a/libgitg/tests/Makefile.am b/libgitg/tests/Makefile.am
index c5354ea..78e2e56 100644
--- a/libgitg/tests/Makefile.am
+++ b/libgitg/tests/Makefile.am
@@ -2,7 +2,7 @@ AM_CPPFLAGS = -g -I$(top_srcdir) -I$(top_srcdir)/gitg -I$(top_srcdir)/libgitg $(
 
 noinst_PROGRAMS = $(TEST_PROGS)
 
-AM_VALAFLAGS = $(GITG_PLUGIN_VALAFLAGS) --vapidir $(srcdir) --pkg posix --pkg gitg-assert
+AM_VALAFLAGS = $(GITG_PLUGIN_VALAFLAGS) --disable-warnings --vapidir $(srcdir) --pkg posix --pkg gitg-assert
 
 TEST_PROGS = test-libgitg
 
@@ -10,7 +10,8 @@ test_libgitg_SOURCES =                                \
        test.vala                               \
        main.vala                               \
        repository.vala                         \
-       test-stage.vala
+       test-stage.vala                         \
+       test-date.vala
 
 test_libgitg_LDADD = $(GITG_PLUGIN_LIBS)
 test_libgitg_CFLAGS = $(GITG_PLUGIN_CFLAGS) -w
diff --git a/libgitg/tests/gitg-assert.h b/libgitg/tests/gitg-assert.h
index 5be2326..561e70c 100644
--- a/libgitg/tests/gitg-assert.h
+++ b/libgitg/tests/gitg-assert.h
@@ -27,6 +27,11 @@
 #define gitg_test_assert_assert_inteq(a, b) g_assert_cmpint(a, ==, b)
 #define gitg_test_assert_assert_uinteq(a, b) g_assert_cmpuint(a, ==, b)
 #define gitg_test_assert_assert_floateq(a, b) g_assert_cmpfloat(a, ==, b)
+#define gitg_test_assert_assert_datetime(a, b) \
+       g_assert_cmpstr (g_date_time_format (a, "%F %T %z"), \
+                        ==, \
+                        g_date_time_format (b, "%F %T %z") \
+)
 
 #endif /* __GITG_ASSERT_H__ */
 
diff --git a/libgitg/tests/gitg-assert.vapi b/libgitg/tests/gitg-assert.vapi
index e83ba49..bca04c4 100644
--- a/libgitg/tests/gitg-assert.vapi
+++ b/libgitg/tests/gitg-assert.vapi
@@ -6,4 +6,5 @@ namespace Gitg.Test.Assert
        public static void assert_inteq(int a, int b);
        public static void assert_uinteq(uint a, uint b);
        public static void assert_floateq(float a, float b);
+       public static void assert_datetime(GLib.DateTime a, GLib.DateTime b);
 }
diff --git a/libgitg/tests/main.vala b/libgitg/tests/main.vala
index 3aa97b2..cbc265e 100644
--- a/libgitg/tests/main.vala
+++ b/libgitg/tests/main.vala
@@ -27,6 +27,7 @@ class Gitg.Test.Main
                GLib.Test.init(ref args);
 
                add(new Stage());
+               add(new Date());
 
                GLib.Test.run();
        }
diff --git a/libgitg/tests/test-date.vala b/libgitg/tests/test-date.vala
new file mode 100644
index 0000000..1cb2e11
--- /dev/null
+++ b/libgitg/tests/test-date.vala
@@ -0,0 +1,125 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2013 - Jesse van den Kieboom
+ *
+ * gitg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * gitg 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using Gitg.Test.Assert;
+
+class Gitg.Test.Date : Gitg.Test.Test
+{
+       protected virtual signal void test_iso8601()
+       {
+               assert_datetime(Gitg.Date.parse("2005"),
+                               new DateTime.local(2005, 1, 1, 0, 0, 0));
+
+               assert_datetime(Gitg.Date.parse("2005-04"),
+                               new DateTime.local(2005, 4, 1, 0, 0, 0));
+
+               assert_datetime(Gitg.Date.parse("2005.04"),
+                               new DateTime.local(2005, 4, 1, 0, 0, 0));
+
+               assert_datetime(Gitg.Date.parse("200504"),
+                               new DateTime.local(2005, 4, 1, 0, 0, 0));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07"),
+                               new DateTime.local(2005, 4, 7, 0, 0, 0));
+
+               assert_datetime(Gitg.Date.parse("20050407"),
+                               new DateTime.local(2005, 4, 7, 0, 0, 0));
+
+               assert_datetime(Gitg.Date.parse("2005.04.07"),
+                               new DateTime.local(2005, 4, 7, 0, 0, 0));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T22"),
+                               new DateTime.local(2005, 4, 7, 22, 0, 0));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T22:13"),
+                               new DateTime.local(2005, 4, 7, 22, 13, 0));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T2213"),
+                               new DateTime.local(2005, 4, 7, 22, 13, 0));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T22:13:13"),
+                               new DateTime.local(2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("200504-07T22:13:13"),
+                               new DateTime.local(2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("20050407T22:13:13"),
+                               new DateTime.local(2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("20050407T2213:13"),
+                               new DateTime.local(2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("20050407T221313"),
+                               new DateTime.local(2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("20050407 221313"),
+                               new DateTime.local(2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("2005.04.07T22:13:13"),
+                               new DateTime.local(2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T22:13:13Z"),
+                               new DateTime.utc(2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T22:13:13+0200"),
+                               new DateTime(new TimeZone("+0200"), 2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T22:13:13-0400"),
+                               new DateTime(new TimeZone("-0400"), 2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T22:13:13+0202"),
+                               new DateTime(new TimeZone("+0202"), 2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T22:13:13+03"),
+                               new DateTime(new TimeZone("+0300"), 2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("2005-04-07T22:13:13+03:20"),
+                               new DateTime(new TimeZone("+0320"), 2005, 4, 7, 22, 13, 13));
+
+       }
+
+       protected virtual signal void test_rfc2822()
+       {
+               assert_datetime(Gitg.Date.parse("Thu, 07 Apr 2005 22:13:13 +0200"),
+                               new DateTime(new TimeZone("+0200"), 2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("Thu, 07 Apr 2005 22:13:13 -0200"),
+                               new DateTime(new TimeZone("-0200"), 2005, 4, 7, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("Fri, 08 Apr 2005 22:13:13 -0200"),
+                               new DateTime(new TimeZone("-0200"), 2005, 4, 8, 22, 13, 13));
+
+               assert_datetime(Gitg.Date.parse("Tue, 08 Mar 2005 22:13:13 +0300"),
+                               new DateTime(new TimeZone("+0300"), 2005, 3, 8, 22, 13, 13));
+
+       }
+
+       protected virtual signal void test_internal()
+       {
+               assert_datetime(Gitg.Date.parse("457849203 +0200"),
+                               (new DateTime.from_unix_utc(457849203))
+                                   .to_timezone(new TimeZone("+0200")));
+
+               assert_datetime(Gitg.Date.parse("457849203 -0200"),
+                               (new DateTime.from_unix_utc(457849203))
+                                   .to_timezone(new TimeZone("-0200")));
+       }
+}
+
+// ex: ts=4 noet


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]