Generate random start and end date between a date range - python

I have written some utility functions to generate a random date start and end date range between a specified date range which will return both the est and the utc times. However I'm not getting consistent results. Sometimes the result is offset by 4 hrs between UTC and EST and sometimes its offset by 5 hrs. Can anyone help whats wrong with the code?
def generate_random_dt_btn_two_dates(start_date,end_date, line_item):
time_between_dates = end_date - start_date
days_between_dates = time_between_dates.days
if line_item:
days_between_dates = round(days_between_dates/2)
if days_between_dates < 1 or days_between_dates is None:
days_between_dates = 1
random_number_of_days = random.randrange(days_between_dates)
utc_date = start_date + timedelta(days=random_number_of_days, hours = random.randrange(24), minutes = random.randrange(60),
seconds = random.randrange(60), microseconds= random.randrange(1000), milliseconds= random.randrange(1000))
est_now = utc_date.astimezone(pytz.timezone("America/New_York"))
return {"utc_date":utc_date, "est_date":est_now}
def generate_random_dt_range(start_date = datetime(2022, 1, 1, 15, 16, 17, 345, tzinfo=timezone.utc),
end_date = datetime(2022, 7, 30, 15, 16, 17, 345, tzinfo=timezone.utc),
line_item = False
):
random_start_date = generate_random_dt_btn_two_dates(start_date , end_date, line_item)
random_end_date = generate_random_dt_btn_two_dates(start_date = random_start_date["utc_date"], end_date = end_date, line_item = line_item)
return {"start_date": random_start_date, "end_date" : random_end_date}
campaign_dates = generate_random_dt_range()
c_end_date = campaign_dates.get("end_date").get("est_date").strftime('%Y-%m-%dT%H:%M:%S.%fZ')
c_start_date = campaign_dates.get("start_date").get("est_date").strftime('%Y-%m-%dT%H:%M:%S.%fZ')
c_end_date_utc = campaign_dates.get("end_date").get("utc_date").strftime('%Y-%m-%dT%H:%M:%S.%fZ')
c_start_date_utc = campaign_dates.get("start_date").get("utc_date").strftime('%Y-%m-%dT%H:%M:%S.%fZ')
print("start_date:", c_start_date,c_start_date_utc)
print("end_date:",c_end_date,c_end_date_utc )

Related

Is there any way to combine time and date in python using pandas?

I have 2 functions which gives output as date and time
def jdtodatestd (jdate):
if len(jdate) == 5:
fmt = '%y%j'
datestd = datetime.datetime.strptime(jdate, fmt).date()
return(datestd)
elif len(jdate) == 6:
yr = jdate[0:2]
day = jdate[2:len(jdate)]
day = day.lstrip('0')
jdate = yr+day
fmt = '%y%j'
datestd = datetime.datetime.strptime(jdate, fmt).date()
return(datestd)
elif len(jdate) == 7:
fmt = '%Y%j'
datestd = datetime.datetime.strptime(jdate, fmt).date()
return(datestd)
jdtodatestd('120365')
Output: datetime.date(2012, 12, 30)
def jdtotimestd (jtime):
if len(jtime) == 5:
jtime = '0' + jtime
elif len(jtime) == 6:
jtime = jtime
else:
jtime = '000000'
stdtime = jtime[0:2] + ':' + jtime[2:4] + ':' + jtime[4:6]
return stdtime
jdtotimestd('140932')
Output: '14:09:32'
I would like to combine both such as '2012, 12, 30 14:09:32
How can I do?
Modify your function jdtotimestd:
def jdtotimestd(jtime):
"""Returns a dt.time object from string."""
jtime = jtime.zfill(6)
return datetime.time(int(jtime[:2]), int(jtime[2:4]), int(jtime[4:]))
d = jdtodatestd('120365')
t = jdtotimestd('140932')
dt = datetime.datetime.combine(d, t)
Output:
>>> dt
datetime.datetime(2012, 12, 30, 14, 9, 32)
You can use strftime and strptime:
output1 = jdtodatestd('120365')
output2 = jdtotimestd('140932')
>>> datetime.datetime.strptime(datetime.datetime.strftime(output1, "%Y-%m-%d")+output2, "%Y-%m-%d%H:%M:%S")
datetime.datetime(2012, 12, 30, 14, 9, 32)

