Repository: joke2k/faker
Pull request #245 (2015-05-21 15:01:02)

Justinwp patch 1


Patch:
diff --git a/README.rst b/README.rst
index e3f59e5c..bd34ea3e 100644
--- a/README.rst
+++ b/README.rst
@@ -259,10 +259,10 @@ How to use with factory-boy
 Seeding the Generator
 ---------------------
 
-When using Faker for unit testing, you will often want to generate the same
-data set. The generator offers a  ``seed()`` method, which seeds the random
-number generator. Calling the same script twice with the same seed produces the
-same results.
+You may want to get always the same generated data - for instance when
+using Faker for unit testing purposes. The generator offers a ``seed()``
+method, which seeds the random number generator. Calling the same script
+twice with the same seed produces the same results.
 
 .. code:: python
 
diff --git a/faker/providers/date_time/__init__.py b/faker/providers/date_time/__init__.py
index 434d3f5b..146ae89d 100644
--- a/faker/providers/date_time/__init__.py
+++ b/faker/providers/date_time/__init__.py
@@ -335,33 +335,118 @@ class Provider(BaseProvider):
         return datetime.fromtimestamp(timestamp)
 
     @classmethod
-    def date_time_this_century(cls):
+    def date_time_between_dates(cls, datetime_start=None, datetime_end=None):
         """
-        :example DateTime('1964-04-04 11:02:02')
+        Takes two DateTime objects and returns a random date between the two given dates.
+        Accepts DateTime objects.
+
+        :param datetime_start DateTime
+        :param datetime_end DateTime
+        :example DateTime('1999-02-02 11:42:52')
+        :return DateTime
         """
-        return cls.date_time_between('-%dy' % (datetime.now().year % 100))
+        if datetime_start is None:
+            datetime_start = datetime.now()
+
+        if datetime_end is None:
+            datetime_end = datetime.now()
+
+        timestamp = random.randint(datetime_to_timestamp(datetime_start),
+                                       datetime_to_timestamp(datetime_end))
+        return datetime.fromtimestamp(timestamp)
 
     @classmethod
-    def date_time_this_decade(cls):
+    def date_time_this_century(cls, before_now=True, after_now=False):
         """
-        :example DateTime('2004-04-04 11:02:02')
+        Gets a DateTime object for the decade year. 
+        
+        :param before_now: include days in current decade before today
+        :param after_now: include days in current decade after today
+        :example DateTime('2012-04-04 11:02:02')
+        :return DateTime
         """
-        return cls.date_time_between('-%dy' % (datetime.now().year % 10))
+        now = datetime.now()
+        this_century_start = datetime(now.year - (now.year % 10), 1, 1)
+        next_century_start = datetime(this_century_start.year + 10, 1, 1)
+
+        if before_now and after_now:
+            return cls.date_time_between_dates(this_century_start, next_century_start)
+        elif not before_now and after_now:
+            return cls.date_time_between_dates(now, next_century_start)
+        elif not after_now and before_now:
+            return cls.date_time_between_dates(this_century_start, now)
+        else:
+            return now
 
     @classmethod
-    def date_time_this_year(cls):
+    def date_time_this_decade(cls, before_now=True, after_now=False):
         """
+        Gets a DateTime object for the decade year. 
+        
+        :param before_now: include days in current decade before today
+        :param after_now: include days in current decade after today
         :example DateTime('2012-04-04 11:02:02')
+        :return DateTime
         """
-        return cls.date_time_between('-%dm' % (datetime.now().month))
+        now = datetime.now()
+        this_decade_start = datetime(now.year - (now.year % 10), 1, 1)
+        next_decade_start = datetime(this_decade_start.year + 10, 1, 1)
+
+        if before_now and after_now:
+            return cls.date_time_between_dates(this_decade_start, next_decade_start)
+        elif not before_now and after_now:
+            return cls.date_time_between_dates(now, next_decade_start)
+        elif not after_now and before_now:
+            return cls.date_time_between_dates(this_decade_start, now)
+        else:
+            return now
 
     @classmethod
-    def date_time_this_month(cls):
+    def date_time_this_year(cls, before_now=True, after_now=False):
         """
+        Gets a DateTime object for the current year. 
+        
+        :param before_now: include days in current year before today
+        :param after_now: include days in current year after today
         :example DateTime('2012-04-04 11:02:02')
+        :return DateTime
         """
