I have two date values in Python which Im trying to get a rounded duration from.
For example: 01-01-2000 to 12-31-2099 is really "100 years", not "99 years".
I have an example, in Java, but Im not sure how to port this to Python speak:
round(endDateEpochInMilliseconds -startDateEpochInMilliseconds /(365.25 * 24 * 3600 * 1000))
Im sure something similar is doable in Python.
import datetime
date1 = datetime.date(2000,1,1)
date2 = datetime.date(2099, 12, 31)
delta = date2-date1
print round(delta.days/365.25,0)
You defently must put endDateEpochInMilliseconds -startDateEpochInMilliseconds into brackets!
round( (endDateEpochInMilliseconds -startDateEpochInMilliseconds) /(365.25 * 24 * 3600 * 1000))
Related
I received a data export from an unspecified source system, which includes dates in the format of:
52164-01-19 00:00:00+00
52992-08-12 04:29:36+00
52838-10-19 04:08:32.999936+00
54022-03-12 17:20:36.999936+00
I was told that the error is caused by a faulty conversion of unix to datetime (seconds and milliseconds).
We came up with a possible approach to refactor the date in python, by separating the year into a "normal" year (2164) and convert the rest into milliseconds.
import time
import math
d0 = '52164-01-19 00:00:00+00'
d0_y = 52164
multiplier = 5
# avg gregorian year in seconds
avg_greg = (365.2425 * 24 * 3600)
d1_modulus = 52164 % (1000 * multiplier)
d1_rest = d0_y - d1_modulus
# replace orginal year with modulus
d1_time = time.strptime(str(d1_modulus) + '-10-19 04:08:32', '%Y-%m-%d %H:%M:%S')
#convert to milliseconds and add d1_rest in "seconds"
bigtime = time.mktime(d1_time) + (avg_greg * d1_rest) #in milliseconds
biggertime = bigtime / 1000 # in seconds
finaltime = time.ctime(biggertime)
# finaltime = 'Thu Mar 12 07:34:41 2020'
print(finaltime)
This code can break for different dates and result in multiplier/modulus combinations to create out of range values for time.mktime.
Can someone suggest an alternative or better approach to this?
Thanks in advance
Gabe
Python datetime only supports between years 1 and 9999.
So I installed astropy and it works fine :
import datetime
import re
import astropy.time as astropy_time # installed with PIP
faulty_data = "52164-01-19 00:00:00+00"
timeformat = re.compile(r"(?P<year>\d{5})-(?P<month>\d{2})-(?P<day>\d{2}) (?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})(?P<sign_tz>[+\- ])(?P<hour_tz>\d{2})")
match = timeformat.fullmatch(faulty_data)
assert match
assert len(match.group("year")) == 5
assert match.group("hour_tz") == "00"
missing_thousand_years = int(match.group("year")[0])
time = astropy_time.Time({"year": int(match.group("year")),
"month": int(match.group("month")),
"day": int(match.group("day")),
"hour": int(match.group("hour")),
"minute": int(match.group("minute")),
"second": int(match.group("second"))
},
scale="utc")
print(time)
milliseconds = time.unix
print(milliseconds)
actual_datetime = datetime.datetime.fromtimestamp(milliseconds / 1000)
print(actual_datetime)
(52164, 1, 19, 0, 0, 0.)
1583971200000.0
2020-03-12 01:00:00
So it seems that the original date was 2020-03-12 01:00:00, which is close to what you got with your method.
NB: it raises two warnings, that you can silence
I'm given time in millis and I can convert that to date obj with
currentDate = datetime.datetime.fromtimestamp(time_stamp/1000.0).date()
I'm trying to get this time as a percentage of that given day so say its 12:00pm I'd like to get 50% as output.
Here's my attempt
currentDate = datetime.datetime.fromtimestamp(time_stamp/1000.0).date()
NextDay_Date = currentDate + datetime.timedelta(days=1)
start_of_next_day=NextDay_Date.replace(hour=00, minute=00)
difference=start_of_next_day.timestamp()*1000 -currentDate.timestamp()*1000
milis_in_a_day=86400000
percent_of_day=difference/milis_in_a_day
There has to be a more elegant solution.
You could just count the number of microseconds passed today, by just using the time part of the date.
from datetime import datetime
today = datetime.now()
microseconds_today = (
(
(
(today.hour * 60) + today.minute
) * 60 + today.second
) * 1_000_000 + today.microsecond
)
print(microseconds_today / 86_400_000_000)
You're basically on the right path, only thing I could think of to be a bit more "readable" is to use timedelta from datetime. Note the fully qualified names used below - datetime in particular can be a bit confusing to read, definitely suggest referencing the documentation: https://docs.python.org/3/library/datetime.html
import datetime
TOTAL_DAY_SECS = 86400.0
def timedelta_percentage(input_datetime):
d = input_datetime - datetime.datetime.combine(input_datetime.date(), datetime.time())
return d.total_seconds() / TOTAL_DAY_SECS
now = datetime.datetime.now()
print(f"'datetime.now()': {now}")
answer = round(timedelta_percentage(now) * 100, 2)
print(f"Percentage of day complete, based on 'now': {answer}%")
Output:
'datetime.now()': 2021-04-23 09:38:16.026000
Percentage of day complete, based on 'now': 40.16%
You could certainly adapt this to be more precise using microseconds, depending how granular of an answer you need.
How in python code convert 10.5 to 10:30 (10 hours and 30 minutes).
Now time = 10.5 I need result time = 10:30
Any simple solution?
Tnx all for help
Try this:
time = 10.5
print '{0:02.0f}:{1:02.0f}'.format(*divmod(float(time) * 60, 60))
10:30
Split the number into its integer and decimal parts, then multiply the decimal part with 60 and put them back together:
t = 10.5
hour, minute = divmod(t, 1)
minute *= 60
result = '{}:{}'.format(int(hour), int(minute))
# result: 10:30
See also the documentation for the divmod function and this question for other ways to split a float into two parts.
You can pass the raw float value as hours to datetime.timedelta(), and then operate with it in what I think is the most comfortable way:
from datetime import datetime, timedelta
td = timedelta(hours=10.5)
dt = datetime.min + td
print("{:%H:%M}".format(dt))
print(td.total_seconds())
I have a timestep (e.g. 2717715 microseconds) which I want to convert to hh:mm:ss format to extract a frame from a youtube video. I have used the following code to do so:
def convert(timestamp):
# pdb.set_trace()
timestamp = float(timestamp)
# seconds = (micros/1000)%60
# minutes = (micros/(1000*60))%60
# hours = (micros/(1000*60*60))%24
# pdb.set_trace
milliseconds = (timestamp / 1000) % 1000
seconds = (( (timestamp / 1000) - milliseconds)/1000)%60
minutes = (((( (timestamp / 1000) - milliseconds)/1000) - seconds)/60) %60
hours = ((((((timestamp / 1000) - milliseconds)/1000) - seconds)/60) - minutes)/60
return hours, minutes, seconds
But it is not working. Can you please tell me what is wrong with my code?
Considering your timestamp is of type float you can use the built in divmod function as follows:
timestamp = 3 * 3600 + 7 * 60 + 20 # just creating (3h 7m 20s) float format timestamp
print(timestamp) # gives 11240
suppose you have that timestamp, you can extract your hours, minutes and seconds from it as follows:
timestamp = float(timestamp)/1000000 # The timestamp is in microseconds
hours,remainder = divmod(timestamp, 3600)
minutes,seconds = divmod(remainder, 60)
print(hours) # gives 3
print(minutes) # gives 7
print(seconds) # gives 20
Hope that helped. Happy Coding.
I think you are looking for the datetime module.
You can get a human-readable time from a timestamp in the following manner:
from datetime import datetime
def convert(timestamp):
return datetime.fromtimestamp(timestamp).time()
I want to calculate difference between two time in hours using django in sql db the time are stored in timefield.
I tried this:
def DesigInfo(request): # attendance summary
emplist = models.staff.objects.values('empId', 'name')
fDate = request.POST.get('fromDate')
tDate = request.POST.get('toDate')
if request.GET.get('empId_id'):
sel = attendance.objects.filter(empId_id=request.GET.get('empId_id'),)
for i in sel:
# print i.
# print i.outTime
# print i.inTime.hour,i.inTime.minute,i.inTime.second - i.outTime.hour,i.outTime.minute,i.outTime.second
ss = i.inTime.hour
ss1 = 12 - ss
mm = i.outTime.hour
mm1 = (12 + mm) - 12
print ss1 + mm1
Since i.inTime and i.outTime are time objects you cannot simply subtract them. A good approach is to convert them to datetime adding the date part (use today() but it is irrelevant to the difference), then subtract obtaining a timedelta object.
delta = datetime.combine(date.today(), i.outTime) - datetime.combine(date.today(), i.inTime)
(Look here: subtract two times in python)
Then if you want to express delta in hours:
delta_hours = delta.days * 24 + delta.seconds / 3600.0
A timedelta object has 3 properties representing 3 different resolutions for time differences (days, seconds and microseconds). In the last expression I avoided to add the microseconds but I suppose it is not relevant in your case. If it is also add delta.microseconds / 3600000000.0
Note that simply dividing seconds by 3600 would have returned only the integer part of hours avoiding fractions. It depends on your business rules how to round it up (round, floor, ceil or leave the fractional part as I did)
Using datetime objects: https://docs.python.org/2/library/datetime.html
A good stack overflow post on the topic How to get current time in Python
from datetime import datetime
now = datetime.now()
# wait some time
then = ... some time
# diff is a datetime.timedelta instance
diff = then - now
diff_hours = diff.seconds / 3600
You might want to play with this codes:
from datetime import datetime
#set the date and time format
date_format = "%m-%d-%Y %H:%M:%S"
#convert string to actual date and time
time1 = datetime.strptime('8-01-2008 00:00:00', date_format)
time2 = datetime.strptime('8-02-2008 01:30:00', date_format)
#find the difference between two dates
diff = time2 - time1
''' days and overall hours between two dates '''
print ('Days & Overall hours from the above two dates')
#print days
days = diff.days
print (str(days) + ' day(s)')
#print overall hours
days_to_hours = days * 24
diff_btw_two_times = (diff.seconds) / 3600
overall_hours = days_to_hours + diff_btw_two_times
print (str(overall_hours) + ' hours');
''' now print only the time difference '''
''' between two times (date is ignored) '''
print ('\nTime difference between two times (date is not considered)')
#like days there is no hours in python
#but it has seconds, finding hours from seconds is easy
#just divide it by 3600
hours = (diff.seconds) / 3600
print (str(hours) + ' Hours')
#same for minutes just divide the seconds by 60
minutes = (diff.seconds) / 60
print (str(minutes) + ' Minutes')
#to print seconds, you know already ;)
print (str(diff.seconds) + ' secs')
The easiest way through I achieve is the comment of Zac given above. I was using relativedelta like this
from dateutil import relativedelta
difference = relativedelta.relativedelta( date1, date2)
no_of_hours = difference.hours
but it did not give me correct result when the days changes. So, I used the approach expressed above:
no_of_hours = (difference.days * 24) + (difference.seconds / 3600)
Please note that you will be getting negative value if date2 is greater than date1. So, you need to swipe the position of date variables in relativedelta.