Repository: meysam81/timeframe (language: python)

Issue:
ValueError when subtracting a timeframe that includes the other but has equal start
Python console:
```Python
from timeframe import TimeFrame
from datetime import datetime
tf1 = TimeFrame(datetime(2022, 2, 22), datetime(2022, 2, 23))
tf2 = TimeFrame(datetime(2022, 2, 22), datetime(2022, 2, 24))
tf2 - tf1
# 2022-02-23T00:00:00.000001#2022-02-24T00:00:00  (fine)
tf1 - tf2
# -> Exception:
Traceback (most recent call last):
  File "F:\Programme\Python\Python310\lib\code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "F:\Programme\Python\Python310\lib\site-packages\timeframe\timeframe.py", line 359, in __sub__
    return TimeFrame(lower, upper)
  File "F:\Programme\Python\Python310\lib\site-packages\timeframe\timeframe.py", line 195, in __init__
    raise ValueError(
ValueError: start should be lower or equal than end: 2022-02-24 00:00:00.000001 & 2022-02-23 00:00:00
```

PS: Great package otherwise! :) 🥇 
TypeError when BatchTimeFrame is subtracted a Timeframe from within 


```Python
        tf_long = TimeFrame(datetime(2022, 3, 1, 12), datetime(2022, 3, 1, 13))
        tf_a = BatchTimeFrame([tf_long])

        tf_sub_a = TimeFrame(datetime(2022, 3, 1, 12, 30), datetime(2022, 3, 1, 12, 45))
        tf_b = BatchTimeFrame([tf_sub_a])

        print(tf_a - tf_b)  #TypeError: Every iterable element should be a BaseTimeFrame
```


Discussion / hints:

Fix patch:
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..6110707
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,5 @@
+github: meysam81
+ko_fi: meysam
+patreon: meysam81
+custom:
+  - https://www.buymeacoffee.com/meysam/
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index ee3c146..119f0b2 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -9,16 +9,16 @@
 # the `language` matrix defined below to confirm you have the correct set of
 # supported CodeQL languages.
 #
-name: "CodeQL"
+name: codeql
 
 on:
   push:
-    branches: [ "main" ]
+    branches: ["main"]
   pull_request:
     # The branches below must be a subset of the branches above
-    branches: [ "main" ]
+    branches: ["main"]
   schedule:
-    - cron: '45 10 * * 1'
+    - cron: "45 10 * * 1"
 
 jobs:
   analyze:
@@ -32,43 +32,42 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        language: [ 'python' ]
+        language: ["python"]
         # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
         # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
 
     steps:
-    - name: Checkout repository
-      uses: actions/checkout@v3
+      - name: Checkout repository
+        uses: actions/checkout@v3
 
-    # Initializes the CodeQL tools for scanning.
-    - name: Initialize CodeQL
-      uses: github/codeql-action/init@v2
-      with:
-        languages: ${{ matrix.language }}
-        # If you wish to specify custom queries, you can do so here or in a config file.
-        # By default, queries listed here will override any specified in a config file.
-        # Prefix the list here with "+" to use these queries and those in the config file.
-        
-        # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
-        # queries: security-extended,security-and-quality
+      # Initializes the CodeQL tools for scanning.
+      - name: Initialize CodeQL
+        uses: github/codeql-action/init@v2
+        with:
+          languages: ${{ matrix.language }}
+          # If you wish to specify custom queries, you can do so here or in a config file.
+          # By default, queries listed here will override any specified in a config file.
+          # Prefix the list here with "+" to use these queries and those in the config file.
 
-        
-    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
-    # If this step fails, then you should remove it and run the build manually (see below)
-    - name: Autobuild
-      uses: github/codeql-action/autobuild@v2
+          # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
+          # queries: security-extended,security-and-quality
 
-    # ℹ️ Command-line programs to run using the OS shell.
-    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
+      # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
+      # If this step fails, then you should remove it and run the build manually (see below)
+      - name: Autobuild
+        uses: github/codeql-action/autobuild@v2
 
-    #   If the Autobuild fails above, remove it and uncomment the following three lines. 
-    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
+      # ℹ️ Command-line programs to run using the OS shell.
+      # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
 
-    # - run: |
-    #   echo "Run, Build Application using script"
-    #   ./location_of_script_within_repo/buildscript.sh
+      #   If the Autobuild fails above, remove it and uncomment the following three lines.
+      #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
 