-        return cls.date_time_between('-%dd' % (datetime.now().day))
-
+        now = datetime.now()
+        this_year_start = now.replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0)
+        next_year_start = datetime(now.year + 1, 1, 1)
+
+        if before_now and after_now:
+            return cls.date_time_between_dates(this_year_start, next_year_start)
+        elif not before_now and after_now:
+            return cls.date_time_between_dates(now, next_year_start)
+        elif not after_now and before_now:
+            return cls.date_time_between_dates(this_year_start, now)
+        else:
+            return now
+        
+    @classmethod
+    def date_time_this_month(cls, before_now=True, after_now=False):
+        """
+        Gets a DateTime object for the current month. 
+        
+        :param before_now: include days in current month before today
+        :param after_now: include days in current month after today
+        :example DateTime('2012-04-04 11:02:02')
+        :return DateTime
+        """
+        now = datetime.now()
+        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)
+
+        if before_now and after_now:
+            return cls.date_time_between_dates(this_month_start, next_month_start)
+        elif not before_now and after_now:
+            return cls.date_time_between_dates(now, next_month_start)
+        elif not after_now and before_now:
+            return cls.date_time_between_dates(this_month_start, now)
+        else:
+            return now
+            
     @classmethod
     def am_pm(cls):
         return cls.date('%p')
diff --git a/setup.py b/setup.py
index bc1888cf..78747f9f 100644
--- a/setup.py
+++ b/setup.py
@@ -57,5 +57,5 @@ setup(
     platforms=["any"],
     test_suite='faker.tests',
     zip_safe=zip_safe,
-    install_requires=install_requires,
+    install_requires=install_requires
 )


Test patch:
diff --git a/faker/tests/__init__.py b/faker/tests/__init__.py
index 5a35505a..b30aeb04 100644
--- a/faker/tests/__init__.py
+++ b/faker/tests/__init__.py
@@ -4,9 +4,11 @@ from __future__ import unicode_literals
 
 __loader__ = None
 
+import datetime
 import json
 import os
 import random
+import time
 import unittest
 import sys
 
@@ -283,6 +285,46 @@ class FactoryTestCase(unittest.TestCase):
         # test that certain formatting strings are allowed on post-1900 dates
         result = datetime_safe.date(2008, 2, 29).strftime('%y')
         self.assertEqual(result, r'08')
+    
+    def test_date_time_between_dates(self):
+        from faker.providers.date_time import Provider
+        provider = Provider
+
+        timestamp_start = random.randint(0,10000000000)
+        timestamp_end = timestamp_start+1
+
+        datetime_start = datetime.datetime.fromtimestamp(timestamp_start)
+        datetime_end = datetime.datetime.fromtimestamp(timestamp_end)
+
+        random_date = provider.date_time_between_dates(datetime_start, datetime_end)
+        self.assertTrue(datetime_start <= random_date)
+        self.assertTrue(datetime_end >= random_date)
+
+    def _datetime_to_time(self, value):
+        return int(time.mktime(value.timetuple()))
+
+    def test_date_time_this_period(self):
+        from faker.providers.date_time import Provider
+        provider = Provider
+        now = datetime.datetime.now()
+        # test century
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_century(after_now=False)) <= self._datetime_to_time(now))
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_century(before_now=False)) >= self._datetime_to_time(now))
+        # test decade
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_decade(after_now=False)) <= self._datetime_to_time(now))
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_decade(before_now=False)) >= self._datetime_to_time(now))
+        self.assertEqual(self._datetime_to_time(provider.date_time_this_decade(before_now=False, after_now=False)),
+                               self._datetime_to_time(now))
+        # test year
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_year(after_now=False)) <= self._datetime_to_time(now))
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_year(before_now=False)) >= self._datetime_to_time(now))
+        self.assertEqual(self._datetime_to_time(provider.date_time_this_year(before_now=False, after_now=False)),
+                               self._datetime_to_time(now))
+        # test month
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_month(after_now=False)) <= self._datetime_to_time(now))
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_month(before_now=False)) >= self._datetime_to_time(now))
+        self.assertEqual(self._datetime_to_time(provider.date_time_this_month(before_now=False, after_now=False)),
+                               self._datetime_to_time(now))
 
     def test_prefix_suffix_always_string(self):
         # Locales known to contain `*_male` and `*_female`.
@@ -292,22 +334,6 @@ class FactoryTestCase(unittest.TestCase):
                 assert isinstance(f.prefix(), string_types)
                 assert isinstance(f.suffix(), string_types)
 
-    def test_no_words_sentence(self):
-        from faker.providers.lorem import Provider
-
-        provider = Provider(None)
-
-        paragraph = provider.paragraph(0)
-        self.assertEqual(paragraph, '')
-
-    def test_no_words_paragraph(self):
-        from faker.providers.lorem import Provider
-
-        provider = Provider(None)
-
-        sentence = provider.sentence(0)
-        self.assertEqual(sentence, '')
-
 
 if __name__ == '__main__':
     unittest.main()