convert time in Python - python

I am parsing an xml file in python and I need to convert the following date and time format to something human-friendly:
<due_date>735444</due_date>
<due_time>55800</due_time>
The format of date seems to be number of days since year 0, and time is the number of seconds since midnight.
How could I convert it into some standard format, such as 2014-07-30 15:30:00 ?

Use datetime.datetime.fromordinal() plus a timedelta() for the seconds after midnight:
import datetime
dt = datetime.datetime.fromordinal(due_date) + datetime.timedelta(seconds=due_time)
Your due_date is relative to the year 1 instead, as your values fit to produce your expected date:
>>> import datetime
>>> due_date = 735444
>>> due_time = 55800
>>> datetime.datetime.fromordinal(due_date) + datetime.timedelta(seconds=due_time)
datetime.datetime(2014, 7, 30, 15, 30)

Related

how to convert time in which hr value is greater than 24?

this how my dataset looks like ;-
Timestamp
2020-11-1 0:1:28:11265
2020-11-1 0:2:3:38616
2020-11-1 0:3:30:31943
2020-11-1 0:4:25:2289
2020-11-1 0:5:4:45378
I try to convert above timestamp using below functions
import datetime
def convert(date_time):
format = '%Y-%m-%d %H:%M:%S:%f' # The format
datetime_obj = datetime.datetime.strptime(date_time, format)
datetime_str = datetime_obj.strftime("%Y-%m-%d %H:%M:%S")
return datetime.datetime.strptime(datetime_str, "%Y-%m-%d %H:%M:%S")
df['Timestamp'] = df['Timestamp'].apply(convert)
df.head()
after running above code i get below error.
ValueError: time data '2020-11-1 24:0:47:40476' does not match format '%Y-%m-%d %H:%M:%S:%f'
how do i convert the date '2020-11-1 24:0:47:40476' --> '2020-11-2 0:0:47:40476'
You can parse the date and time separately, parsing the date part into just a date with the time component set to 0:00:00, then add the time part as timedelta to it:
>>> from datetime import datetime, timedelta
>>> s = '2020-11-1 24:0:47:40476'
>>> d, t = s.split()
>>> d
'2020-11-1'
>>> t
'24:0:47:40476'
>>> ts = datetime.strptime(d, '%Y-%m-%d')
>>> ts
datetime.datetime(2020, 11, 1, 0, 0)
>>> h, m, s, ms = t.split(':')
>>> ts + timedelta(hours=int(h), minutes=int(m), seconds=int(s), milliseconds=int(ms))
datetime.datetime(2020, 11, 2, 0, 1, 27, 476000)
Note that this may or may not work as desired should DST transitions happen right during that time; it's a bit unclear how that's supposed to work.
Also note that the 40476 milliseconds (?) added up to additional minutes. It’s slightly unclear what exactly that number is supposed to represent, you may have to split that up into milli- and microseconds too before passing it to timedelta.

How to convert datetime from decimal to “%y-%m-%d %H:%M:%S” given the time origin?

I did my search around but I couldn't find an answer that satisfies my problem.
I am using python 3.7 and I need to convert a series of decimal numbers into datetime object in the form %Y-%m-%d %H:%M:%S. While doing so I need to consider an origin point, for example:
t = 0.000000 equals to 2016-06-25 00:00:00
t = 0.010417 equals to ..... ?
and so on. I know that in my decimal time the integer part is day since start, decimal part is fraction of day.
I have found an answer using R here. I also think that I might need to use the class method date.fromordinal(ordinal)or something similar but I cannot figure it out how to do it.
This is what I have tried so far:
example t = 1.010416
import datetime as DT
from datetime import timedelta
day = int(x)
datetime_object = DT.datetime.strptime("2016-06-25 00:00:00", '%Y-%m-%d %H:%M:%S')
python_datetime = DT.datetime.fromordinal(day) + timedelta(days=datetime_object.day-1)
I get:
datetime.datetime(1, 1, 25, 0, 0)
But I cannot add the year 2016 nor the month. Also, for every case in which int(t) = 0, I get:
ValueError: ordinal must be >= 1
Thank you very much for your answers
Just to leave a clear answer here, taking into account my comments on the other answers:
from datetime import datetime,timedelta
base_date = datetime(2016, 6, 25)
deltas = (2.34857, 0.010417, 1.010416)
for delta in deltas:
print((base_date + timedelta(delta)).strftime('%Y-%m-%d %H:%M:%S'))
That code yields the following ouput:
>>> from datetime import datetime,timedelta
>>>
>>> base_date = datetime(2016, 6, 25)
>>> deltas = (2.34857, 0.010417, 1.010416)
>>>
>>> for delta in deltas:
... print((base_date + timedelta(delta)).strftime('%Y-%m-%d %H:%M:%S'))
...
2016-06-27 08:21:56
2016-06-25 00:15:00
2016-06-26 00:14:59
>>>
timedelta stores its data in this format: (DAYS, SECONDS) so you can calculate it easily:
import datetime
t = 2.34857
# Full days
days = int(t)
# Part of a day
part_of_day = t - int(t)
seconds = int(part_of_day * 24 * 60 * 60)
# Calculate the time delta
dt = datetime.timedelta(
days=days,
seconds=seconds
)
# Add t-delta to the first day
first_day = datetime.datetime(2016, 6, 25)
current_time = first_day + dt
current_time
will return:
datetime.datetime(2016, 6, 27, 8, 21, 56)
Then you can convert it to a string with this function:
datetime.datetime.strftime(current_time, '%Y-%m-%d %H:%M:%S')
'2016-06-27 08:21:56'
Edit 1: Instead of constructing the timedelta by days-seconds, one can use just float days as parameter (thanks to accdias!):
dt = datetime.timedelta(days=t)

