diff --git a/awscli/bcdoc/docstringparser.py b/awscli/bcdoc/docstringparser.py
index 868bd5d..3eaf662 100644
--- a/awscli/bcdoc/docstringparser.py
+++ b/awscli/bcdoc/docstringparser.py
@@ -11,9 +11,10 @@
 # ANY KIND, either express or implied. See the License for the specific
 # language governing permissions and limitations under the License.
 from botocore.compat import six
+from html import parser as html_parser
 
 
-class DocStringParser(six.moves.html_parser.HTMLParser):
+class DocStringParser(html_parser.HTMLParser):
     """
     A simple HTML parser.  Focused on converting the subset of HTML
     that appears in the documentation strings of the JSON models into
@@ -23,20 +24,20 @@ class DocStringParser(six.moves.html_parser.HTMLParser):
     def __init__(self, doc):
         self.tree = None
         self.doc = doc
-        six.moves.html_parser.HTMLParser.__init__(self)
+        html_parser.HTMLParser.__init__(self)
 
     def reset(self):
-        six.moves.html_parser.HTMLParser.reset(self)
+        html_parser.HTMLParser.reset(self)
         self.tree = HTMLTree(self.doc)
 
     def feed(self, data):
         # HTMLParser is an old style class, so the super() method will not work.
-        six.moves.html_parser.HTMLParser.feed(self, data)
+        html_parser.HTMLParser.feed(self, data)
         self.tree.write()
         self.tree = HTMLTree(self.doc)
 
     def close(self):
-        six.moves.html_parser.HTMLParser.close(self)
+        html_parser.HTMLParser.close(self)
         # Write if there is anything remaining.
         self.tree.write()
         self.tree = HTMLTree(self.doc)
diff --git a/awscli/botocore/auth.py b/awscli/botocore/auth.py
index e8c83ad..e50be2a 100644
--- a/awscli/botocore/auth.py
+++ b/awscli/botocore/auth.py
@@ -396,7 +396,7 @@ class SigV4Auth(BaseSigner):
     def add_auth(self, request):
         if self.credentials is None:
             raise NoCredentialsError()
-        datetime_now = datetime.datetime.utcnow()
+        datetime_now = datetime.datetime.now(datetime.timezone.utc)
         request.context['timestamp'] = datetime_now.strftime(SIGV4_TIMESTAMP)
         # This could be a retry.  Make sure the previous
         # authorization header is removed first.
@@ -440,7 +440,7 @@ class SigV4Auth(BaseSigner):
         if 'Date' in request.headers:
             del request.headers['Date']
             datetime_timestamp = datetime.datetime.strptime(
-                request.context['timestamp'], SIGV4_TIMESTAMP)
+                request.context['timestamp'], SIGV4_TIMESTAMP[:-1] + '%z')
             request.headers['Date'] = formatdate(
                 int(calendar.timegm(datetime_timestamp.timetuple())))
             if 'X-Amz-Date' in request.headers:
@@ -528,7 +528,7 @@ class S3ExpressPostAuth(S3ExpressAuth):
     REQUIRES_IDENTITY_CACHE = True
 
     def add_auth(self, request):
-        datetime_now = datetime.datetime.utcnow()
+        datetime_now = datetime.datetime.now(datetime.timezone.utc)
         request.context['timestamp'] = datetime_now.strftime(SIGV4_TIMESTAMP)
 
         fields = {}
@@ -781,7 +781,7 @@ class S3SigV4PostAuth(SigV4Auth):
     http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html
     """
     def add_auth(self, request):
-        datetime_now = datetime.datetime.utcnow()
+        datetime_now = datetime.datetime.now(datetime.timezone.utc)
         request.context['timestamp'] = datetime_now.strftime(SIGV4_TIMESTAMP)
 
         fields = {}
diff --git a/awscli/botocore/compat.py b/awscli/botocore/compat.py
index b189271..de182f4 100644
--- a/awscli/botocore/compat.py
+++ b/awscli/botocore/compat.py
@@ -33,7 +33,7 @@ from urllib3 import exceptions
 logger = logging.getLogger(__name__)
 
 
-from botocore.vendored.six.moves import http_client
+from http import client as http_client
 
 class HTTPHeaders(http_client.HTTPMessage):
     pass
diff --git a/awscli/botocore/configloader.py b/awscli/botocore/configloader.py
index 3d1de2f..d8120c6 100644
--- a/awscli/botocore/configloader.py
+++ b/awscli/botocore/configloader.py
@@ -18,6 +18,7 @@ import sys
 
 import botocore.exceptions
 from botocore.compat import six
+import configparser
 
 
 def multi_file_load_config(*filenames):
@@ -143,10 +144,10 @@ def raw_config_parse(config_filename, parse_subsections=True):
         path = os.path.expanduser(path)
         if not os.path.isfile(path):
             raise botocore.exceptions.ConfigNotFound(path=_unicode_path(path))
-        cp = six.moves.configparser.RawConfigParser()
+        cp = configparser.RawConfigParser()
         try:
             cp.read([path])
-        except (six.moves.configparser.Error, UnicodeDecodeError):
+        except (configparser.Error, UnicodeDecodeError):
             raise botocore.exceptions.ConfigParseError(
                 path=_unicode_path(path))
         else:
diff --git a/awscli/botocore/crt/auth.py b/awscli/botocore/crt/auth.py
index 534a7f8..5046b35 100644
--- a/awscli/botocore/crt/auth.py
+++ b/awscli/botocore/crt/auth.py
@@ -55,10 +55,7 @@ class CrtSigV4Auth(BaseSigner):
         if self.credentials is None:
             raise NoCredentialsError()
 
-        # Use utcnow() because that's what gets mocked by tests, but set
-        # timezone because CRT assumes naive datetime is local time.
-        datetime_now = datetime.datetime.utcnow().replace(
-            tzinfo=datetime.timezone.utc)
+        datetime_now = datetime.datetime.now(datetime.timezone.utc)
 
         # Use existing 'X-Amz-Content-SHA256' header if able
         existing_sha256 = self._get_existing_sha256(request)
@@ -245,10 +242,7 @@ class CrtSigV4AsymAuth(BaseSigner):
         if self.credentials is None:
             raise NoCredentialsError()
 
-        # Use utcnow() because that's what gets mocked by tests, but set
-        # timezone because CRT assumes naive datetime is local time.
-        datetime_now = datetime.datetime.utcnow().replace(
-            tzinfo=datetime.timezone.utc)
+        datetime_now = datetime.datetime.now(datetime.timezone.utc)
 
         # Use existing 'X-Amz-Content-SHA256' header if able
         existing_sha256 = self._get_existing_sha256(request)
