diff --git a/Data/UnixTime/Conv.hs b/Data/UnixTime/Conv.hs
--- a/Data/UnixTime/Conv.hs
+++ b/Data/UnixTime/Conv.hs
@@ -19,6 +19,9 @@
 import System.Posix.Types (EpochTime)
 import System.Time (ClockTime(..))
 
+-- $setup
+-- >>> import Data.Function (on)
+
 foreign import ccall unsafe "c_parse_unix_time"
         c_parse_unix_time :: CString -> CString -> IO CTime
 
@@ -38,6 +41,7 @@
 -- This is a wrapper for strptime_l().
 -- Many implementations of strptime_l() do not support %Z and
 -- some implementations of strptime_l() do not support %z, either.
+-- 'utMicroSeconds' is always set to 0.
 
 parseUnixTime :: Format -> ByteString -> UnixTime
 parseUnixTime fmt str = unsafePerformIO $
@@ -48,6 +52,7 @@
 -- |
 -- Parsing 'ByteString' to 'UnixTime' interpreting as GMT.
 -- This is a wrapper for strptime_l().
+-- 'utMicroSeconds' is always set to 0.
 --
 -- >>> parseUnixTimeGMT webDateFormat "Thu, 01 Jan 1970 00:00:00 GMT"
 -- UnixTime {utSeconds = 0, utMicroSeconds = 0}
@@ -64,6 +69,8 @@
 -- |
 -- Formatting 'UnixTime' to 'ByteString' in local time.
 -- This is a wrapper for strftime_l().
+-- 'utMicroSeconds' is ignored.
+-- The result depends on the TZ environment variable.
 
 formatUnixTime :: Format -> UnixTime -> IO ByteString
 formatUnixTime fmt t =
@@ -73,9 +80,17 @@
 -- |
 -- Formatting 'UnixTime' to 'ByteString' in GMT.
 -- This is a wrapper for strftime_l().
+-- 'utMicroSeconds' is ignored.
 --
 -- >>> formatUnixTimeGMT webDateFormat $ UnixTime 0 0
 -- "Thu, 01 Jan 1970 00:00:00 GMT"
+-- >>> let ut = UnixTime 100 200
+-- >>> let str = formatUnixTimeGMT "%s" ut
+-- >>> let ut' = parseUnixTimeGMT "%s" str
+-- >>> ((==) `on` utSeconds) ut ut'
+-- True
+-- >>> ((==) `on` utMicroSeconds) ut ut'
+-- False
 
 formatUnixTimeGMT :: Format -> UnixTime -> ByteString
 formatUnixTimeGMT fmt t =
diff --git a/cbits/conv.c b/cbits/conv.c
--- a/cbits/conv.c
+++ b/cbits/conv.c
@@ -15,6 +15,7 @@
 #include <string.h>
 #include <time.h>
 #include <locale.h>
+#include <stdlib.h>
 
 #if THREAD_SAFE
 #if HAVE_XLOCALE_H
@@ -36,6 +37,31 @@
 }
 #endif
 
+/*
+ * Set the value of the TZ environment variable to UTC
+ * and return the old value.
+ */
+char *set_tz_utc() {
+    char *tz;
+    tz = getenv("TZ");
+    setenv("TZ", "", 1);
+    tzset();
+    return tz;
+}
+
+/*
+ * Set the value of the TZ environment variable to tz or
+ * unset the variable if tz is null;
+ */
+void set_tz(char *local_tz) {
+    if (local_tz) {
+      setenv("TZ", local_tz, 1);
+    } else {
+      unsetenv("TZ");
+    }
+    tzset();
+}
+
 time_t c_parse_unix_time(char *fmt, char *src) {
     struct tm dst;
     init_locale();
@@ -54,7 +80,7 @@
  *
  * Copyright (c) 1997 Kungliga Tekniska H.gskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved. 
+ * All rights reserved.
  */
 
 static int
@@ -91,13 +117,16 @@
 
 time_t c_parse_unix_time_gmt(char *fmt, char *src) {
     struct tm dst;
+    char *local_tz;
     init_locale();
     memset(&dst, 0, sizeof(struct tm));
+    local_tz = set_tz_utc();
 #if THREAD_SAFE
     strptime_l(src, fmt, &dst, c_locale);
 #else
     strptime(src, fmt, &dst);
 #endif
+    set_tz(local_tz);
     return timegm(&dst);
 }
 
@@ -114,11 +143,18 @@
 
 size_t c_format_unix_time_gmt(char *fmt, time_t src, char* dst, int siz) {
     struct tm tim;
+    char *local_tz;
+    size_t dst_size;
+
     init_locale();
     gmtime_r(&src, &tim);
+
+    local_tz = set_tz_utc();
 #if THREAD_SAFE
-    return strftime_l(dst, siz, fmt, &tim, c_locale);
+    dst_size = strftime_l(dst, siz, fmt, &tim, c_locale);
 #else
-    return strftime(dst, siz, fmt, &tim);
+    dst_size = strftime(dst, siz, fmt, &tim);
 #endif
+    set_tz(local_tz);
+    return dst_size;
 }
diff --git a/test/UnixTimeSpec.hs b/test/UnixTimeSpec.hs
--- a/test/UnixTimeSpec.hs
+++ b/test/UnixTimeSpec.hs
@@ -5,6 +5,7 @@
 
 import Data.ByteString (ByteString)
 import qualified Data.ByteString.Char8 as BS
+import Data.Function (on)
 import Data.Time
 import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
 import Data.UnixTime
@@ -13,7 +14,7 @@
 import Foreign.Storable (peek, poke)
 import Test.Hspec
 import Test.Hspec.QuickCheck (prop)
-import Test.QuickCheck
+import Test.QuickCheck hiding ((===))
 
 #if !MIN_VERSION_time(1,5,0)
 import System.Locale (defaultTimeLocale)
@@ -42,12 +43,17 @@
             let model = formatMailModel utcTime timeZone
             ours `shouldReturn` model
 
-    describe "parseUnixTimeGMT & formatUnixTimeGMT" $
-        prop "inverses the result" $ \ut@(UnixTime sec _) ->
+    describe "parseUnixTimeGMT & formatUnixTimeGMT" $ do
+        let (===) = (==) `on` utSeconds
+        prop "inverses the result" $ \ut ->
             let dt  = formatUnixTimeGMT webDateFormat ut
                 ut' = parseUnixTimeGMT  webDateFormat dt
                 dt' = formatUnixTimeGMT webDateFormat ut'
-            in ut' == UnixTime sec 0 && dt == dt'
+            in ut === ut' && dt == dt'
+        prop "inverses the result (2)" $ \ut ->
+            let str = formatUnixTimeGMT "%s" ut
+                ut' = parseUnixTimeGMT "%s" str
+            in ut === ut'
 
     describe "addUnixDiffTime & diffUnixTime" $
         prop "invrses the result" $ \(ut0, ut1) ->
diff --git a/unix-time.cabal b/unix-time.cabal
--- a/unix-time.cabal
+++ b/unix-time.cabal
@@ -1,5 +1,5 @@
 Name:                   unix-time
-Version:                0.3.6
+Version:                0.3.7
 Author:                 Kazu Yamamoto <kazu@iij.ad.jp>
 Maintainer:             Kazu Yamamoto <kazu@iij.ad.jp>
 License:                BSD3