Convert TLE times (decimal days) to seconds after epoch

The standard two line element (TLE) format contains times as 2-digit year plus decimal days, so 16012.375 would be January 12, 2016 at 09:00. Using python's time or datatime modules, how can I convert this to seconds after epoch? I think I should use structured time but I am not sure how. seconds_of is a fictitious function - need to replace with something real.
EDIT: It will be most helpful if the answer is long (verbose) - like one step per line or so, so I can understand what is happening.
EDIT 2: After seeing the comments from #J.F.Sebastian I looked at the link for TLE and found it nowhere states "UTC". So I should point out the initial information and final information are UTC. There is no reference to local time, time zone, or system time.
e.g.
tim = "16012.375"
year = 2000 + int(tim[0:2])
decimal_days = float(tim[2:])
print year, decimal_days
2016, 12.375
# seconds_of is a fictitious function - need to replace with something real
seconds_after_epoch = seconds_of(2016,1,1) + (3600. * 24.) * decimal_days
You could try something like this [EDIT according to the comments].
import datetime
import time
# get year 2 digit and floating seconds days
y_d, nbs = "16012.375".split('.')
# parse to datetime (since midnight and add the seconds) %j Day of the year as a zero-padded decimal number.
d = datetime.datetime.strptime(y_d, "%y%j") + datetime.timedelta(seconds=float("." + nbs) * 24 * 60 * 60)
# 1.0 => 1 day
# from time tuple get epoch time.
time.mktime(d.timetuple())
#1481896800.0
It is easy to get datetime object given year and decimal_days:
>>> from datetime import datetime, timedelta
>>> year = 2016
>>> decimal_days = 12.375
>>> datetime(year, 1, 1) + timedelta(decimal_days - 1)
datetime.datetime(2016, 1, 12, 9, 0)
How to convert the datetime object into "seconds since epoch" depends on the timezone (local, utc, etc). See Converting datetime.date to UTC timestamp in Python e.g., if your input is in UTC then it is simple to get "seconds since the Epoch":
>>> utc_time = datetime(2016, 1, 12, 9, 0)
>>> (utc_time - datetime(1970, 1, 1)).total_seconds()
1452589200.0

How do I convert relative dates to absolute dates?

I am looking at a netcdf file through Python and the date on the netcdf file is 138276, which is the number of hours since 2000-01-01 00:00:00. This date corresponds to October 7. How I can convert this date of 138276 hours since 2000-01-01 00:00:00 into the format of 2015-10-07 00:00:00?
Since the start date is constant, create a datetime object and just add whatever hours you want using datetime.timedelta:
from datetime import datetime, timedelta
start = datetime(2000,1,1,0,0,0)
new = start + timedelta(hours=138276)
print(new)
2015-10-10 00:00:00
The answer is also 2105-10-10 not 2015-10-07
You can use dt.strptime to parse your string into a datetime object and then construct a dt.timedelta object and set param hours=your_val to add the required number of hours:
In [25]:
import datetime as dt
dt.datetime.strptime('2000-01-01 00:00:00', '%Y-%m-%d %H:%M:%S') + dt.timedelta(hours=138276)
Out[25]:
datetime.datetime(2015, 10, 10, 12, 0)
It's unclear to me how you arrive at a target date of 2015-010-07 when it's 2015-10-10?
If you are using the netCDF4 package, you should use the num2date function.
In [1]: from netCDF4 import num2date
In [2]: date = num2date(138276, 'hours since 2000-01-01 00:00:00', calendar='standard')
In [3]: date
Out[3]: datetime.datetime(2015, 10, 10, 12, 0)
most likely, your netCDF time variable also has the units and calendar in there so you probably don't need to hard code those. In fact, the num2date function will take a list or array of dates.
Have timedelta increment the hours properly. Your date calculation is a little off tho.
from datetime import datetime, timedelta
old_date = '2000-01-01'
curr_date = datetime.strptime(old_date, '%Y-%m-%d') + timedelta(hours=138276 )
print(curr_date)
2015-10-10 12:00:00
To change output format, change curr_date to:
print(curr_date.strftime('%Y%m%d%H'))
2015101012

Convert strange date format to standard date format

In Sweden we sometimes use a strange date format, for example New Year is the 31/12. If I have this format as a string ,which can be any date between 1/1 and 31/12, and if we assume that it is this year, how do I get into a standard date format using Python (format as 2012-01-01 and 2012-12-31) that can be sore in be stored as a date in a mySQL database.
Simply split the two values, map them to integers and update a datetime.date() instance:
import datetime
day, month = map(int, yourvalue.split('/'))
adate = datetime.date.today().replace(month=month, day=day)
By using datetime.date.today() we get the current year.
Demo:
>>> import datetime
>>> somevalue = '31/12'
>>> day, month = map(int, somevalue.split('/'))
>>> datetime.date.today().replace(month=month, day=day)
datetime.date(2012, 12, 31)
>>> someothervalue = '1/1'
>>> day, month = map(int, someothervalue.split('/'))
>>> datetime.date.today().replace(month=month, day=day)
datetime.date(2012, 1, 1)
Alternatively, you could use the datetime.strptime() method to parse these dates, but you'll have to manually correct the year afterwards (it'll use 1900 as the default if no year is being parsed):
adate = datetime.datetime.strptime(yourvalue, '%d/%m').date()
adate = adate.replace(year=datetime.date.today().year)
There is nothing strange about this format :)
You can use the datetime module:
import datetime
d = datetime.datetime.strptime('31/12', '%d/%m').date().replace(year=2012)
print d
>> datetime.date(2012, 12, 31)

Categories