diff --git a/awscli/botocore/docs/bcdoc/docstringparser.py b/awscli/botocore/docs/bcdoc/docstringparser.py
index 868bd5d..3eaf662 100644
--- a/awscli/botocore/docs/bcdoc/docstringparser.py
+++ b/awscli/botocore/docs/bcdoc/docstringparser.py
@@ -11,9 +11,10 @@
 # ANY KIND, either express or implied. See the License for the specific
 # language governing permissions and limitations under the License.
 from botocore.compat import six
+from html import parser as html_parser
 
 
-class DocStringParser(six.moves.html_parser.HTMLParser):
+class DocStringParser(html_parser.HTMLParser):
     """
     A simple HTML parser.  Focused on converting the subset of HTML
     that appears in the documentation strings of the JSON models into
@@ -23,20 +24,20 @@ class DocStringParser(six.moves.html_parser.HTMLParser):
     def __init__(self, doc):
         self.tree = None
         self.doc = doc
-        six.moves.html_parser.HTMLParser.__init__(self)
+        html_parser.HTMLParser.__init__(self)
 
     def reset(self):
-        six.moves.html_parser.HTMLParser.reset(self)
+        html_parser.HTMLParser.reset(self)
         self.tree = HTMLTree(self.doc)
 
     def feed(self, data):
         # HTMLParser is an old style class, so the super() method will not work.
-        six.moves.html_parser.HTMLParser.feed(self, data)
+        html_parser.HTMLParser.feed(self, data)
         self.tree.write()
         self.tree = HTMLTree(self.doc)
 
     def close(self):
-        six.moves.html_parser.HTMLParser.close(self)
+        html_parser.HTMLParser.close(self)
         # Write if there is anything remaining.
         self.tree.write()
         self.tree = HTMLTree(self.doc)
diff --git a/awscli/botocore/httpsession.py b/awscli/botocore/httpsession.py
index 29b2103..d51dfdd 100644
--- a/awscli/botocore/httpsession.py
+++ b/awscli/botocore/httpsession.py
@@ -59,7 +59,7 @@ from botocore.exceptions import (
     ReadTimeoutError,
     SSLError,
 )
-from botocore.vendored.six.moves.urllib_parse import unquote
+from urllib.parse import unquote
 
 filter_ssl_warnings()
 logger = logging.getLogger(__name__)
diff --git a/awscli/botocore/parsers.py b/awscli/botocore/parsers.py
index ffca974..367c867 100644
--- a/awscli/botocore/parsers.py
+++ b/awscli/botocore/parsers.py
@@ -119,7 +119,8 @@ import json
 import logging
 import re
 
-from botocore.compat import ETree, XMLParseError, six
+from botocore.compat import ETree, XMLParseError
+from http import client as http_client
 from botocore.eventstream import EventStream, NoInitialResponseError
 from botocore.utils import (
     is_json_value_header,
@@ -300,7 +301,7 @@ class ResponseParser(object):
                   "service, unable to populate error code and message.")
         return {
             'Error': {'Code': str(response['status_code']),
-                      'Message': six.moves.http_client.responses.get(
+                      'Message': http_client.responses.get(
                           response['status_code'], '')},
             'ResponseMetadata': {},
         }
@@ -1035,7 +1036,7 @@ class RestXMLParser(BaseRestParser, BaseXMLResponseParser):
         return {
             'Error': {
                 'Code': str(response['status_code']),
-                'Message': six.moves.http_client.responses.get(
+                'Message': http_client.responses.get(
                     response['status_code'], ''),
             },
             'ResponseMetadata': {
diff --git a/awscli/botocore/signers.py b/awscli/botocore/signers.py
index 57df023..7ff87e4 100644
--- a/awscli/botocore/signers.py
+++ b/awscli/botocore/signers.py
@@ -549,7 +549,7 @@ class S3PostPresigner(object):
         policy = {}
 
         # Create an expiration date for the policy
-        datetime_now = datetime.datetime.utcnow()
+        datetime_now = datetime.datetime.now(datetime.timezone.utc)
         expire_date = datetime_now + datetime.timedelta(seconds=expires_in)
         policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601)
 
diff --git a/awscli/botocore/utils.py b/awscli/botocore/utils.py
index a408d9d..f4d7ece 100644
--- a/awscli/botocore/utils.py
+++ b/awscli/botocore/utils.py
@@ -72,7 +72,7 @@ from botocore.exceptions import (
     UnsupportedS3ControlArnError,
     UnsupportedS3ControlConfigurationError,
 )
-from botocore.vendored.six.moves.urllib.request import getproxies, proxy_bypass
+from urllib.request import getproxies, proxy_bypass
 from dateutil.tz import tzutc
 from urllib3.exceptions import LocationParseError
 
@@ -583,13 +583,13 @@ class InstanceMetadataFetcher(IMDSFetcher):
             return
         try:
             expiration = datetime.datetime.strptime(
-                expiration, "%Y-%m-%dT%H:%M:%SZ"
+                expiration, "%Y-%m-%dT%H:%M:%S%z"
             )
             refresh_interval = self._config.get(
                 "ec2_credential_refresh_window", 60 * 10
             )
             refresh_interval_with_jitter = refresh_interval + random.randint(120, 600)
-            current_time = datetime.datetime.utcnow()
+            current_time = datetime.datetime.now(datetime.timezone.utc)
             refresh_offset = datetime.timedelta(seconds=refresh_interval_with_jitter)
             extension_time = expiration - refresh_offset
             if current_time >= extension_time:
diff --git a/awscli/compat.py b/awscli/compat.py
index 4ea633b..1031356 100644
--- a/awscli/compat.py
+++ b/awscli/compat.py
@@ -25,6 +25,8 @@ from functools import partial
 import urllib.parse as urlparse
 from urllib.error import URLError
 
+import queue
+import urllib.request
 from botocore.compat import six
 from botocore.compat import OrderedDict
 
@@ -33,11 +35,10 @@ from botocore.compat import OrderedDict
 # This may get large.
 advance_iterator = six.advance_iterator
 PY3 = six.PY3
-queue = six.moves.queue
-shlex_quote = six.moves.shlex_quote
+shlex_quote = shlex.quote
 StringIO = six.StringIO
 BytesIO = six.BytesIO
-urlopen = six.moves.urllib.request.urlopen
+urlopen = urllib.request.urlopen
 binary_type = six.binary_type
 
 # Most, but not all, python installations will have zlib. This is required to
diff --git a/awscli/customizations/cloudformation/deployer.py b/awscli/customizations/cloudformation/deployer.py
index 3733c55..8236d33 100644
--- a/awscli/customizations/cloudformation/deployer.py
+++ b/awscli/customizations/cloudformation/deployer.py
@@ -20,7 +20,7 @@ import collections
 from awscli.customizations.cloudformation import exceptions
 from awscli.customizations.cloudformation.artifact_exporter import mktempfile, parse_s3_url
 
-from datetime import datetime
+from datetime import datetime, timezone
 
 LOG = logging.getLogger(__name__)
 
@@ -85,7 +85,7 @@ class Deployer(object):
         :return:
         """
 