Datetime format when adding time durations

time_1 = datetime.timedelta(hours = hours_1, minutes = minutes_1, seconds = seconds_1)
time_2 = datetime.timedelta(hours = hours_2, minutes = minutes_2, seconds = seconds_2)
when added it gives the answer in days and hours but I really just want the total number of hours.
This should help.
import datetime
time_1 = datetime.timedelta(hours = 10, minutes = 2, seconds = 5)
time_2 = datetime.timedelta(hours = 30, minutes = 5, seconds = 7)
print(time_1 + time_2)
print(((time_1 + time_2).total_seconds()/60)/60)
Output:
1 day, 16:07:12
40.12

How to extract day, month and year from utcnow?

I have the following var: time_created = datetime.utcnow()
How to create a time_created_day var from time_created that will contain only Y, M, d
like this datetime.datetime(2017, 11, 7)
I have the following solution:
from datetime import date
time_created_day = date(time_created.year, time_created.month, time_created. day)
is it the best way?
Use datetime.utcnow().date()
datetime.utcnow().date()
datetime.date(2017, 11, 7)
Adding to answer
The datetime object always contains year, month, day as well as hours, minutes, seconds, and microseconds. It is a combination of what the date and time objects contain, see datetime Objects
from datetime import datetime
# this is your datetime object
time_created = datetime.utcnow()
# when you want to see it formatted as Y,M,D call the date method
date_created = time_created.date()
time_created
date_created
Output:
datetime.datetime(2017, 11, 7, 23, 43, 43, 761750)
datetime.date(2017, 11, 7)`
Use time_created.day to find the day.
time_created_day = time_created.day
(Similar for month and year)
here it is easiest for you
var dateObj = new Date();
var month = dateObj.getUTCMonth() + 1; //months from 1-12
var day = dateObj.getUTCDate();
var year = dateObj.getUTCFullYear();
newdate = year + " " + month + " " + day;

Count summer days between two dates

I want to count summer days between two dates. Summer is May first to August last.
This will count all days:
import datetime
startdate=datetime.datetime(2015,1,1)
enddate=datetime.datetime(2016,6,1)
delta=enddate-startdate
print delta.days
>>517
But how can only count the passed summer days?
You could define a generator to iterate over every date between startdate and enddate, define a function to check if a date represents a summer day and use sum to count the summer days:
import datetime
startdate = datetime.datetime(2015,1,1)
enddate = datetime.datetime(2016,6,1)
all_dates = (startdate + datetime.timedelta(days=x) for x in range(0, (enddate-startdate).days))
def is_summer_day(date):
return 5 <= date.month <= 8
print(sum(1 for date in all_dates if is_summer_day(date)))
# 154
Thanks to the generator, you don't need to create a huge list in memory with every day between startdate and enddate.
This iteration still considers every single day, even if it's not needed. For very large gaps, you could use the fact that every complete year has 123 summer days according to your definition.
You can create a few functions to count how many summer days you have between two days:
from datetime import date
def get_summer_start(year):
return date(year, 5, 1)
def get_summer_end(year):
return date(year, 8, 31)
def get_start_date(date, year):
return max(date, get_summer_start(year))
def get_end_date(date, year):
return min(date, get_summer_end(year))
def count_summer_days(date1, date2):
date1_year = date1.year
date2_year = date2.year
if date1_year == date2_year:
s = get_start_date(date1, date1_year)
e = get_end_date(date2, date1_year)
return (e - s).days
else:
s1 = max(date1, get_summer_start(date1_year))
e1 = get_summer_end(date1_year)
first_year = max(0,(e1 -s1).days)
s1 = get_summer_start(date2_year)
e1 = min(date2, get_summer_end(date2_year))
last_year = max(0,(e2 -s2).days)
other_years = date2_year - date1_year - 1
summer_days_per_year = (get_summer_end(date1_year) - get_summer_start(date1_year)).days
return first_year + last_year + (other_years * summer_days_per_year)
date1 = date(2015,1,1)
date2 = date(2016,6,1)
print count_summer_days(date1, date2)
Here is a better solution for large periods:
first_summer_day = (5,1)
last_summer_day = (8,31)
from datetime import date
startdate = date(2015,1,1)
enddate = date(2016,6,1)
# make sure that startdate > endate
if startdate > enddate:
startdate, endate = endate, startdate
def iter_yearly_summer_days(startdate, enddate):
for year in range(startdate.year, enddate.year+1):
start_period = startdate if year == startdate.year else date(year, 1, 1)
end_period = enddate if year == enddate.year else date(year, 12, 31)
year_first_summer_day = date(year, *first_summer_day)
year_last_summer_day = date(year, *last_summer_day)
summer_days_that_year = (min(year_last_summer_day, end_period) - max(year_first_summer_day, start_period)).days
print('year {} had {} days of summer'.format(year, summer_days_that_year))
yield summer_days_that_year
print(sum(iter_yearly_summer_days(startdate, enddate)))

Slots Creation based on date and time(float) field

I have two date field.
from_date and
to_date
In One2many line item, there is three float fields
from_time ,to_time and interval
Slot have to be created based on the above parameters.
Example:
from_date = '2017-07-21'
to_date = '2017-07-21'
the duration is one day.
The One2many line items have the values
from_time = 9.0
to_time = 10.0
interval = 30(in minutes)
The output should generate two slots
1. '2017-07-21 09:00:00' '2017-07-21 09:30:00'
2. '2017-07-21 09:30:00' '2017-07-21 10:00:00'
It should generate two line items.
If the duration is for week.
it should generate 2 * 7 = 14 slots.
I have used the code which generates for one day.
#api.one
def generate(self):
cr = self.env.cr
uid = self.env.uid
context = self.env.context
event = self.pool.get('calendar.event')
slot = self.pool.get('slot.booking')
old_data_id = slot.search(cr, uid, [('slot_id', '=',self.id)], context=context)
slot.unlink(cr, uid ,old_data_id)
for each in self.shift_line:
if each.interval > 60 or each.interval == 0:
raise osv.except_osv(_('Attention!'), _('Please enter interval timings in minutes range like (10-60) '))
interval = each.interval
fmt = "%Y-%m-%d"
start_date = datetime.strptime(self.from_date, fmt)
end_date = datetime.strptime(self.to_date, fmt)
days = []
date = start_date
pdb.set_trace()
str_start_time = '%s %s' % (self.from_date,'{0:02.0f}:{1:02.0f}'.format(*divmod(each.from_time * 60, 60)))+':00'
str_end_time = '%s %s' % (self.from_date,'{0:02.0f}:{1:02.0f}'.format(*divmod(each.to_time * 60, 60)))+':00'
time = datetime.strptime(str_start_time, '%Y-%m-%d %H:%M:%S')
end = datetime.strptime(str_end_time, '%Y-%m-%d %H:%M:%S')
while date <= end_date:
hours = []
while time <= end:
hours.append(time.strftime("%Y-%m-%d %H:%M:%S"))
time += timedelta(minutes=interval)
date += timedelta(days=1)
time += timedelta(days=1)
end += timedelta(days=1)
days.append(hours)
print "\n\n\n\n\nn\+++++++++++++++++++++days",days
for hours in days[0][:-1]:
val = datetime.strptime(hours, '%Y-%m-%d %H:%M:%S')
val = val + timedelta(minutes=interval)
values = {
'name' : 'Slot for ' + self.employee_id.name,
'start_datetime' : hours,
'stop_datetime' : str(val),
'slot_id' : self.id,
'shift_lines_id' : each.id,
'partner_id': self.employee_id.id,
'duration' : each.interval,
}
print "\n\n\n\n\n\n\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++values",values
slot.create(cr, uid, values, context=context)
Any help for multiple days is appreciated.
ist_timedelta = timedelta(seconds=((time in seconds)-10800))
adding this will give the exact answer, here 10800 is because of 3 hours difference of UTC to KSA.

Categories