Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use timezone aware datetimes #6587

Merged
merged 11 commits into from
Nov 11, 2021
2 changes: 1 addition & 1 deletion AUTHORING_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ and 10`.

Always create timezone aware datetime objects. For libraries that use protobuf,
omitting the timezone may lead to unexpected behavior when the datetime
is converted to a protobuf tiemstamp.
is converted to a protobuf timestamp.

```py
import datetime
Expand Down
2 changes: 1 addition & 1 deletion appengine/flexible/datastore/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def index():
entity = datastore.Entity(key=ds.key('visit'))
entity.update({
'user_ip': user_ip,
'timestamp': datetime.datetime.utcnow()
'timestamp': datetime.datetime.now(tz=datetime.timezone.utc)
})

ds.put(entity)
Expand Down
2 changes: 1 addition & 1 deletion appengine/flexible/tasks/create_app_engine_queue_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def create_task(project, queue, location, payload=None, in_seconds=None):

if in_seconds is not None:
# Convert "seconds from now" into an rfc3339 datetime string.
d = datetime.datetime.utcnow() + datetime.timedelta(seconds=in_seconds)
d = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(seconds=in_seconds)

# Create Timestamp protobuf.
timestamp = timestamp_pb2.Timestamp()
Expand Down
2 changes: 1 addition & 1 deletion appengine/standard/mail/user_signup.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get(self):
if code:
record = ndb.Key(UserConfirmationRecord, code).get()
# 2-hour time limit on confirming.
if record and (datetime.datetime.now() - record.timestamp <
if record and (datetime.datetime.now(tz=datetime.timezone.utc) - record.timestamp <
datetime.timedelta(hours=2)):
record.confirmed = True
record.put()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def fetch_times(limit):
@app.route('/')
def root():
# Store the current access time in Datastore.
store_time(datetime.datetime.now())
store_time(datetime.datetime.now(tz=datetime.timezone.utc))

# Fetch the most recent 10 access times from Datastore.
times = fetch_times(10)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def root():
# Record and fetch the recent times a logged-in user has accessed
# the site. This is currently shared amongst all users, but will be
# individualized in a following step.
store_time(datetime.datetime.now())
store_time(datetime.datetime.now(tz=datetime.timezone.utc))
times = fetch_times(10)

return render_template(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def root():
claims = google.oauth2.id_token.verify_firebase_token(
id_token, firebase_request_adapter)

store_time(claims['email'], datetime.datetime.now())
store_time(claims['email'], datetime.datetime.now(tz=datetime.timezone.utc))
times = fetch_times(claims['email'], 10)

except ValueError as exc:
Expand Down
2 changes: 1 addition & 1 deletion appengine/standard_python3/pubsub/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def signer():

@pytest.fixture
def fake_token(signer):
now = calendar.timegm(datetime.datetime.utcnow().utctimetuple())
now = calendar.timegm(datetime.datetime.now(tz=datetime.timezone.utc).utctimetuple())
payload = {
'aud': 'example.com',
'azp': '1234567890',
Expand Down
6 changes: 3 additions & 3 deletions blog/introduction_to_data_models_in_cloud_datastore/blog.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2015, Google, Inc.
# Copyright 2015 Google, LLC.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
Expand Down Expand Up @@ -43,7 +43,7 @@ def create_user(ds, username, profile):

leahecole marked this conversation as resolved.
Show resolved Hide resolved

def create_post(ds, username, post_content):
now = datetime.datetime.utcnow()
now = datetime.datetime.now(tz=datetime.timezone.utc)
key = path_to_key(ds, '{0}.user/{1}.post'.format(username, now))
entity = datastore.Entity(key)

Expand All @@ -57,7 +57,7 @@ def create_post(ds, username, post_content):


def repost(ds, username, original):
now = datetime.datetime.utcnow()
now = datetime.datetime.now(tz=datetime.timezone.utc)
new_key = path_to_key(ds, '{0}.user/{1}.post'.format(username, now))
new = datastore.Entity(new_key)

Expand Down
4 changes: 2 additions & 2 deletions blog/introduction_to_data_models_in_cloud_datastore/wiki.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2015, Google, Inc.
# Copyright 2015 Google, LLC.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
Expand Down Expand Up @@ -37,7 +37,7 @@ def path_to_key(datastore, path):

leahecole marked this conversation as resolved.
Show resolved Hide resolved
def save_page(ds, page, content):
with ds.transaction():
now = datetime.datetime.utcnow()
now = datetime.datetime.now(tz=datetime.timezone.utc)
current_key = path_to_key(ds, '{}.page/current.revision'.format(page))
revision_key = path_to_key(ds, '{}.page/{}.revision'.format(page, now))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def encrypt_and_insert_data(
team: str,
email: str,
) -> None:
time_cast = datetime.datetime.utcnow()
time_cast = datetime.datetime.now(tz=datetime.timezone.utc)
# Use the envelope AEAD primitive to encrypt the email, using the team name as
# associated data. Encryption with associated data ensures authenticity
# (who the sender is) and integrity (the data has not been tampered with) of that
Expand Down
2 changes: 1 addition & 1 deletion cloud-sql/mysql/sqlalchemy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def get_index_context():
def save_vote():
# Get the team and time the vote was cast.
team = request.form["team"]
time_cast = datetime.datetime.utcnow()
time_cast = datetime.datetime.now(tz=datetime.timezone.utc)
# Verify that the team is one of the allowed options
if team != "TABS" and team != "SPACES":
logger.warning(team)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def encrypt_and_insert_data(
team: str,
email: str,
) -> None:
time_cast = datetime.datetime.utcnow()
time_cast = datetime.datetime.now(tz=datetime.timezone.utc)
# Use the envelope AEAD primitive to encrypt the email, using the team name as
# associated data. Encryption with associated data ensures authenticity
# (who the sender is) and integrity (the data has not been tampered with) of that
Expand Down
2 changes: 1 addition & 1 deletion cloud-sql/postgres/sqlalchemy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def get_index_context():
def save_vote():
# Get the team and time the vote was cast.
team = request.form['team']
time_cast = datetime.datetime.utcnow()
time_cast = datetime.datetime.now(tz=datetime.timezone.utc)
# Verify that the team is one of the allowed options
if team != "TABS" and team != "SPACES":
logger.warning(team)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def encrypt_and_insert_data(
team: str,
email: str,
) -> None:
time_cast = datetime.datetime.utcnow()
time_cast = datetime.datetime.now(tz=datetime.timezone.utc)
# Use the envelope AEAD primitive to encrypt the email, using the team name as
# associated data. Encryption with associated data ensures authenticity
# (who the sender is) and integrity (the data has not been tampered with) of that
Expand Down
2 changes: 1 addition & 1 deletion cloud-sql/sql-server/sqlalchemy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def get_index_context():
def save_vote():
# Get the team and time the vote was cast.
team = request.form["team"]
time_cast = datetime.datetime.utcnow()
time_cast = datetime.datetime.now(tz=datetime.timezone.utc)
# Verify that the team is one of the allowed options
if team != "TABS" and team != "SPACES":
logger.warning(team)
Expand Down
3 changes: 3 additions & 0 deletions composer/airflow_1_samples/bq_copy_across_locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
# Set default arguments
# --------------------------------------------------------------------------------

# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)

default_args = {
Expand Down
3 changes: 3 additions & 0 deletions composer/airflow_1_samples/hadoop_tutorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
from airflow.utils import trigger_rule

# Output file for Cloud Dataproc job.
# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
output_file = os.path.join(
models.Variable.get('gcs_bucket'), 'wordcount',
datetime.datetime.now().strftime('%Y%m%d-%H%M%S')) + os.sep
Expand Down
3 changes: 3 additions & 0 deletions composer/airflow_1_samples/kubernetes_pod_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
key='service-account.json')
# [END composer_kubernetespodoperator_secretobject_airflow_1]

# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
YESTERDAY = datetime.datetime.now() - datetime.timedelta(days=1)

# If a Pod fails to launch, or has an error occur in the container, Airflow
Expand Down
3 changes: 3 additions & 0 deletions composer/airflow_1_samples/quickstart.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import airflow
from airflow.operators import bash_operator

# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
YESTERDAY = datetime.datetime.now() - datetime.timedelta(days=1)

default_args = {
Expand Down
4 changes: 3 additions & 1 deletion composer/airflow_1_samples/unit_testing_cycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
from airflow import models
from airflow.operators import dummy_operator


# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)

default_dag_args = {
Expand Down
4 changes: 3 additions & 1 deletion composer/airflow_1_samples/unit_testing_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
from airflow.operators import bash_operator
from airflow.operators import dummy_operator


# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)

default_dag_args = {
Expand Down
3 changes: 3 additions & 0 deletions composer/workflows/bq_copy_across_locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
# Set default arguments
# --------------------------------------------------------------------------------

# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)

default_args = {
Expand Down
3 changes: 3 additions & 0 deletions composer/workflows/hadoop_tutorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
from airflow.utils import trigger_rule

# Output file for Cloud Dataproc job.
# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
output_file = os.path.join(
models.Variable.get('gcs_bucket'), 'wordcount',
datetime.datetime.now().strftime('%Y%m%d-%H%M%S')) + os.sep
Expand Down
3 changes: 3 additions & 0 deletions composer/workflows/kubernetes_pod_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
key='service-account.json')
# [END composer_kubernetespodoperator_secretobject]

# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
YESTERDAY = datetime.datetime.now() - datetime.timedelta(days=1)

# If a Pod fails to launch, or has an error occur in the container, Airflow
Expand Down
3 changes: 3 additions & 0 deletions composer/workflows/quickstart.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import airflow
from airflow.operators import bash

# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
YESTERDAY = datetime.datetime.now() - datetime.timedelta(days=1)

default_args = {
Expand Down
6 changes: 4 additions & 2 deletions composer/workflows/unit_testing_cycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""An example DAG demonstrating a cyle in the task IDs."""
"""An example DAG demonstrating a cycle in the task IDs."""

import datetime

from airflow import models
from airflow.operators import dummy


# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)

default_dag_args = {
Expand Down
4 changes: 3 additions & 1 deletion composer/workflows/unit_testing_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
from airflow.operators import bash
from airflow.operators import dummy


# If you are running Airflow in more than one time zone
# see https://airflow.apache.org/docs/apache-airflow/stable/timezone.html
# for best practices
yesterday = datetime.datetime.now() - datetime.timedelta(days=1)

default_dag_args = {
Expand Down
12 changes: 6 additions & 6 deletions datastore/cloud-client/snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ def properties(client):
{
"category": "Personal",
"description": "Learn Cloud Datastore",
"created": datetime.datetime.utcnow(),
"created": datetime.datetime.now(tz=datetime.timezone.utc),
"done": False,
"priority": 4,
"percent_complete": 10.5,
Expand Down Expand Up @@ -536,7 +536,7 @@ def key_filter(client):
def ascending_sort(client):
# Create the entity that we're going to query.
task = upsert(client)
task["created"] = datetime.datetime.utcnow()
task["created"] = datetime.datetime.now(tz=datetime.timezone.utc)
client.put(task)

# [START datastore_ascending_sort]
Expand All @@ -550,7 +550,7 @@ def ascending_sort(client):
def descending_sort(client):
# Create the entity that we're going to query.
task = upsert(client)
task["created"] = datetime.datetime.utcnow()
task["created"] = datetime.datetime.now(tz=datetime.timezone.utc)
client.put(task)

# [START datastore_descending_sort]
Expand All @@ -564,7 +564,7 @@ def descending_sort(client):
def multi_sort(client):
# Create the entity that we're going to query.
task = upsert(client)
task["created"] = datetime.datetime.utcnow()
task["created"] = datetime.datetime.now(tz=datetime.timezone.utc)
client.put(task)

# [START datastore_multi_sort]
Expand Down Expand Up @@ -721,7 +721,7 @@ def exploding_properties(client):
{
"tags": ["fun", "programming", "learn"],
"collaborators": ["alice", "bob", "charlie"],
"created": datetime.datetime.utcnow(),
"created": datetime.datetime.now(tz=datetime.timezone.utc),
}
)
# [END datastore_exploding_properties]
Expand Down Expand Up @@ -767,7 +767,7 @@ def transfer_funds(client, from_key, to_key, amount):
def transactional_get_or_create(client):
# [START datastore_transactional_get_or_create]
with client.transaction():
key = client.key("Task", datetime.datetime.utcnow().isoformat())
key = client.key("Task", datetime.datetime.now(tz=datetime.timezone.utc).isoformat())

task = client.get(key)

Expand Down
2 changes: 1 addition & 1 deletion datastore/cloud-client/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def add_task(client: datastore.Client, description: str):
# Apply new field values and save the Task entity to Datastore
task.update(
{
"created": datetime.datetime.utcnow(),
"created": datetime.datetime.now(tz=datetime.timezone.utc),
"description": description,
"done": False,
}
Expand Down
2 changes: 1 addition & 1 deletion firestore/cloud-async-client/snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ async def add_data_types():
"stringExample": "Hello, World!",
"booleanExample": True,
"numberExample": 3.14159265,
"dateExample": datetime.datetime.now(),
"dateExample": datetime.datetime.now(tz=datetime.timezone.utc),
"arrayExample": [5, True, "hello"],
"nullExample": None,
"objectExample": {"a": 5, "b": True},
Expand Down
2 changes: 1 addition & 1 deletion firestore/cloud-client/snippets.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def add_data_types():
u'stringExample': u'Hello, World!',
u'booleanExample': True,
u'numberExample': 3.14159265,
u'dateExample': datetime.datetime.now(),
u'dateExample': datetime.datetime.now(tz=datetime.timezone.utc),
u'arrayExample': [5, True, u'hello'],
u'nullExample': None,
u'objectExample': {
Expand Down
2 changes: 1 addition & 1 deletion functions/helloworld/sample_storage_test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_print_name():
filename = str(uuid.uuid4())
port = 8089 # Each running framework instance needs a unique port

example_timestamp = datetime.datetime.now().isoformat()
example_timestamp = datetime.datetime.now(tz=datetime.timezone.utc).isoformat()
storage_message = {
'data': {
'name': filename,
Expand Down
4 changes: 2 additions & 2 deletions iot/api-client/codelabs/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,10 @@ def create_jwt(project_id, private_key_file, algorithm, jwt_expires_minutes):

token = {
# The time that the token was issued at
'iat': datetime.datetime.utcnow(),
'iat': datetime.datetime.now(tz=datetime.timezone.utc),
# The time the token expires.
'exp': (
datetime.datetime.utcnow() +
datetime.datetime.now(tz=datetime.timezone.utc) +
datetime.timedelta(minutes=jwt_expires_minutes)),
# The audience field should always be set to the GCP project id.
'aud': project_id
Expand Down
Loading