-        now = datetime.utcnow().isoformat()
+        now = datetime.now(timezone.utc).isoformat()
         description = "Created by AWS CLI at {0} UTC".format(now)
 
         # Each changeset will get a unique name based on time
diff --git a/awscli/customizations/cloudtrail/validation.py b/awscli/customizations/cloudtrail/validation.py
index 78e2540..ad13507 100644
--- a/awscli/customizations/cloudtrail/validation.py
+++ b/awscli/customizations/cloudtrail/validation.py
@@ -19,7 +19,7 @@ import re
 import sys
 import zlib
 from zlib import error as ZLibError
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
 from dateutil import tz, parser
 
 import cryptography
@@ -401,7 +401,7 @@ class DigestTraverser(object):
         :param end_date: Date to stop validating at (inclusive).
         """
         if end_date is None:
-            end_date = datetime.utcnow()
+            end_date = datetime.now(timezone.utc)
         end_date = normalize_date(end_date)
         start_date = normalize_date(start_date)
         bucket = self.starting_bucket
@@ -703,7 +703,7 @@ class CloudTrailValidateLogs(BasicCommand):
         if args.end_time:
             self.end_time = normalize_date(parse_date(args.end_time))
         else:
-            self.end_time = normalize_date(datetime.utcnow())
+            self.end_time = datetime.now(timezone.utc)
         if self.start_time > self.end_time:
             raise ParamValidationError(
                 'Invalid time range specified: start-time must '
diff --git a/awscli/customizations/codecommit.py b/awscli/customizations/codecommit.py
index 6b30e83..7859fb8 100644
--- a/awscli/customizations/codecommit.py
+++ b/awscli/customizations/codecommit.py
@@ -150,7 +150,7 @@ class CodeCommitGetCommand(BasicCommand):
         request = AWSRequest()
         request.url = url_to_sign
         request.method = 'GIT'
-        now = datetime.datetime.utcnow()
+        now = datetime.datetime.now(datetime.timezone.utc)
         request.context['timestamp'] = now.strftime('%Y%m%dT%H%M%S')
         split = urlsplit(request.url)
         # we don't want to include the port number in the signature
diff --git a/awscli/customizations/codedeploy/push.py b/awscli/customizations/codedeploy/push.py
index 4c08664..6d97c8c 100644
--- a/awscli/customizations/codedeploy/push.py
+++ b/awscli/customizations/codedeploy/push.py
@@ -16,7 +16,7 @@ import sys
 import zipfile
 import tempfile
 import contextlib
-from datetime import datetime
+from datetime import datetime, timezone
 
 from botocore.exceptions import ClientError
 
@@ -133,7 +133,7 @@ class Push(BasicCommand):
         if not parsed_args.description:
             parsed_args.description = (
                 'Uploaded by AWS CLI {0} UTC'.format(
-                    datetime.utcnow().isoformat()
+                    datetime.now(timezone.utc).isoformat()
                 )
             )
 
diff --git a/awscli/customizations/configure/__init__.py b/awscli/customizations/configure/__init__.py
index ab06305..55f11a9 100644
--- a/awscli/customizations/configure/__init__.py
+++ b/awscli/customizations/configure/__init__.py
@@ -11,7 +11,7 @@
 # ANY KIND, either express or implied. See the License for the specific
 # language governing permissions and limitations under the License.
 import string
-from botocore.vendored.six.moves import shlex_quote
+from shlex import quote as shlex_quote
 
 NOT_SET = '<not set>'
 PREDEFINED_SECTION_NAMES = ('plugins')
diff --git a/awscli/customizations/datapipeline/__init__.py b/awscli/customizations/datapipeline/__init__.py
index c47ca94..0c12c39 100644
--- a/awscli/customizations/datapipeline/__init__.py
+++ b/awscli/customizations/datapipeline/__init__.py
@@ -12,7 +12,7 @@
 # language governing permissions and limitations under the License.
 
 import json
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
 
 from awscli.formatter import get_formatter
 from awscli.arguments import CustomArgument
@@ -186,7 +186,7 @@ class QueryArgBuilder(object):
     """
     def __init__(self, current_time=None):
         if current_time is None:
-            current_time = datetime.utcnow()
+            current_time = datetime.now(timezone.utc)
         self.current_time = current_time
 
     def build_query(self, parsed_args):
diff --git a/awscli/customizations/ec2/bundleinstance.py b/awscli/customizations/ec2/bundleinstance.py
index 96d9ece..ad4dca0 100644
--- a/awscli/customizations/ec2/bundleinstance.py
+++ b/awscli/customizations/ec2/bundleinstance.py
@@ -120,7 +120,7 @@ def _generate_policy(params):
     # Called if there is no policy supplied by the user.
     # Creates a policy that provides access for 24 hours.
     delta = datetime.timedelta(hours=24)
-    expires = datetime.datetime.utcnow() + delta
+    expires = datetime.datetime.now(datetime.timezone.utc) + delta
     expires_iso = expires.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
     policy = POLICY.format(expires=expires_iso,
                            bucket=params['Bucket'],
diff --git a/awscli/customizations/eks/get_token.py b/awscli/customizations/eks/get_token.py
index c85b86d..9812be4 100644
--- a/awscli/customizations/eks/get_token.py
+++ b/awscli/customizations/eks/get_token.py
@@ -16,7 +16,7 @@ import json
 import os
 import sys
 
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
 from botocore.signers import RequestSigner
 from botocore.model import ServiceId
 
@@ -106,7 +106,7 @@ class GetTokenCommand(BasicCommand):
     ]
 
     def get_expiration_time(self):
-        token_expiration = datetime.utcnow() + timedelta(
+        token_expiration = datetime.now(timezone.utc) + timedelta(
             minutes=TOKEN_EXPIRATION_MINS
         )
         return token_expiration.strftime('%Y-%m-%dT%H:%M:%SZ')
diff --git a/awscli/customizations/logs/tail.py b/awscli/customizations/logs/tail.py
index cb31510..623e027 100644
--- a/awscli/customizations/logs/tail.py
+++ b/awscli/customizations/logs/tail.py
@@ -11,7 +11,8 @@
 # ANY KIND, either express or implied. See the License for the specific
 # language governing permissions and limitations under the License.
 from collections import defaultdict
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
+import functools
 import json
 import re
 import time
@@ -261,7 +262,7 @@ class TimestampUtils(object):
     def __init__(self, now=None):
         self._now = now
         if now is None:
-            self._now = datetime.utcnow
+            self._now = functools.partial(datetime.now, timezone.utc)
 
     def to_epoch_millis(self, timestamp):
         re_match = self._RELATIVE_TIMESTAMP_REGEX.match(timestamp)
diff --git a/awscli/customizations/opsworks.py b/awscli/customizations/opsworks.py
index a2a0c1e..ff73132 100644
--- a/awscli/customizations/opsworks.py
+++ b/awscli/customizations/opsworks.py
@@ -507,7 +507,7 @@ class OpsWorksRegister(BasicCommand):
             "Resource": arn,
         }
         if timeout is not None:
