Convert dictionary timestamp key-value pairs into datetime - python

I have a dictionary which has a timestamp stored as key and value pairs:
timestamp_info = {
'day': 8, 'fold': 0, 'hour': 0,
'max': {'day': 31, 'fold': 0,'hour': 23},
'microsecond': 639000, 'minute': 17, 'month': 10, 'second': 35, 'year': 2021
}
I am trying to take timestamp from dictionary and convert to datetime.datetime timestamp format. I tried the following but it does not work as it asks for str (exact error is: "strptime() argument 1 must be str, not dict"):
result = datetime.datetime.strptime(timestamp_info, "%Y-%m-%d %H:%M:%S")
I want this result to be compared with datetime.datetime.now and take difference in seconds between current timestamp and result, that is the reason I need timestamp format.

Chirs Oram already shows how to build a string that you can then parse with strptime(). Alternatively, you can pass the values directly to datetime():
timestamp_info = {
'day':8, 'fold':0,'hour':0, 'max':{'day':31, 'fold':0,'hour':23},
'microsecond':639000,'minute':17,'month':10,'second':35, 'year':2021
}
year = timestamp_info['year']
month = timestamp_info['month']
day = timestamp_info['day']
hour = timestamp_info['hour']
minute = timestamp_info['minute']
second = timestamp_info['second']
result = datetime.datetime(year=year, month=month, day=day, hour=hour, minute=minute, second=second)
Or you can do this more succinctly by removing the attributes not needed for datetime:
timestamp_info = {
'day':8, 'fold':0,'hour':0, 'max':{'day':31, 'fold':0,'hour':23},
'microsecond':639000,'minute':17,'month':10,'second':35, 'year':2021
}
del timestamp_info['fold']
del timestamp_info['max']
result = datetime.datetime(**timestamp_info)

You can extract each part of the timestamp in the specified format, and concatenate them into a string:
timestamp_info = {
'day':8, 'fold':0,'hour':0, 'max':{'day':31, 'fold':0,'hour':23},
'microsecond':639000,'minute':17,'month':10,'second':35, 'year':2021
}
year = str(timestamp_info['year'])
month = str(timestamp_info['month'])
day = str(timestamp_info['day'])
hour = str(timestamp_info['hour'])
minute = str(timestamp_info['minute'])
second = str(timestamp_info['second'])
timestamp = '-'.join([year, month, day]) + ' ' + ':'.join([hour, minute, second])
result = datetime.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S")
Which results in:
2021-10-08 00:17:35

Related

Know which parts a day contains