-    - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v2
-      with:
-        category: "/language:${{matrix.language}}"
+      # - run: |
+      #   echo "Run, Build Application using script"
+      #   ./location_of_script_within_repo/buildscript.sh
+
+      - name: Perform CodeQL Analysis
+        uses: github/codeql-action/analyze@v2
+        with:
+          category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
index fe461b4..4063a37 100644
--- a/.github/workflows/dependency-review.yml
+++ b/.github/workflows/dependency-review.yml
@@ -4,7 +4,7 @@
 #
 # Source repository: https://github.com/actions/dependency-review-action
 # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
-name: 'Dependency Review'
+name: dependency-review
 on: [pull_request]
 
 permissions:
@@ -14,7 +14,7 @@ jobs:
   dependency-review:
     runs-on: ubuntu-latest
     steps:
-      - name: 'Checkout Repository'
+      - name: "Checkout Repository"
         uses: actions/checkout@v3
-      - name: 'Dependency Review'
+      - name: "Dependency Review"
         uses: actions/dependency-review-action@v2
diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml
index a09e846..d6a1fe8 100644
--- a/.github/workflows/publish-pypi.yml
+++ b/.github/workflows/publish-pypi.yml
@@ -14,7 +14,7 @@ jobs:
       - name: Setup python
         uses: actions/setup-python@v4
         with:
-          python-version: "3.10"
+          python-version: "3.11"
       - name: Prepare
         run: |
           pip install -U pip wheel
diff --git a/LICENSE b/LICENSE
index ef13281..c94ec86 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2021 Meysam
+Copyright (c) 2022 Meysam Azad <contact@meysam.io>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/setup.py b/setup.py
index 96bec93..1b4ddd4 100644
--- a/setup.py
+++ b/setup.py
@@ -32,6 +32,7 @@
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
+        "Programming Language :: Python :: 3.11",
     ],
-    python_requires=">=3.6,<3.11",
+    python_requires=">=3.6",
 )
diff --git a/tox.ini b/tox.ini
index a785512..d2fa623 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = py3.{6,7,8,9,10}
+envlist = py3.{6,7,8,9,10,11}
 
 [testenv]
 
@@ -7,9 +7,11 @@ deps =
     coverage>=5.3,<6.0
     pytest>=6.1.2,<7.0.0
     pytest-asyncio>=0.14.0,<1.0.0
+    faker<16
+    pytest-repeat~=0.9.1
 
 commands =
-    coverage run --source=timeframe -m pytest {posargs}
+    coverage run --source=timeframe -m pytest --last-failed {posargs}
     coverage html
     coverage xml
     coverage report -m


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index f46cc59..8f83d62 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -15,23 +15,25 @@ jobs:
       - name: Setup python
         uses: actions/setup-python@v4
         with:
-          python-version: "3.10"
+          python-version: ${{ matrix.python-version }}
       - name: Prepare
         run: |
           pip install -U pip tox
-      - name: Run tests ${{ matrix.python-version }}
-        run: |
-          tox -e ${{ matrix.python-version }}
+      - name: Run tests
+        run: tox -e py${{ matrix.python-version }}
       - name: Coverage Report
+        if: github.ref == 'refs/heads/main'
         uses: codecov/codecov-action@v3
         with:
+          token: ${{ secrets.CODECOV_TOKEN }}
           fail_ci_if_error: true
           verbose: true
     strategy:
       matrix:
         python-version:
-          - py3.6
-          - py3.7
-          - py3.8
-          - py3.9
-          - py3.10
+          - "3.6"
+          - "3.7"
+          - "3.8"
+          - "3.9"
+          - "3.10"
+          - "3.11"
diff --git a/test/conftest.py b/test/conftest.py
new file mode 100644
index 0000000..136f052
--- /dev/null
+++ b/test/conftest.py
@@ -0,0 +1,28 @@
+import pytest
+
+from timeframe import BatchTimeFrame, TimeFrame
+
+
+@pytest.fixture
+def random_timeframe(faker):
+    return TimeFrame(
+        faker.date_time_between(start_date="-1y", end_date="now"),
+        faker.date_time_between(start_date="now", end_date="+1y"),
+    )
+
+
+@pytest.fixture
+def random_batch_timeframes(faker):
+    def get_timeframe():
+        start = faker.date_time()
+        end = faker.date_time_between(start_date=start, end_date="+1h")
+        return TimeFrame(start, end)
+
+    return BatchTimeFrame([get_timeframe() for _ in range(10)])
+
+
+@pytest.fixture(scope="session", autouse=True)
+def faker_seed():
+    import time
+
+    return time.time()