-            valid_until = datetime.datetime.utcnow() + timeout
+            valid_until = datetime.datetime.now(datetime.timezone.utc) + timeout
             statement["Condition"] = {
                 "DateLessThan": {
                     "aws:CurrentTime":
diff --git a/tests/functional/botocore/test_credentials.py b/tests/functional/botocore/test_credentials.py
index 843be90..0349eb4 100644
--- a/tests/functional/botocore/test_credentials.py
+++ b/tests/functional/botocore/test_credentials.py
@@ -19,7 +19,7 @@ import time
 import mock
 import tempfile
 import shutil
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
 import sys
 
 import pytest
@@ -47,8 +47,8 @@ from botocore.stub import Stubber
 from botocore.tokens import SSOTokenProvider
 from botocore.utils import datetime2timestamp
 
-TIME_IN_ONE_HOUR = datetime.utcnow() + timedelta(hours=1)
-TIME_IN_SIX_MONTHS = datetime.utcnow() + timedelta(hours=4320)
+TIME_IN_ONE_HOUR = datetime.now(timezone.utc) + timedelta(hours=1)
+TIME_IN_SIX_MONTHS = datetime.now(timezone.utc) + timedelta(hours=4320)
 
 
 class TestCredentialRefreshRaces(unittest.TestCase):
diff --git a/tests/functional/botocore/test_ec2.py b/tests/functional/botocore/test_ec2.py
index 795094e..3ff22c4 100644
--- a/tests/functional/botocore/test_ec2.py
+++ b/tests/functional/botocore/test_ec2.py
@@ -86,13 +86,13 @@ class TestCopySnapshotCustomization(BaseSessionTest):
             '<snapshotId>%s</snapshotId>\n'
             '</CopySnapshotResponse>\n'
         )
-        self.now = datetime.datetime(2011, 9, 9, 23, 36)
+        self.now = datetime.datetime(2011, 9, 9, 23, 36, tzinfo=datetime.timezone.utc)
         self.datetime_patch = mock.patch.object(
             botocore.auth.datetime, 'datetime',
             mock.Mock(wraps=datetime.datetime)
         )
         self.mocked_datetime = self.datetime_patch.start()
-        self.mocked_datetime.utcnow.return_value = self.now
+        self.mocked_datetime.now.return_value = self.now
 
     def tearDown(self):
         super(TestCopySnapshotCustomization, self).tearDown()
diff --git a/tests/functional/botocore/test_lex.py b/tests/functional/botocore/test_lex.py
index 7e7f619..dbdf329 100644
--- a/tests/functional/botocore/test_lex.py
+++ b/tests/functional/botocore/test_lex.py
@@ -11,7 +11,7 @@
 # ANY KIND, either express or implied. See the License for the specific
 # language governing permissions and limitations under the License.
 import mock
-from datetime import datetime
+from datetime import datetime, timezone
 
 from tests import BaseSessionTest, ClientHTTPStubber
 
@@ -32,10 +32,10 @@ class TestLex(BaseSessionTest):
             'inputStream': b''
         }
 
-        timestamp = datetime(2017, 3, 22, 0, 0)
+        timestamp = datetime(2017, 3, 22, 0, 0, tzinfo=timezone.utc)
 
         with mock.patch('botocore.auth.datetime') as _datetime:
-            _datetime.datetime.utcnow.return_value = timestamp
+            _datetime.datetime.now.return_value = timestamp
             self.http_stubber.add_response(body=b'{}')
             with self.http_stubber:
                 self.client.post_content(**params)
diff --git a/tests/functional/botocore/test_s3express.py b/tests/functional/botocore/test_s3express.py
index 390721e..ebb89b0 100644
--- a/tests/functional/botocore/test_s3express.py
+++ b/tests/functional/botocore/test_s3express.py
@@ -108,7 +108,6 @@ class TestS3ExpressAuth:
 class TestS3ExpressIdentityCache:
     def test_default_s3_express_cache(self, default_s3_client, mock_datetime):
         mock_datetime.now.return_value = DATE
-        mock_datetime.utcnow.return_value = DATE
 
         identity_cache = S3ExpressIdentityCache(
             default_s3_client,
@@ -126,7 +125,6 @@ class TestS3ExpressIdentityCache:
         self, default_s3_client, mock_datetime
     ):
         mock_datetime.now.return_value = DATE
-        mock_datetime.utcnow.return_value = DATE
         bucket = 'my_bucket'
 
         identity_cache = S3ExpressIdentityCache(
@@ -151,7 +149,6 @@ class TestS3ExpressIdentityCache:
         self, default_s3_client, mock_datetime
     ):
         mock_datetime.now.return_value = DATE
-        mock_datetime.utcnow.return_value = DATE
         bucket = 'my_bucket'
         other_bucket = 'other_bucket'
 
@@ -204,7 +201,7 @@ class TestS3ExpressRequests:
         )
 
     def test_create_bucket(self, default_s3_client, mock_datetime):
-        mock_datetime.utcnow.return_value = DATE
+        mock_datetime.now.return_value = DATE
 
         with ClientHTTPStubber(default_s3_client) as stubber:
             stubber.add_response()
@@ -228,7 +225,6 @@ class TestS3ExpressRequests:
         self._assert_standard_sigv4_signature(stubber.requests[0].headers)
 
     def test_get_object(self, default_s3_client, mock_datetime):
-        mock_datetime.utcnow.return_value = DATE
         mock_datetime.now.return_value = DATE
 
         with ClientHTTPStubber(default_s3_client) as stubber:
@@ -250,7 +246,6 @@ class TestS3ExpressRequests:
     def test_cache_with_multiple_requests(
         self, default_s3_client, mock_datetime
     ):
-        mock_datetime.utcnow.return_value = DATE
         mock_datetime.now.return_value = DATE
 
         with ClientHTTPStubber(default_s3_client) as stubber:
@@ -275,7 +270,6 @@ class TestS3ExpressRequests:
     def test_delete_objects_injects_correct_checksum(
         self, default_s3_client, mock_datetime
     ):
-        mock_datetime.utcnow.return_value = DATE
         mock_datetime.now.return_value = DATE
 
         with ClientHTTPStubber(default_s3_client) as stubber:
diff --git a/tests/functional/botocore/test_sts.py b/tests/functional/botocore/test_sts.py
index cdc212a..a279881 100644
--- a/tests/functional/botocore/test_sts.py
+++ b/tests/functional/botocore/test_sts.py
@@ -10,7 +10,7 @@
 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 # ANY KIND, either express or implied. See the License for the specific
 # language governing permissions and limitations under the License.
-from datetime import datetime
+from datetime import datetime, timezone
 import re
 
 import mock
