Inconsistent datetime object in Python3 and Django2 - python-3.x

Python 3, Django 2
I am trying to get a function to consistently return a datetime object.
Here are the conditions where it does and does not work.
I have a function that generates a datetime object with an offset like so:
from django.conf import settings
from datetime import datetime
def off_time():
date = datetime.now()
offset = settings.TIME_OFFSET
offtime = date + offset
return offtime
TIME_OFFSET is generated in settings thus:
from datetime import timedelta
TIME_OFFSET = timedelta(days=370000)
If I save to a model object like this:
from django.db import models
import stellar.physics_tools
class Test(models.Model):
cdate = models.DateTimeField(default=stellar.physics_tools.off_time, help_text='When Generated')
and then work on the cdate, I can do this:
cdate = test.cdate
creation_date = cdate.strftime("%d-%m-%Y %H:%M:%S")
and it works ok.
but if I try this:
newtime = stellar.physics_tools.off_time
return newtime.strftime("%d-%m-%Y %H:%M:%S")
I get:
'function' object has no attribute 'strftime'
I need this function to return an object that I can use .strftime on, at least.
Any help appreciated. Thanks.

For this to work I need to call the function with () like this:
newtime = stellar.physics_tools.off_time()
I was not doing this because if I did this in the Django model construction it returns the value created when the class is defined, which is not what I want.
In short I still need to use stellar.physics_tools.off_time in the Django model, but when calling the function outside of this I need to use stellar.physics_tools.off_time().

Related

How to correctly mock with unittest.mock across different modules

I've got a simple exercise function in module a.my_cal.py:
# a.my_cal.py
from datetime import datetime
def is_weekday():
today = datetime.today()
day_of_the_week = today.weekday()
print(f"Day of the week: {today}")
return (0 <= day_of_the_week < 5)
The function returns true for a weekday and false otherwise.
I am trying to test the function by mocking the datetime.today value so that the test passes on any day of the week.
My test is in module b.test_my_cal.py and it looks as follows:
# b.test_my_cal
from unittest.mock import Mock
import src.my_calendar
monday = src.my_calendar.datetime(year=2023, month=1, day=2)
datetime = Mock()
def test_my_cal():
datetime.today.return_value = monday
print(f"Print mocked day: {datetime.today.return_value}")
assert src.my_calendar.is_weekday()
What am I missing here, as the function under test always gets the current day rather than the mocked Monday?

Python datetime parsing timestamp with timezone

I ran into this problem a while back ago where parsing an ISO string with time zone data and parsing a timestamp (supposedly of the same time) will give different results. I have written a test to check this behavior and it seems pretty inconsistent:
from pytz import timezone as tz
from datetime import datetime
timezone = "Australia/Sydney"
start_time = "2021-05-04T08:12:00"
tz_object = tz(timezone)
naive_datetime = datetime.fromisoformat(start_time)
zoned_time = datetime(naive_datetime.year, naive_datetime.month, naive_datetime.day, naive_datetime.hour, naive_datetime.minute, naive_datetime.second, tzinfo=tz_object)
parsed_time = datetime.fromtimestamp(zoned_time.timestamp(), tz_object)
assert zoned_time.time() == naive_datetime.time()
assert zoned_time.time() == parsed_time.time()
This test produces the following output
File "test.py", line 13, in <module>
assert zoned_time.time() == parsed_time.time()
AssertionError
Unless I'm missing something I can only conclude that the time resulting from this line
parsed_time = datetime.fromtimestamp(zoned_time.timestamp(), tz_object)
Is producing a different time than parsing the actual ISO string. Typically I'd expect the timestamp from the parsed time return a timestamp referring to 8:12 am in the time zone it was assigned.
Is this behavior expected?
Did I miss something?
With Python 3.9, use zoneinfo. Note that there is a deprecation shim for pytz if required.
Your code then works fine like
from datetime import datetime
from zoneinfo import ZoneInfo
timezone = "Australia/Sydney"
tz_object = ZoneInfo(timezone)
start_time = "2021-05-04T08:12:00"
naive_datetime = datetime.fromisoformat(start_time)
zoned_time = datetime(naive_datetime.year, naive_datetime.month, naive_datetime.day, naive_datetime.hour, naive_datetime.minute, naive_datetime.second, tzinfo=tz_object)
parsed_time = datetime.fromtimestamp(zoned_time.timestamp(), tz_object)
assert zoned_time.time() == naive_datetime.time()
assert zoned_time.time() == parsed_time.time()
As to why you got an assertion error: with pytz you need to localize the datetime object with the time zone; never set a tzinfo directly with pytz.

