Repository: joke2k/faker
Pull request #307 (2015-12-01 15:58:37)

Timestamp conversion


Patch:
diff --git a/faker/providers/date_time/__init__.py b/faker/providers/date_time/__init__.py
index 06637d7b..5f9b50e7 100644
--- a/faker/providers/date_time/__init__.py
+++ b/faker/providers/date_time/__init__.py
@@ -2,10 +2,12 @@
 
 from __future__ import unicode_literals
 
+from datetime import timedelta
 import re
 from time import time, mktime
 
-from datetime import timedelta
+from dateutil import relativedelta
+from dateutil.tz import tzlocal
 
 from faker.generator import random
 from faker.utils.datetime_safe import date, datetime, real_date, real_datetime
@@ -15,6 +17,8 @@ from .. import BaseProvider
 
 
 def datetime_to_timestamp(dt):
+    if dt.tzinfo is not None:
+        dt = dt.astimezone(tzlocal())
     return mktime(dt.timetuple())
 
 
@@ -356,8 +360,10 @@ class Provider(BaseProvider):
         if datetime_end is None:
             datetime_end = datetime.now(tzinfo)
 
-        timestamp = random.randint(datetime_to_timestamp(datetime_start),
-                                       datetime_to_timestamp(datetime_end))
+        timestamp = random.randint(
+            datetime_to_timestamp(datetime_start),
+            datetime_to_timestamp(datetime_end),
+        )
         return datetime.fromtimestamp(timestamp, tzinfo)
 
     @classmethod
@@ -445,8 +451,8 @@ class Provider(BaseProvider):
         """
         now = datetime.now(tzinfo)
         this_month_start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
-        next_month_start = datetime(now.year, now.month + 1 % 12, 1, tzinfo=tzinfo)
 
+        next_month_start = this_month_start + relativedelta.relativedelta(months=1)
         if before_now and after_now:
             return cls.date_time_between_dates(this_month_start, next_month_start, tzinfo)
         elif not before_now and after_now:
diff --git a/setup.py b/setup.py
index e342ef9f..e1d02115 100644
--- a/setup.py
+++ b/setup.py
@@ -53,6 +53,9 @@ setup(
     platforms=["any"],
     test_suite='faker.tests',
     zip_safe=zip_safe,
+    install_requires=[
+        "python-dateutil>=2.4",
+    ],
     extras_require={
         ':python_version=="2.6"': ['importlib'],
         ':python_version=="3.0"': ['importlib'],


Test patch:
diff --git a/faker/tests/__init__.py b/faker/tests/__init__.py
index 8019b007..d20ab2c4 100644
--- a/faker/tests/__init__.py
+++ b/faker/tests/__init__.py
@@ -10,6 +10,7 @@ import os
 import time
 import unittest
 import sys
+from dateutil.tz import tzlocal
 
 try:
     from mock import patch
@@ -303,6 +304,14 @@ class FactoryTestCase(unittest.TestCase):
         pick = provider.random_element(choices)
         self.assertTrue(pick in choices)
 
+    def test_timezone_conversion(self):
+        from faker.providers.date_time import datetime_to_timestamp
+
+        now = datetime.datetime.now(utc).replace(microsecond=0)
+        timestamp = datetime_to_timestamp(now)
+        now_back = datetime.datetime.fromtimestamp(timestamp, utc)
+        self.assertEqual(now, now_back)
+
     def test_datetime_safe(self):
         from faker.utils import datetime_safe
         # test using example provided in module