@@ -38,9 +38,9 @@ class TestSTSPresignedUrl(BaseSessionTest):
         self.stubber.activate()
 
     def test_presigned_url_contains_no_content_type(self):
-        timestamp = datetime(2017, 3, 22, 0, 0)
+        timestamp = datetime(2017, 3, 22, 0, 0, tzinfo=timezone.utc)
         with mock.patch('botocore.auth.datetime') as _datetime:
-            _datetime.datetime.utcnow.return_value = timestamp
+            _datetime.datetime.now.return_value = timestamp
             url = self.client.generate_presigned_url('get_caller_identity', {})
 
         # There should be no 'content-type' in x-amz-signedheaders
diff --git a/tests/functional/ec2/test_bundle_instance.py b/tests/functional/ec2/test_bundle_instance.py
index 5bc3204..67015f0 100644
--- a/tests/functional/ec2/test_bundle_instance.py
+++ b/tests/functional/ec2/test_bundle_instance.py
@@ -34,7 +34,7 @@ class TestBundleInstance(BaseAWSCommandParamsTest):
 
     def setUp(self):
         super(TestBundleInstance, self).setUp()
-        # This mocks out datetime.datetime.utcnow() so that it always
+        # This mocks out datetime.datetime.now() so that it always
         # returns the same datetime object.  This is because this value
         # is embedded into the policy file that is generated and we
         # don't what the policy or its signature to change each time
@@ -44,7 +44,7 @@ class TestBundleInstance(BaseAWSCommandParamsTest):
             mock.Mock(wraps=datetime.datetime)
         )
         mocked_datetime = self.datetime_patcher.start()
-        mocked_datetime.utcnow.return_value = datetime.datetime(2013, 8, 9)
+        mocked_datetime.now.return_value = datetime.datetime(2013, 8, 9, tzinfo=datetime.timezone.utc)
 
     def tearDown(self):
         super(TestBundleInstance, self).tearDown()
diff --git a/tests/functional/ec2instanceconnect/test_opentunnel.py b/tests/functional/ec2instanceconnect/test_opentunnel.py
index 83f824d..ddefc47 100644
--- a/tests/functional/ec2instanceconnect/test_opentunnel.py
+++ b/tests/functional/ec2instanceconnect/test_opentunnel.py
@@ -310,10 +310,10 @@ def request_params_for_describe_eice():
 
 
 @pytest.fixture
-def datetime_utcnow_patch():
+def datetime_now_patch():
     clock = datetime.datetime(2020, 1, 1, 1, 1, 1, tzinfo=tzutc())
     with mock.patch('datetime.datetime') as dt:
-        dt.utcnow.return_value = clock
+        dt.now.return_value = clock
         yield dt
 
 
@@ -393,7 +393,7 @@ class TestOpenTunnel:
             describe_eice_response,
             request_params_for_describe_instance,
             request_params_for_describe_eice,
-            datetime_utcnow_patch,
+            datetime_now_patch,
     ):
         cli_runner.env["AWS_USE_FIPS_ENDPOINT"] = "false"
         cmdline = [
diff --git a/tests/functional/eks/test_get_token.py b/tests/functional/eks/test_get_token.py
index 89801f9..cdf51f7 100644
--- a/tests/functional/eks/test_get_token.py
+++ b/tests/functional/eks/test_get_token.py
@@ -11,7 +11,7 @@
 # ANY KIND, either express or implied. See the License for the specific
 # language governing permissions and limitations under the License.
 import base64
-from datetime import datetime
+from datetime import datetime, timezone
 import json
 import os
 
@@ -80,7 +80,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest):
 
     @mock.patch('awscli.customizations.eks.get_token.datetime')
     def test_get_token(self, mock_datetime):
-        mock_datetime.utcnow.return_value = datetime(2019, 10, 23, 23, 0, 0, 0)
+        mock_datetime.now.return_value = datetime(2019, 10, 23, 23, 0, 0, 0, tzinfo=timezone.utc)
         cmd = 'eks get-token --cluster-name %s' % self.cluster_name
         response = self.run_get_token(cmd)
         self.assertEqual(
@@ -98,7 +98,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest):
 
     @mock.patch('awscli.customizations.eks.get_token.datetime')
     def test_query_nested_object(self, mock_datetime):
-        mock_datetime.utcnow.return_value = datetime(2019, 10, 23, 23, 0, 0, 0)
+        mock_datetime.now.return_value = datetime(2019, 10, 23, 23, 0, 0, 0, tzinfo=timezone.utc)
         cmd = 'eks get-token --cluster-name %s' % self.cluster_name
         cmd += ' --query status'
         response = self.run_get_token(cmd)
@@ -120,7 +120,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest):
 
     @mock.patch('awscli.customizations.eks.get_token.datetime')
     def test_output_text(self, mock_datetime):
-        mock_datetime.utcnow.return_value = datetime(2019, 10, 23, 23, 0, 0, 0)
+        mock_datetime.now.return_value = datetime(2019, 10, 23, 23, 0, 0, 0, tzinfo=timezone.utc)
         cmd = 'eks get-token --cluster-name %s' % self.cluster_name
         cmd += ' --output text'
         stdout, _, _ = self.run_cmd(cmd)
@@ -130,7 +130,7 @@ class TestGetTokenCommand(BaseAWSCommandParamsTest):
 
     @mock.patch('awscli.customizations.eks.get_token.datetime')
     def test_output_table(self, mock_datetime):
-        mock_datetime.utcnow.return_value = datetime(2019, 10, 23, 23, 0, 0, 0)
+        mock_datetime.now.return_value = datetime(2019, 10, 23, 23, 0, 0, 0, tzinfo=timezone.utc)
         cmd = 'eks get-token --cluster-name %s' % self.cluster_name
         cmd += ' --output table'
         stdout, _, _ = self.run_cmd(cmd)
diff --git a/tests/functional/logs/test_tail.py b/tests/functional/logs/test_tail.py
index 6049a7f..5707da9 100644
--- a/tests/functional/logs/test_tail.py
+++ b/tests/functional/logs/test_tail.py
@@ -152,7 +152,7 @@ class TestTailCommand(BaseAWSCommandParamsTest):
 
     def test_tail_defaults_to_10m(self):
         datetime_mock = mock.Mock(wraps=datetime)