"'str' object has no attribute 'strftime'" in ComplexDateTimeField conversion

Well, I'm implementing a testcase in service, but I'm facing some problems.
Here's a sample of the code
datetime_one = mongo.ComplexDateTimeField()._convert_from_string('2019, 12, 20, 19, 24, 10, 451923')
visitor = Visit()
visitor.user_id = '750645c7-bf66-4023-9a2d-9c942a25f6cd'
visitor.timestamp = mongo.ComplexDateTimeField().to_mongo(datetime_one)
visitor.save()
visitor is an object from the class Visit:
from datetime import datetime
import mongoengine as mongo
class Visit(mongo.Document):
user_id = mongo.UUIDField(required=True)
timestamp = mongo.ComplexDateTimeField(required=True, default=datetime.utcnow, editable=False)
When I try run this code I get error in the line of visitor.timestamp...
AttributeError: 'str' object has no attribute 'strftime'
What am I doing wrong here?
You need to use datetime instances, not strings and you don't need to use to_mongo or _convert_from_string.
As described in the doc of the ComplexDateTimeField, the only difference with a regular DateTimeField is that the date will be stored as a string behind the scene but any interaction you have with the attribute will be with a datetime.
See below:
class Visit(Document):
timestamp = ComplexDateTimeField()
visit = Visit(timestamp=datetime.utcnow())
visit.save()
assert isinstance(visit.timestamp, datetime)
# print object as it is stored in mongodb
print(Visit.objects.as_pymongo())
# Output: [{'timestamp': '2020,01,23,22,24,21,449017', '_id': ObjectId('5e2a1d15f3ede875e9c0b806')}]
Feel free to look at the corresponding test file if you want more code samples.

What's get_products() missing 1 required positional argument: 'self'

I am trying to program for a friend of mine for fun and practice to make myself better in Python 3.6.3, I don't really understand why I got this error.
TypeError: get_products() missing 1 required positional argument: 'self'
I have done some research, it says I should initialize the object, which I did, but it is still giving me this error. Can anyone tell me where I did wrong? Or is there any better ways to do it?
from datetime import datetime, timedelta
from time import sleep
from gdax.public_client import PublicClient
# import pandas
import requests
class MyGdaxHistoricalData(object):
"""class for fetch candle data for a given currency pair"""
def __init__(self):
print([productList['id'] for productList in PublicClient.get_products()])
# self.pair = input("""\nEnter your product name separated by a comma.
self.pair = [i for i in input("Enter: ").split(",")]
self.uri = 'https://api.gdax.com/products/{pair}/candles'.format(pair = self.pair)
#staticmethod
def dataToIso8681(data):
"""convert a data time object to the ISO-8681 format
Args:
date(datetime): The date to be converted
Return:
string: The ISO-8681 formated date
"""
return 0
if __name__ == "__main__":
import gdax
MyData = MyGdaxHistoricalData()
# MyData = MyGdaxHistoricalData(input("""\nEnter your product name separated by a comma.
# print(MyData.pair)
Possibly you missed to create object of PublicClient. Try PublicClient().get_products()
Edited:
why I need the object of PublicClient?
Simple thumb rule of OOP's, if you wanna use some property(attribute) or behavior(method) of class, you need a object of that class. Else you need to make it static, use #staticmethod decorator in python.

How to add n minutes in groovy

I am working in SoapUI , which supports GroovyScript in TestCases.
In some TestCases i supposed to use a date of now + 15 minutes, 30, or 90 minutes.
If im using this script:
import java.util.Calendar;
def tdFormat = "yyyy-MM-dd HH:mm"
def today = Calendar.getInstance()
def today15min = today.add(today.MINUTE,15)
def todayFormated = today15min.format(tdFormat)
gets NullPointerException: Cannot invoke method format() on null object error at line: 6.
How can i fix this?
Using TimeCategory.
use( groovy.time.TimeCategory ) {
println 15.minutes.from.now.format( 'yyyy-MM-dd HH:mm' )
}
Calendar is a static class used to create Dates. Calendar.add() returns void, because it simply modifies the Calendar. You need to call getTime() to get a Date object which you can then format how you please.

Resources