The dateparser library set missing parts of a date to today's values.
Example:
>>> import dateparser
>>> dateparser.parse("2015")
datetime.datetime(2015, 2, 14, 0, 0)
How to know which parts a date really contains?
(and thus which parts were set to today's values by the library)?
This is what I've come up with.
Is there a more efficient way?
date_str = input('Type a date: ')
settings = {"REQUIRE_PARTS": ["year"]}
res = dateparser.parse(date_str, settings=settings)
if res is None:
print("Invalid Date")
return
settings = {"REQUIRE_PARTS": ["year", "month"]}
res = dateparser.parse(date_str, settings=settings)
if res is None:
print("Date has year only")
return
settings = {"REQUIRE_PARTS": ["year", "month", "day"]}
res = dateparser.parse(date_str, settings=settings)
if res is None:
print("Date has year and month")
return
print("Date has year, month and day")

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;

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.

Django built-in timesince filter to show only Days

I am using {{ prospect.date_1 }} - ({{ prospect.date_1|timesince }} ago) in my template to get time since the date.
The point is, date_1 is a date not datetime, so when i apply the filter it tells me like
July 18, 2014 - (11 hours, 39 minutes ago)
expected output
July 18, 2014 - (0 days ago)
taken from naturalday
#register.filter(expects_localtime=True)
def days_since(value, arg=None):
try:
tzinfo = getattr(value, 'tzinfo', None)
value = date(value.year, value.month, value.day)
except AttributeError:
# Passed value wasn't a date object
return value
except ValueError:
# Date arguments out of range
return value
today = datetime.now(tzinfo).date()
delta = value - today
if abs(delta.days) == 1:
day_str = _("day")
else:
day_str = _("days")
if delta.days < 1:
fa_str = _("ago")
else:
fa_str = _("from now")
return "%s %s %s" % (abs(delta.days), day_str, fa_str)
results
>>> days_since(datetime.now())
'0 days ago'
>>> days_since(date(2013, 5, 12))
'432 days ago'
>>> days_since(date(2014, 12, 12))
'147 days from now'
>>> days_since(date(2014, 7, 19))
'1 day from now'
#Jack, Have you tried to use in-built python:
Visit: https://docs.python.org/2/library/datetime.html#datetime.datetime.day
Also if this might help:
https://docs.djangoproject.com/en/1.6/ref/contrib/humanize/#naturaltime
Edit:
from datetime import date
from datetime import datetime
d = date.today()
datetime.combine(d, datetime.min.time())

recursively traverse multidimensional dictionary and export to csv

I've have a complex multidimensional dictionary that I want to export some of the the key value pairs to a csv file as a running log file. I've tried the various help with exporting to cvs functions and hacked away at most of the code example in stackoverflow on traversing multidimensional dictionaries but have failed to arrive at a solution. This problem is also unique in that it has only some key values I want to export.
Here is the dictionary:
cpu_stats = {'time_stamp': {'hour': 22, 'month': 5, 'second': 43, 'year': 2014, 'day': 29, 'minute': 31}, 'cpus': [[{'metric_type': 'CPU_INDEX', 'value': 1}, {'metric_type': 'CPU_TEMPERATURE', 'value': 39}, {'metric_type': 'CPU_FAN_SPEED', 'value': 12000}]]}
I need to format the values in time_stamp into a yyyy-mm-dd hh:mm:ss and store it as the first cell of the row. I then need the values in 'cpus' for CPU_INDEX, CPU_TEMPERATURE, and CPU_FAN_SPEED in the same row as the time stamp.
The csv file should look like this:
time_stamp, cpu_index, cpu_temperature, cpu_fan_speed
2014-05-29, 1, 38, 12000
One example I've been hacking away on is:
def walk_dict(seq, level=0):
"""Recursively traverse a multidimensional dictionary and print all
keys and values.
"""
items = seq.items()
items.sort()
for v in items:
if isinstance(v[1], dict):
# Print the key before make a recursive call
print "%s%s" % (" " * level, v[0])
nextlevel = level + 1
walk_dict(v[1], nextlevel)
else:
print "%s%s %s" % (" " * level, v[0], v[1])
I get the following output
walk_dict(cpu_stats)
cpus [[{'metric_type': 'CPU_INDEX', 'value': 1}, {'metric_type': 'CPU_TEMPERATURE', 'value': 38}, {'metric_type': 'CPU_FAN_SPEED', 'value': 12000}]]
time_stamp
day 29
hour 22
minute 17
month 5
second 19
year 2014
I have also been hacking away at this function as well hoping I can store the date information into variables that can then be formatted into a single string. Unfortuatly it has recursive calls which loose the local variables on subsequent calls. Using global was futile.
def parseDictionary(obj, nested_level=0, output=sys.stdout):
spacing = ' '
if type(obj) == dict:
print >> output, '%s{' % ((nested_level) * spacing)
for k, v in obj.items():
if hasattr(v, '__iter__'):
# 1st level, prints time and cpus
print >> output, '%s:' % (k)
parseDictionary(v, nested_level + 1, output)
else:
# here is the work
if k == "hour":
hour = v
elif k == "month":
month = v
elif k == "second":
second = v
elif k == "year":
year = v
elif k == "day":
day = v
elif k == "minute":
minute = v
print >> output, '%s %s' % (k, v)
print >> output, '%s}' % (nested_level * spacing)
elif type(obj) == list:
print >> output, '%s[' % ((nested_level) * spacing)
for v in obj:
if hasattr(v, '__iter__'):
parseDictionary(v, nested_level + 1, output)
else:
print >> output, '%s%s' % ((nested_level + 1) * spacing, v)
print >> output, '%s]' % ((nested_level) * spacing)
else:
print >> output, '%s%s' % (nested_level * spacing, obj)
if __name__ == "__main__":
global year
global month
global day
global hour
global minute
global second
cpu_stats = {'time_stamp': {'hour': 22, 'month': 5, 'second': 43, 'year': 2014, 'day': 29, 'minute': 31}, 'cpus': [[{'metric_type': 'CPU_INDEX', 'value': 1}, {'metric_type': 'CPU_TEMPERATURE', 'value': 39}, {'metric_type': 'CPU_FAN_SPEED', 'value': 12000}]]}
parseDictionary(cpu_stats)
print '%s-%s-%s %s:%s:%s' % (year, month, day, hour, minute, second)
output:
{
time_stamp:
{
hour 22
month 5
second 27
year 2014
day 29
minute 57
cpus:
[
[
{
metric_type CPU_INDEX
value 1
{
metric_type CPU_TEMPERATURE
value 39
{
metric_type CPU_FAN_SPEED
value 12000
]
]
Traceback (most recent call last):
File "./cpu.py", line 135, in <module>
print '%s-%s-%s %s:%s:%s' % (year, month, day, hour, minute, second)
NameError: global name 'year' is not defined
Thanks, I appreciate any help in pointing me in the right direction as I'm currently at a loss.
I think you might be missing the point of dictionaries. Rather than iterate over the keys of a dictionary and checking if its the key you want, you should just look up the key you want. It might be easier to approach the problem like this:
t = cpu_stats['time_stamp']
date = '{}-{}-{}'.format(t['year'], t['month'], t['day'])
for cpu in cpu_stats['cpus']:
c = {d['metric_type']: d['value'] for d in cpu}
row = [date, c['cpu_index'], c['cpu_temperature'], c'[cpu_fan_speed']]
Life would be easier if you had had your cpus value as a list of dictionaries, rather than a list of lists of dictionaries, and stored your timestamps as datetime objects:
cpu_stats = {'time_stamp': datetime.datetime(2014, 5, 29, 22, 31, 43), 'cpus': [{'CPU_INDEX': 1, 'CPU_TEMPERATURE': 39, 'CPU_FAN_SPEED': 12000}]}
The whole point of a dictionary is lost if you bury it in a structure like {'key_name': 'my_key', 'key_value': 'my_value'}. This just adds an extra layer that you don't need, instead you only need: {'my_key': 'my_value'}
I agree with #desired login, however assuming you have no control of the incoming data and had to work with what you showed in your questions... You could just traverse it like so:
cpu_stats = {'time_stamp': {'hour': 22, 'month': 5, 'second': 43, 'year': 2014, 'day': 29, 'minute': 31},
'cpus': [ [{'metric_type': 'CPU_INDEX', 'value': 1}, {'metric_type': 'CPU_TEMPERATURE', 'value': 39}, {'metric_type': 'CPU_FAN_SPEED', 'value': 12000} ] ]
}
timestamp = ''
for stats in cpu_stats.keys():
if stats == 'time_stamp':
timestamp = '{year}-{month}-{day}'.format(**cpu_stats[stats])
if stats == 'cpus':
for cpu in cpu_stats[stats]:
cpu_index = ''
cpu_temperature = ''
cpu_fan_speed = ''
for metric in cpu:
if metric['metric_type'] == 'CPU_INDEX':
cpu_index = str(metric['value'])
elif metric['metric_type'] == 'CPU_TEMPERATURE':
cpu_temperature = str(metric['value'])
elif metric['metric_type'] == 'CPU_FAN_SPEED':
cpu_fan_speed = str(metric['value'])
print ','.join([timestamp, cpu_index, cpu_temperature, cpu_fan_speed])

Categories