-        datetime_mock.utcnow = mock.Mock(
+        datetime_mock.now = mock.Mock(
             return_value=datetime(1970, 1, 1, 0, 10, 1, tzinfo=tz.tzutc()))
         with mock.patch('awscli.customizations.logs.tail.datetime',
                         new=datetime_mock):
@@ -177,7 +177,7 @@ class TestTailCommand(BaseAWSCommandParamsTest):
 
     def test_tail_with_relative_since(self):
         datetime_mock = mock.Mock(wraps=datetime)
-        datetime_mock.utcnow = mock.Mock(
+        datetime_mock.now = mock.Mock(
             return_value=datetime(1970, 1, 1, 0, 0, 2, tzinfo=tz.tzutc()))
         with mock.patch('awscli.customizations.logs.tail.datetime',
                         new=datetime_mock):
diff --git a/tests/functional/rds/test_generate_db_auth_token.py b/tests/functional/rds/test_generate_db_auth_token.py
index 795b939..4562b92 100644
--- a/tests/functional/rds/test_generate_db_auth_token.py
+++ b/tests/functional/rds/test_generate_db_auth_token.py
@@ -53,7 +53,7 @@ class TestGenerateDBAuthToken(BaseAWSCommandParamsTest):
         clock = datetime.datetime(2016, 11, 7, 17, 39, 33, tzinfo=tzutc())
 
         with mock.patch('datetime.datetime') as dt:
-            dt.utcnow.return_value = clock
+            dt.now.return_value = clock
             stdout, _, _ = self.run_cmd(command, expected_rc=0)
 
         expected = (
diff --git a/tests/functional/s3/test_presign_command.py b/tests/functional/s3/test_presign_command.py
index 2db338a..03741d1 100644
--- a/tests/functional/s3/test_presign_command.py
+++ b/tests/functional/s3/test_presign_command.py
@@ -18,13 +18,13 @@ from awscli.testutils import BaseAWSCommandParamsTest, mock, temporary_file
 from awscli.testutils import create_clidriver
 
 
-# Values used to fix time.time() and datetime.datetime.utcnow()
+# Values used to fix time.time() and datetime.datetime.now()
 # so we know the exact values of the signatures generated.
 FROZEN_TIMESTAMP = 1471305652
 DEFAULT_EXPIRES = 3600
 FROZEN_TIME = mock.Mock(return_value=FROZEN_TIMESTAMP)
 FROZEN_DATETIME = mock.Mock(
-    return_value=datetime.datetime(2016, 8, 18, 14, 33, 3, 0))
+    return_value=datetime.datetime(2016, 8, 18, 14, 33, 3, 0, tzinfo=datetime.timezone.utc))
 
 
 class TestPresignCommand(BaseAWSCommandParamsTest):
@@ -78,7 +78,7 @@ class TestPresignCommand(BaseAWSCommandParamsTest):
     def get_presigned_url_for_cmd(self, cmdline):
         with mock.patch('time.time', FROZEN_TIME):
             with mock.patch('datetime.datetime') as d:
-                d.utcnow = FROZEN_DATETIME
+                d.now = FROZEN_DATETIME
                 stdout = self.assert_params_for_cmd(cmdline, None)[0].strip()
                 return stdout
 
diff --git a/tests/integration/botocore/test_client_http.py b/tests/integration/botocore/test_client_http.py
index d6b0902..4e66fdf 100644
--- a/tests/integration/botocore/test_client_http.py
+++ b/tests/integration/botocore/test_client_http.py
@@ -8,7 +8,8 @@ from contextlib import contextmanager
 
 import botocore.session
 from botocore.config import Config
-from botocore.vendored.six.moves import BaseHTTPServer, socketserver
+from http import server as BaseHTTPServer
+import socketserver
 from botocore.exceptions import (
     ConnectTimeoutError, ReadTimeoutError, EndpointConnectionError,
     ConnectionClosedError, ClientError, ProxyConnectionError
diff --git a/tests/integration/customizations/test_codecommit.py b/tests/integration/customizations/test_codecommit.py
index 751e051..fc4d2c1 100644
--- a/tests/integration/customizations/test_codecommit.py
+++ b/tests/integration/customizations/test_codecommit.py
@@ -14,7 +14,7 @@
 import awscli
 import os
 
-from datetime import datetime
+from datetime import datetime, timezone
 
 from six import StringIO
 from botocore.session import Session
@@ -59,7 +59,7 @@ class TestCodeCommitCredentialHelper(unittest.TestCase):
     @mock.patch('sys.stdout', new_callable=StringIOWithFileNo)
     @mock.patch.object(awscli.customizations.codecommit.datetime, 'datetime')
     def test_integration_using_cli_driver(self, dt_mock, stdout_mock):
-        dt_mock.utcnow.return_value = datetime(2010, 10, 8)
+        dt_mock.now.return_value = datetime(2010, 10, 8, tzinfo=timezone.utc)
         driver = create_clidriver()
         entry_point = AWSCLIEntryPoint(driver)
         rc = entry_point.main('codecommit credential-helper get'.split())
@@ -75,7 +75,7 @@ class TestCodeCommitCredentialHelper(unittest.TestCase):
     @mock.patch('sys.stdout', new_callable=StringIOWithFileNo)
     @mock.patch.object(awscli.customizations.codecommit.datetime, 'datetime')
     def test_integration_fips_using_cli_driver(self, dt_mock, stdout_mock):
-        dt_mock.utcnow.return_value = datetime(2010, 10, 8)
+        dt_mock.now.return_value = datetime(2010, 10, 8, tzinfo=timezone.utc)
         driver = create_clidriver()
         entry_point = AWSCLIEntryPoint(driver)
         rc = entry_point.main('codecommit credential-helper get'.split())
@@ -91,7 +91,7 @@ class TestCodeCommitCredentialHelper(unittest.TestCase):
     @mock.patch('sys.stdout', new_callable=StringIOWithFileNo)
     @mock.patch.object(awscli.customizations.codecommit.datetime, 'datetime')
     def test_integration_vpc_using_cli_driver(self, dt_mock, stdout_mock):
-        dt_mock.utcnow.return_value = datetime(2010, 10, 8)
+        dt_mock.now.return_value = datetime(2010, 10, 8, tzinfo=timezone.utc)
         driver = create_clidriver()
         entry_point = AWSCLIEntryPoint(driver)
         rc = entry_point.main('codecommit credential-helper get'.split())
diff --git a/tests/unit/botocore/auth/test_signers.py b/tests/unit/botocore/auth/test_signers.py
index 73d3b12..25ca21f 100644
--- a/tests/unit/botocore/auth/test_signers.py
+++ b/tests/unit/botocore/auth/test_signers.py
@@ -28,10 +28,10 @@ from botocore.awsrequest import AWSRequest
 
 class BaseTestWithFixedDate(unittest.TestCase):
     def setUp(self):
-        self.fixed_date = datetime.datetime(2014, 3, 10, 17, 2, 55, 0)
+        self.fixed_date = datetime.datetime(2014, 3, 10, 17, 2, 55, 0, tzinfo=datetime.timezone.utc)
         self.datetime_patch = mock.patch('botocore.auth.datetime.datetime')
         self.datetime_mock = self.datetime_patch.start()
-        self.datetime_mock.utcnow.return_value = self.fixed_date
+        self.datetime_mock.now.return_value = self.fixed_date
         self.datetime_mock.strptime.return_value = self.fixed_date
 
     def tearDown(self):
@@ -358,9 +358,9 @@ class TestSigV4(unittest.TestCase):
         with mock.patch.object(
                 botocore.auth.datetime, 'datetime',
                 mock.Mock(wraps=datetime.datetime)) as mock_datetime:
-            original_utcnow = datetime.datetime(2014, 1, 1, 0, 0)
+            original_now = datetime.datetime(2014, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)
 
-            mock_datetime.utcnow.return_value = original_utcnow
+            mock_datetime.now.return_value = original_now
             # Go through the add_auth process once. This will attach
             # a timestamp to the request at the beginning of auth.
             auth.add_auth(request)
@@ -368,8 +368,8 @@ class TestSigV4(unittest.TestCase):
             # Ensure the date is in the Authorization header
             self.assertIn('20140101', request.headers['Authorization'])
             # Now suppose the utc time becomes the next day all of a sudden
-            mock_datetime.utcnow.return_value = datetime.datetime(
-                2014, 1, 2, 0, 0)
+            mock_datetime.now.return_value = datetime.datetime(
+                2014, 1, 2, 0, 0, tzinfo=datetime.timezone.utc)
             # Smaller methods like the canonical request and string_to_sign
             # should  have the timestamp attached to the request in their
             # body and not what the time is now mocked as. This is to ensure
@@ -535,8 +535,8 @@ class TestSigV4Presign(BasePresignTest):
             mock.Mock(wraps=datetime.datetime)
         )
         mocked_datetime = self.datetime_patcher.start()
-        mocked_datetime.utcnow.return_value = datetime.datetime(
-            2014, 1, 1, 0, 0)
+        mocked_datetime.now.return_value = datetime.datetime(
+            2014, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)
 
     def tearDown(self):
         self.datetime_patcher.stop()
@@ -730,8 +730,8 @@ class TestS3SigV4Post(BaseS3PresignPostTest):
             mock.Mock(wraps=datetime.datetime)
         )
         mocked_datetime = self.datetime_patcher.start()
-        mocked_datetime.utcnow.return_value = datetime.datetime(
-            2014, 1, 1, 0, 0)
+        mocked_datetime.now.return_value = datetime.datetime(
+            2014, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)
 
     def tearDown(self):
         self.datetime_patcher.stop()
diff --git a/tests/unit/botocore/test_client.py b/tests/unit/botocore/test_client.py
index f28b959..1b3d56b 100644
--- a/tests/unit/botocore/test_client.py
+++ b/tests/unit/botocore/test_client.py
@@ -960,7 +960,7 @@ class TestAutoGeneratedClient(unittest.TestCase):
         lines = [
             ('    Creates an iterator that will paginate through responses '
              'from :py:meth:`MyService.Client.test_operation`.'),
-            '    **Request Syntax** ',
+            '    **Request Syntax**',
             '    ::',
             '      response_iterator = paginator.paginate(',
             "          Foo='string',",
@@ -976,17 +976,17 @@ class TestAutoGeneratedClient(unittest.TestCase):
             '    :type Bar: string',
             '    :param Bar: Documents Bar',
             '    :type PaginationConfig: dict',
-            '    :param PaginationConfig: ',
+            '    :param PaginationConfig:',
             ('      A dictionary that provides parameters to control '
              'pagination.'),
-            '      - **MaxItems** *(integer) --* ',
+            '      - **MaxItems** *(integer) --*',
             ('        The total number of items to return. If the total '
              'number of items available is more than the value specified '
              'in max-items then a ``NextToken`` will be provided in the '
              'output that you can use to resume pagination.'),
-            '      - **PageSize** *(integer) --* ',
+            '      - **PageSize** *(integer) --*',
             '        The size of each page.',
-            '      - **StartingToken** *(string) --* ',
+            '      - **StartingToken** *(string) --*',
             ('        A token to specify where to start paginating. This is '
              'the ``NextToken`` from a previous response.'),
             '    :returns: None',
diff --git a/tests/unit/botocore/test_credentials.py b/tests/unit/botocore/test_credentials.py
index c59f278..c50f593 100644
--- a/tests/unit/botocore/test_credentials.py
+++ b/tests/unit/botocore/test_credentials.py
@@ -11,7 +11,7 @@
 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 # ANY KIND, either express or implied. See the License for the specific
 # language governing permissions and limitations under the License.
-from datetime import datetime, timedelta
+from datetime import datetime, timedelta, timezone
 import subprocess
 import mock
 import os
@@ -111,7 +111,7 @@ class TestRefreshableCredentials(TestCredentials):
 
     def test_refresh_needed(self):
         # The expiry time was set for 30 minutes ago, so if we
-        # say the current time is utcnow(), then we should need
+        # say the current time is now(), then we should need
         # a refresh.
         self.mock_time.return_value = datetime.now(tzlocal())
         self.assertTrue(self.creds.refresh_needed())
@@ -291,8 +291,8 @@ class TestAssumeRoleCredentialFetcher(BaseEnvVar):
         self.assertEqual(response, expected_response)
 
     def test_retrieves_from_cache(self):
-        date_in_future = datetime.utcnow() + timedelta(seconds=1000)
-        utc_timestamp = date_in_future.isoformat() + 'Z'
+        date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000)
+        utc_timestamp = date_in_future.isoformat()
         cache_key = (
             '793d6e2f27667ab2da104824407e486bfec24a47'
         )
@@ -703,8 +703,8 @@ class TestAssumeRoleWithWebIdentityCredentialFetcher(BaseEnvVar):
         self.assertEqual(response, expected_response)
 
     def test_retrieves_from_cache(self):
-        date_in_future = datetime.utcnow() + timedelta(seconds=1000)
-        utc_timestamp = date_in_future.isoformat() + 'Z'
+        date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000)
+        utc_timestamp = date_in_future.isoformat()
         cache_key = (
             '793d6e2f27667ab2da104824407e486bfec24a47'
         )
@@ -823,8 +823,8 @@ class TestAssumeRoleWithWebIdentityCredentialProvider(unittest.TestCase):
         mock_loader_cls.assert_called_with('/some/path/token.jwt')
 
     def test_assume_role_retrieves_from_cache(self):
-        date_in_future = datetime.utcnow() + timedelta(seconds=1000)
-        utc_timestamp = date_in_future.isoformat() + 'Z'
+        date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000)
+        utc_timestamp = date_in_future.isoformat()
 
         cache_key = (
             'c29461feeacfbed43017d20612606ff76abc073d'
@@ -1961,8 +1961,8 @@ class TestAssumeRoleCredentialProvider(unittest.TestCase):
         self.assertEqual(expiry_time, '2016-11-06T01:30:00UTC')
 
     def test_assume_role_retrieves_from_cache(self):
-        date_in_future = datetime.utcnow() + timedelta(seconds=1000)
-        utc_timestamp = date_in_future.isoformat() + 'Z'
+        date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000)
+        utc_timestamp = date_in_future.isoformat()
         self.fake_config['profiles']['development']['role_arn'] = 'myrole'
 
         cache_key = (
@@ -1989,8 +1989,8 @@ class TestAssumeRoleCredentialProvider(unittest.TestCase):
         self.assertEqual(creds.token, 'baz-cached')
 
     def test_chain_prefers_cache(self):
-        date_in_future = datetime.utcnow() + timedelta(seconds=1000)
-        utc_timestamp = date_in_future.isoformat() + 'Z'
+        date_in_future = datetime.now(timezone.utc) + timedelta(seconds=1000)
+        utc_timestamp = date_in_future.isoformat()
 
         # The profile we will be using has a cache entry, but the profile it
         # is sourcing from does not. This should result in the cached
diff --git a/tests/unit/botocore/test_signers.py b/tests/unit/botocore/test_signers.py
index e06e0c1..507e2ea 100644
--- a/tests/unit/botocore/test_signers.py
+++ b/tests/unit/botocore/test_signers.py
@@ -609,9 +609,9 @@ class TestS3PostPresigner(BaseSignerTest):
 
         self.datetime_patch = mock.patch('botocore.signers.datetime')
         self.datetime_mock = self.datetime_patch.start()
-        self.fixed_date = datetime.datetime(2014, 3, 10, 17, 2, 55, 0)
+        self.fixed_date = datetime.datetime(2014, 3, 10, 17, 2, 55, 0, tzinfo=datetime.timezone.utc)
         self.fixed_delta = datetime.timedelta(seconds=3600)
-        self.datetime_mock.datetime.utcnow.return_value = self.fixed_date
+        self.datetime_mock.datetime.now.return_value = self.fixed_date
         self.datetime_mock.timedelta.return_value = self.fixed_delta
 
     def tearDown(self):
@@ -979,7 +979,7 @@ class TestGenerateDBAuthToken(BaseSignerTest):
         clock = datetime.datetime(2016, 11, 7, 17, 39, 33, tzinfo=tzutc())
 
         with mock.patch('datetime.datetime') as dt:
-            dt.utcnow.return_value = clock
+            dt.now.return_value = clock
             result = generate_db_auth_token(
                 self.client, hostname, port, username)
 
diff --git a/tests/unit/botocore/test_utils.py b/tests/unit/botocore/test_utils.py
index 1f27e25..8116070 100644
--- a/tests/unit/botocore/test_utils.py
+++ b/tests/unit/botocore/test_utils.py
@@ -98,7 +98,7 @@ from botocore.stub import Stubber
 from botocore.config import Config
 from botocore.endpoint_provider import RuleSetEndpoint
 
-DATE = datetime.datetime(2021, 12, 10, 00, 00, 00)
+DATE = datetime.datetime(2021, 12, 10, 00, 00, 00, tzinfo=datetime.timezone.utc)
 DT_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
 
 
@@ -1004,7 +1004,7 @@ class TestSwitchToChunkedEncodingForNonSeekableObjects(unittest.TestCase):
     def test_switch_to_chunked_encodeing_for_stream_like_object(self):
         request = AWSRequest(
             method='POST', headers={},
-            data=io.BufferedIOBase(b"some initial binary data"),
+            data=io.BufferedIOBase(),
             url='https://foo.amazonaws.com/bucket/key.txt'
         )
         prepared_request = request.prepare()
@@ -2819,7 +2819,7 @@ class TestInstanceMetadataFetcher(unittest.TestCase):
        self, dt=None, offset=None, offset_func=operator.add
     ):
         if dt is None:
-            dt = datetime.datetime.utcnow()
+            dt = datetime.datetime.now(datetime.timezone.utc)
         if offset is not None:
             dt = offset_func(dt, offset)
 
diff --git a/tests/unit/botocore/test_waiters.py b/tests/unit/botocore/test_waiters.py
index 27fbe1f..b79e173 100644
--- a/tests/unit/botocore/test_waiters.py
+++ b/tests/unit/botocore/test_waiters.py
@@ -648,7 +648,7 @@ class TestCreateWaiter(unittest.TestCase):
             ('    Polls :py:meth:`MyService.Client.foo` every 1 '
              'seconds until a successful state is reached. An error '
              'is returned after 1 failed checks.'),
-            '    **Request Syntax** ',
+            '    **Request Syntax**',
             '    ::',
             '      waiter.wait(',
             "          bar='string'",
diff --git a/tests/unit/customizations/eks/test_get_token.py b/tests/unit/customizations/eks/test_get_token.py
index 17c07b0..0d1b7fc 100644
--- a/tests/unit/customizations/eks/test_get_token.py
+++ b/tests/unit/customizations/eks/test_get_token.py
@@ -49,6 +49,6 @@ class TestGetTokenCommand(BaseTokenTest):
         cmd = GetTokenCommand(self._session)
         timestamp = cmd.get_expiration_time()
         try:
-            datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ')
+            datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S%z')
         except ValueError:
             raise ValueError("Incorrect data format, should be %Y-%m-%dT%H:%M:%SZ")
diff --git a/tests/unit/customizations/test_opsworks.py b/tests/unit/customizations/test_opsworks.py
index 1471ba9..f6816b9 100644
--- a/tests/unit/customizations/test_opsworks.py
+++ b/tests/unit/customizations/test_opsworks.py
@@ -34,8 +34,8 @@ class TestOpsWorksBase(unittest.TestCase):
             mock.Mock(wraps=datetime.datetime)
         )
         mocked_datetime = self.datetime_patcher.start()
-        mocked_datetime.utcnow.return_value = datetime.datetime(
-            2013, 8, 9, 23, 42)
+        mocked_datetime.now.return_value = datetime.datetime(
+            2013, 8, 9, 23, 42, tzinfo=datetime.timezone.utc)
 
     def tearDown(self):
         self.datetime_patcher.stop()
diff --git a/tests/utils/botocore/__init__.py b/tests/utils/botocore/__init__.py
index 9b8f205..abedac8 100644
--- a/tests/utils/botocore/__init__.py
+++ b/tests/utils/botocore/__init__.py
@@ -560,12 +560,12 @@ class FreezeTime(contextlib.ContextDecorator):
     :param module: reference to imported module to patch (e.g. botocore.auth.datetime)
 
     :type date: datetime.datetime
-    :param date: datetime object specifying the output for utcnow()
+    :param date: datetime object specifying the output for now()
     """
 
     def __init__(self, module, date=None):
         if date is None:
-            date = datetime.datetime.utcnow()
+            date = datetime.datetime.now(datetime.timezone.utc)
         self.date = date
         self.datetime_patcher = mock.patch.object(
             module, 'datetime',
@@ -574,7 +574,7 @@ class FreezeTime(contextlib.ContextDecorator):
 
     def __enter__(self, *args, **kwargs):
         mock = self.datetime_patcher.start()
-        mock.utcnow.return_value = self.date
+        mock.now.return_value = self.date
 
     def __exit__(self, *args, **kwargs):
         self.datetime_patcher.stop()
